├── .gitignore
├── AndroidManifest.xml
├── LICENSE
├── README.md
├── ic_launcher-web.png
├── jni
├── Android.mk
├── Application.mk
└── Blur.cpp
├── libs
├── android-support-v4.jar
├── armeabi-v7a
│ └── libblurjni.so
└── armeabi
│ └── libblurjni.so
├── proguard-project.txt
├── project.properties
├── res
├── drawable-hdpi
│ └── ic_launcher.png
├── drawable-mdpi
│ └── ic_launcher.png
├── drawable-xhdpi
│ └── ic_launcher.png
├── drawable-xxhdpi
│ └── ic_launcher.png
├── drawable
│ ├── bank.xml
│ ├── bg_squ_click.xml
│ ├── bg_squ_click_black.xml
│ ├── bg_squ_normal.xml
│ ├── bg_squ_normal_black.xml
│ ├── blue.xml
│ └── bottom.xml
├── layout
│ ├── activity_blur.xml
│ └── list_item.xml
├── menu
│ └── blur.xml
├── values-sw600dp
│ └── dimens.xml
├── values-sw720dp-land
│ └── dimens.xml
├── values-v11
│ └── styles.xml
├── values-v14
│ └── styles.xml
└── values
│ ├── attrs.xml
│ ├── dimens.xml
│ ├── strings.xml
│ └── styles.xml
├── screenshot
├── device-2014-02-18-162218.png
└── screenshot1.png
└── src
└── com
└── koalcat
├── blurdemo
├── AppInfo.java
├── ApplicationsAdapter.java
├── BlurActivity.java
├── FastBitmapDrawable.java
├── HanziToPinyin.java
├── IndexCursor.java
└── Utilities.java
└── view
├── BaseRender.java
├── Blur.java
├── BlurRSRender.java
├── GLRender.java
├── JNIRender.java
├── LiveBlurListView.java
├── LiveBlurViewGroup.java
├── RSRender.java
├── ScriptIntrinsicBlurRender.java
└── blur.rs
/.gitignore:
--------------------------------------------------------------------------------
1 | # built application files
2 | *.apk
3 | *.ap_
4 |
5 | # files for the dex VM
6 | *.dex
7 |
8 | # Java class files
9 | *.class
10 |
11 | # generated files
12 | bin/
13 | gen/
14 |
15 | # Local configuration file (sdk path, etc)
16 | local.properties
17 |
18 | # Eclipse project files
19 | .classpath
20 | .project
21 |
22 | # Proguard folder generated by Eclipse
23 | proguard/
24 |
25 | # Intellij project files
26 | *.iml
27 | *.ipr
28 | *.iws
29 | .idea/
30 |
--------------------------------------------------------------------------------
/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
2 |
6 |
7 |
10 |
11 |
15 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | Apache License
2 | Version 2.0, January 2004
3 | http://www.apache.org/licenses/
4 |
5 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
6 |
7 | 1. Definitions.
8 |
9 | "License" shall mean the terms and conditions for use, reproduction,
10 | and distribution as defined by Sections 1 through 9 of this document.
11 |
12 | "Licensor" shall mean the copyright owner or entity authorized by
13 | the copyright owner that is granting the License.
14 |
15 | "Legal Entity" shall mean the union of the acting entity and all
16 | other entities that control, are controlled by, or are under common
17 | control with that entity. For the purposes of this definition,
18 | "control" means (i) the power, direct or indirect, to cause the
19 | direction or management of such entity, whether by contract or
20 | otherwise, or (ii) ownership of fifty percent (50%) or more of the
21 | outstanding shares, or (iii) beneficial ownership of such entity.
22 |
23 | "You" (or "Your") shall mean an individual or Legal Entity
24 | exercising permissions granted by this License.
25 |
26 | "Source" form shall mean the preferred form for making modifications,
27 | including but not limited to software source code, documentation
28 | source, and configuration files.
29 |
30 | "Object" form shall mean any form resulting from mechanical
31 | transformation or translation of a Source form, including but
32 | not limited to compiled object code, generated documentation,
33 | and conversions to other media types.
34 |
35 | "Work" shall mean the work of authorship, whether in Source or
36 | Object form, made available under the License, as indicated by a
37 | copyright notice that is included in or attached to the work
38 | (an example is provided in the Appendix below).
39 |
40 | "Derivative Works" shall mean any work, whether in Source or Object
41 | form, that is based on (or derived from) the Work and for which the
42 | editorial revisions, annotations, elaborations, or other modifications
43 | represent, as a whole, an original work of authorship. For the purposes
44 | of this License, Derivative Works shall not include works that remain
45 | separable from, or merely link (or bind by name) to the interfaces of,
46 | the Work and Derivative Works thereof.
47 |
48 | "Contribution" shall mean any work of authorship, including
49 | the original version of the Work and any modifications or additions
50 | to that Work or Derivative Works thereof, that is intentionally
51 | submitted to Licensor for inclusion in the Work by the copyright owner
52 | or by an individual or Legal Entity authorized to submit on behalf of
53 | the copyright owner. For the purposes of this definition, "submitted"
54 | means any form of electronic, verbal, or written communication sent
55 | to the Licensor or its representatives, including but not limited to
56 | communication on electronic mailing lists, source code control systems,
57 | and issue tracking systems that are managed by, or on behalf of, the
58 | Licensor for the purpose of discussing and improving the Work, but
59 | excluding communication that is conspicuously marked or otherwise
60 | designated in writing by the copyright owner as "Not a Contribution."
61 |
62 | "Contributor" shall mean Licensor and any individual or Legal Entity
63 | on behalf of whom a Contribution has been received by Licensor and
64 | subsequently incorporated within the Work.
65 |
66 | 2. Grant of Copyright License. Subject to the terms and conditions of
67 | this License, each Contributor hereby grants to You a perpetual,
68 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable
69 | copyright license to reproduce, prepare Derivative Works of,
70 | publicly display, publicly perform, sublicense, and distribute the
71 | Work and such Derivative Works in Source or Object form.
72 |
73 | 3. Grant of Patent License. Subject to the terms and conditions of
74 | this License, each Contributor hereby grants to You a perpetual,
75 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable
76 | (except as stated in this section) patent license to make, have made,
77 | use, offer to sell, sell, import, and otherwise transfer the Work,
78 | where such license applies only to those patent claims licensable
79 | by such Contributor that are necessarily infringed by their
80 | Contribution(s) alone or by combination of their Contribution(s)
81 | with the Work to which such Contribution(s) was submitted. If You
82 | institute patent litigation against any entity (including a
83 | cross-claim or counterclaim in a lawsuit) alleging that the Work
84 | or a Contribution incorporated within the Work constitutes direct
85 | or contributory patent infringement, then any patent licenses
86 | granted to You under this License for that Work shall terminate
87 | as of the date such litigation is filed.
88 |
89 | 4. Redistribution. You may reproduce and distribute copies of the
90 | Work or Derivative Works thereof in any medium, with or without
91 | modifications, and in Source or Object form, provided that You
92 | meet the following conditions:
93 |
94 | (a) You must give any other recipients of the Work or
95 | Derivative Works a copy of this License; and
96 |
97 | (b) You must cause any modified files to carry prominent notices
98 | stating that You changed the files; and
99 |
100 | (c) You must retain, in the Source form of any Derivative Works
101 | that You distribute, all copyright, patent, trademark, and
102 | attribution notices from the Source form of the Work,
103 | excluding those notices that do not pertain to any part of
104 | the Derivative Works; and
105 |
106 | (d) If the Work includes a "NOTICE" text file as part of its
107 | distribution, then any Derivative Works that You distribute must
108 | include a readable copy of the attribution notices contained
109 | within such NOTICE file, excluding those notices that do not
110 | pertain to any part of the Derivative Works, in at least one
111 | of the following places: within a NOTICE text file distributed
112 | as part of the Derivative Works; within the Source form or
113 | documentation, if provided along with the Derivative Works; or,
114 | within a display generated by the Derivative Works, if and
115 | wherever such third-party notices normally appear. The contents
116 | of the NOTICE file are for informational purposes only and
117 | do not modify the License. You may add Your own attribution
118 | notices within Derivative Works that You distribute, alongside
119 | or as an addendum to the NOTICE text from the Work, provided
120 | that such additional attribution notices cannot be construed
121 | as modifying the License.
122 |
123 | You may add Your own copyright statement to Your modifications and
124 | may provide additional or different license terms and conditions
125 | for use, reproduction, or distribution of Your modifications, or
126 | for any such Derivative Works as a whole, provided Your use,
127 | reproduction, and distribution of the Work otherwise complies with
128 | the conditions stated in this License.
129 |
130 | 5. Submission of Contributions. Unless You explicitly state otherwise,
131 | any Contribution intentionally submitted for inclusion in the Work
132 | by You to the Licensor shall be under the terms and conditions of
133 | this License, without any additional terms or conditions.
134 | Notwithstanding the above, nothing herein shall supersede or modify
135 | the terms of any separate license agreement you may have executed
136 | with Licensor regarding such Contributions.
137 |
138 | 6. Trademarks. This License does not grant permission to use the trade
139 | names, trademarks, service marks, or product names of the Licensor,
140 | except as required for reasonable and customary use in describing the
141 | origin of the Work and reproducing the content of the NOTICE file.
142 |
143 | 7. Disclaimer of Warranty. Unless required by applicable law or
144 | agreed to in writing, Licensor provides the Work (and each
145 | Contributor provides its Contributions) on an "AS IS" BASIS,
146 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
147 | implied, including, without limitation, any warranties or conditions
148 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
149 | PARTICULAR PURPOSE. You are solely responsible for determining the
150 | appropriateness of using or redistributing the Work and assume any
151 | risks associated with Your exercise of permissions under this License.
152 |
153 | 8. Limitation of Liability. In no event and under no legal theory,
154 | whether in tort (including negligence), contract, or otherwise,
155 | unless required by applicable law (such as deliberate and grossly
156 | negligent acts) or agreed to in writing, shall any Contributor be
157 | liable to You for damages, including any direct, indirect, special,
158 | incidental, or consequential damages of any character arising as a
159 | result of this License or out of the use or inability to use the
160 | Work (including but not limited to damages for loss of goodwill,
161 | work stoppage, computer failure or malfunction, or any and all
162 | other commercial damages or losses), even if such Contributor
163 | has been advised of the possibility of such damages.
164 |
165 | 9. Accepting Warranty or Additional Liability. While redistributing
166 | the Work or Derivative Works thereof, You may choose to offer,
167 | and charge a fee for, acceptance of support, warranty, indemnity,
168 | or other liability obligations and/or rights consistent with this
169 | License. However, in accepting such obligations, You may act only
170 | on Your own behalf and on Your sole responsibility, not on behalf
171 | of any other Contributor, and only if You agree to indemnify,
172 | defend, and hold each Contributor harmless for any liability
173 | incurred by, or claims asserted against, such Contributor by reason
174 | of your accepting any such warranty or additional liability.
175 |
176 | END OF TERMS AND CONDITIONS
177 |
178 | APPENDIX: How to apply the Apache License to your work.
179 |
180 | To apply the Apache License to your work, attach the following
181 | boilerplate notice, with the fields enclosed by brackets "{}"
182 | replaced with your own identifying information. (Don't include
183 | the brackets!) The text should be enclosed in the appropriate
184 | comment syntax for the file format. We also recommend that a
185 | file or class name and description of purpose be included on the
186 | same "printed page" as the copyright notice for easier
187 | identification within third-party archives.
188 |
189 | Copyright {yyyy} {name of copyright owner}
190 |
191 | Licensed under the Apache License, Version 2.0 (the "License");
192 | you may not use this file except in compliance with the License.
193 | You may obtain a copy of the License at
194 |
195 | http://www.apache.org/licenses/LICENSE-2.0
196 |
197 | Unless required by applicable law or agreed to in writing, software
198 | distributed under the License is distributed on an "AS IS" BASIS,
199 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
200 | See the License for the specific language governing permissions and
201 | limitations under the License.
202 |
203 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | LiveBlurListView
2 | ================
3 |
4 | Sample to show how to implement live blur for Android ViewGroup
5 |
6 | 
7 |
8 | Demo Apk
9 | ===
10 | [GooglePlay](https://play.google.com/store/apps/details?id=com.koalcat.blurdemo)
11 |
12 | License
13 | ===
14 |
15 | Copyright 2014 xuchdeid
16 |
17 | Licensed under the Apache License, Version 2.0 (the "License");
18 | you may not use this file except in compliance with the License.
19 | You may obtain a copy of the License at
20 |
21 | http://www.apache.org/licenses/LICENSE-2.0
22 |
23 | Unless required by applicable law or agreed to in writing, software
24 | distributed under the License is distributed on an "AS IS" BASIS,
25 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
26 | See the License for the specific language governing permissions and
27 | limitations under the License.
28 |
--------------------------------------------------------------------------------
/ic_launcher-web.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/xuchdeid/LiveBlurListView/28609338dbfc93430cdd1cb8eed45254375f4d84/ic_launcher-web.png
--------------------------------------------------------------------------------
/jni/Android.mk:
--------------------------------------------------------------------------------
1 | LOCAL_PATH:= $(call my-dir)
2 |
3 | include $(CLEAR_VARS)
4 |
5 | LOCAL_MODULE := blurjni
6 | LOCAL_CFLAGS := -Werror
7 | LOCAL_SRC_FILES := Blur.cpp
8 |
9 | LOCAL_LDLIBS := -llog -lGLESv2 -lm -ljnigraphics
10 |
11 |
12 | include $(BUILD_SHARED_LIBRARY)
13 |
--------------------------------------------------------------------------------
/jni/Application.mk:
--------------------------------------------------------------------------------
1 | # The ARMv7 is significanly faster due to the use of the hardware FPU
2 | APP_ABI := armeabi armeabi-v7a
3 | APP_PLATFORM := android-8
4 |
--------------------------------------------------------------------------------
/jni/Blur.cpp:
--------------------------------------------------------------------------------
1 | #include
2 | #include
3 | #include
4 | #include
5 | #include
6 | #include
7 |
8 | #define LOG_TAG "libbitmaputils"
9 | #define LOGI(...) __android_log_print(ANDROID_LOG_INFO,LOG_TAG,__VA_ARGS__)
10 | #define LOGE(...) __android_log_print(ANDROID_LOG_ERROR,LOG_TAG,__VA_ARGS__)
11 |
12 | typedef struct {
13 | uint8_t red;
14 | uint8_t green;
15 | uint8_t blue;
16 | uint8_t alpha;
17 | } rgba;
18 |
19 | extern "C" {
20 | JNIEXPORT void JNICALL Java_com_koalcat_view_JNIRender_Blur(JNIEnv* env, jobject obj, jobject bitmapIn, jobject bitmapOut, jint radius);
21 | };
22 |
23 | JNIEXPORT void JNICALL Java_com_koalcat_view_JNIRender_Blur(JNIEnv* env, jobject obj, jobject bitmapIn, jobject bitmapOut, jint radius) {
24 | //LOGI("Blurring bitmap...");
25 |
26 | // Properties
27 | AndroidBitmapInfo infoIn;
28 | void* pixelsIn;
29 | AndroidBitmapInfo infoOut;
30 | void* pixelsOut;
31 |
32 | int ret;
33 |
34 | // Get image info
35 | if ((ret = AndroidBitmap_getInfo(env, bitmapIn, &infoIn)) < 0 || (ret = AndroidBitmap_getInfo(env, bitmapOut, &infoOut)) < 0) {
36 | LOGE("AndroidBitmap_getInfo() failed ! error=%d", ret);
37 | return;
38 | }
39 |
40 | // Check image
41 | if (infoIn.format != ANDROID_BITMAP_FORMAT_RGBA_8888 || infoOut.format != ANDROID_BITMAP_FORMAT_RGBA_8888) {
42 | LOGE("Bitmap format is not RGBA_8888!");
43 | LOGE("==> %d %d", infoIn.format, infoOut.format);
44 | return;
45 | }
46 |
47 | // Lock all images
48 | if ((ret = AndroidBitmap_lockPixels(env, bitmapIn, &pixelsIn)) < 0 || (ret = AndroidBitmap_lockPixels(env, bitmapOut, &pixelsOut)) < 0) {
49 | LOGE("AndroidBitmap_lockPixels() failed ! error=%d", ret);
50 | }
51 |
52 | int h = infoIn.height;
53 | int w = infoIn.width;
54 |
55 | //LOGI("Image size is: %i %i", w, h);
56 |
57 | rgba* input = (rgba*) pixelsIn;
58 | rgba* output = (rgba*) pixelsOut;
59 |
60 | int wm = w - 1;
61 | int hm = h - 1;
62 | int wh = w * h;
63 | int whMax = fmax(w, h);
64 | int div = radius + radius + 1;
65 |
66 | int r[wh];
67 | int g[wh];
68 | int b[wh];
69 | int rsum, gsum, bsum, x, y, i, yp, yi, yw;
70 | rgba p;
71 | int vmin[whMax];
72 |
73 | int divsum = (div + 1) >> 1;
74 | divsum *= divsum;
75 | int dv[256 * divsum];
76 | for (i = 0; i < 256 * divsum; i++) {
77 | dv[i] = (i / divsum);
78 | }
79 |
80 | yw = yi = 0;
81 |
82 | int stack[div][3];
83 | int stackpointer;
84 | int stackstart;
85 | int rbs;
86 | int ir;
87 | int ip;
88 | int r1 = radius + 1;
89 | int routsum, goutsum, boutsum;
90 | int rinsum, ginsum, binsum;
91 |
92 | for (y = 0; y < h; y++) {
93 | rinsum = ginsum = binsum = routsum = goutsum = boutsum = rsum = gsum = bsum = 0;
94 | for (i = -radius; i <= radius; i++) {
95 | p = input[yi + (int)fmin(wm, fmax(i, 0))];
96 |
97 | ir = i + radius; // same as sir
98 |
99 | stack[ir][0] = p.red;
100 | stack[ir][1] = p.green;
101 | stack[ir][2] = p.blue;
102 | rbs = r1 - fabs(i);
103 | rsum += stack[ir][0] * rbs;
104 | gsum += stack[ir][1] * rbs;
105 | bsum += stack[ir][2] * rbs;
106 | if (i > 0) {
107 | rinsum += stack[ir][0];
108 | ginsum += stack[ir][1];
109 | binsum += stack[ir][2];
110 | } else {
111 | routsum += stack[ir][0];
112 | goutsum += stack[ir][1];
113 | boutsum += stack[ir][2];
114 | }
115 | }
116 | stackpointer = radius;
117 |
118 | for (x = 0; x < w; x++) {
119 |
120 | r[yi] = dv[rsum];
121 | g[yi] = dv[gsum];
122 | b[yi] = dv[bsum];
123 |
124 | rsum -= routsum;
125 | gsum -= goutsum;
126 | bsum -= boutsum;
127 |
128 | stackstart = stackpointer - radius + div;
129 | ir = stackstart % div; // same as sir
130 |
131 | routsum -= stack[ir][0];
132 | goutsum -= stack[ir][1];
133 | boutsum -= stack[ir][2];
134 |
135 | if (y == 0) {
136 | vmin[x] = fmin(x + radius + 1, wm);
137 | }
138 | p = input[yw + vmin[x]];
139 |
140 | stack[ir][0] = p.red;
141 | stack[ir][1] = p.green;
142 | stack[ir][2] = p.blue;
143 |
144 | rinsum += stack[ir][0];
145 | ginsum += stack[ir][1];
146 | binsum += stack[ir][2];
147 |
148 | rsum += rinsum;
149 | gsum += ginsum;
150 | bsum += binsum;
151 |
152 | stackpointer = (stackpointer + 1) % div;
153 | ir = (stackpointer) % div; // same as sir
154 |
155 | routsum += stack[ir][0];
156 | goutsum += stack[ir][1];
157 | boutsum += stack[ir][2];
158 |
159 | rinsum -= stack[ir][0];
160 | ginsum -= stack[ir][1];
161 | binsum -= stack[ir][2];
162 |
163 | yi++;
164 | }
165 | yw += w;
166 | }
167 | for (x = 0; x < w; x++) {
168 | rinsum = ginsum = binsum = routsum = goutsum = boutsum = rsum = gsum = bsum = 0;
169 | yp = -radius * w;
170 | for (i = -radius; i <= radius; i++) {
171 | yi = fmax(0, yp) + x;
172 |
173 | ir = i + radius; // same as sir
174 |
175 | stack[ir][0] = r[yi];
176 | stack[ir][1] = g[yi];
177 | stack[ir][2] = b[yi];
178 |
179 | rbs = r1 - fabs(i);
180 |
181 | rsum += r[yi] * rbs;
182 | gsum += g[yi] * rbs;
183 | bsum += b[yi] * rbs;
184 |
185 | if (i > 0) {
186 | rinsum += stack[ir][0];
187 | ginsum += stack[ir][1];
188 | binsum += stack[ir][2];
189 | } else {
190 | routsum += stack[ir][0];
191 | goutsum += stack[ir][1];
192 | boutsum += stack[ir][2];
193 | }
194 |
195 | if (i < hm) {
196 | yp += w;
197 | }
198 | }
199 | yi = x;
200 | stackpointer = radius;
201 | for (y = 0; y < h; y++) {
202 | output[yi].red = dv[rsum];
203 | output[yi].green = dv[gsum];
204 | output[yi].blue = dv[bsum];
205 |
206 | rsum -= routsum;
207 | gsum -= goutsum;
208 | bsum -= boutsum;
209 |
210 | stackstart = stackpointer - radius + div;
211 | ir = stackstart % div; // same as sir
212 |
213 | routsum -= stack[ir][0];
214 | goutsum -= stack[ir][1];
215 | boutsum -= stack[ir][2];
216 |
217 | if (x == 0) vmin[y] = fmin(y + r1, hm) * w;
218 | ip = x + vmin[y];
219 |
220 | stack[ir][0] = r[ip];
221 | stack[ir][1] = g[ip];
222 | stack[ir][2] = b[ip];
223 |
224 | rinsum += stack[ir][0];
225 | ginsum += stack[ir][1];
226 | binsum += stack[ir][2];
227 |
228 | rsum += rinsum;
229 | gsum += ginsum;
230 | bsum += binsum;
231 |
232 | stackpointer = (stackpointer + 1) % div;
233 | ir = stackpointer; // same as sir
234 |
235 | routsum += stack[ir][0];
236 | goutsum += stack[ir][1];
237 | boutsum += stack[ir][2];
238 |
239 | rinsum -= stack[ir][0];
240 | ginsum -= stack[ir][1];
241 | binsum -= stack[ir][2];
242 |
243 | yi += w;
244 | }
245 | }
246 |
247 | // Unlocks everything
248 | AndroidBitmap_unlockPixels(env, bitmapIn);
249 | AndroidBitmap_unlockPixels(env, bitmapOut);
250 |
251 | //LOGI ("Bitmap blurred.");
252 | }
253 | /*
254 | int min(int a, int b) {
255 | return a > b ? b : a;
256 | }
257 |
258 | int max(int a, int b) {
259 | return a > b ? a : b;
260 | }*/
261 |
--------------------------------------------------------------------------------
/libs/android-support-v4.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/xuchdeid/LiveBlurListView/28609338dbfc93430cdd1cb8eed45254375f4d84/libs/android-support-v4.jar
--------------------------------------------------------------------------------
/libs/armeabi-v7a/libblurjni.so:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/xuchdeid/LiveBlurListView/28609338dbfc93430cdd1cb8eed45254375f4d84/libs/armeabi-v7a/libblurjni.so
--------------------------------------------------------------------------------
/libs/armeabi/libblurjni.so:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/xuchdeid/LiveBlurListView/28609338dbfc93430cdd1cb8eed45254375f4d84/libs/armeabi/libblurjni.so
--------------------------------------------------------------------------------
/proguard-project.txt:
--------------------------------------------------------------------------------
1 | # To enable ProGuard in your project, edit project.properties
2 | # to define the proguard.config property as described in that file.
3 | #
4 | # Add project specific ProGuard rules here.
5 | # By default, the flags in this file are appended to flags specified
6 | # in ${sdk.dir}/tools/proguard/proguard-android.txt
7 | # You can edit the include path and order by changing the ProGuard
8 | # include property in project.properties.
9 | #
10 | # For more details, see
11 | # http://developer.android.com/guide/developing/tools/proguard.html
12 |
13 | # Add any project specific keep options here:
14 |
15 | # If your project uses WebView with JS, uncomment the following
16 | # and specify the fully qualified class name to the JavaScript interface
17 | # class:
18 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview {
19 | # public *;
20 | #}
21 |
--------------------------------------------------------------------------------
/project.properties:
--------------------------------------------------------------------------------
1 | # This file is automatically generated by Android Tools.
2 | # Do not modify this file -- YOUR CHANGES WILL BE ERASED!
3 | #
4 | # This file must be checked in Version Control Systems.
5 | #
6 | # To customize properties used by the Ant build system edit
7 | # "ant.properties", and override values to adapt the script to your
8 | # project structure.
9 | #
10 | # To enable ProGuard to shrink and obfuscate your code, uncomment this (available properties: sdk.dir, user.home):
11 | #proguard.config=${sdk.dir}/tools/proguard/proguard-android.txt:proguard-project.txt
12 |
13 | # Project target.
14 | target=android-19
15 | renderscript.target=15
16 |
--------------------------------------------------------------------------------
/res/drawable-hdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/xuchdeid/LiveBlurListView/28609338dbfc93430cdd1cb8eed45254375f4d84/res/drawable-hdpi/ic_launcher.png
--------------------------------------------------------------------------------
/res/drawable-mdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/xuchdeid/LiveBlurListView/28609338dbfc93430cdd1cb8eed45254375f4d84/res/drawable-mdpi/ic_launcher.png
--------------------------------------------------------------------------------
/res/drawable-xhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/xuchdeid/LiveBlurListView/28609338dbfc93430cdd1cb8eed45254375f4d84/res/drawable-xhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/res/drawable-xxhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/xuchdeid/LiveBlurListView/28609338dbfc93430cdd1cb8eed45254375f4d84/res/drawable-xxhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/res/drawable/bank.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
5 |
6 |
--------------------------------------------------------------------------------
/res/drawable/bg_squ_click.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
9 |
10 |
13 |
14 |
18 |
19 |
23 |
24 |
25 |
--------------------------------------------------------------------------------
/res/drawable/bg_squ_click_black.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
9 |
10 |
13 |
14 |
18 |
19 |
23 |
24 |
25 |
--------------------------------------------------------------------------------
/res/drawable/bg_squ_normal.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
9 |
10 |
12 |
13 |
17 |
18 |
22 |
23 |
24 |
--------------------------------------------------------------------------------
/res/drawable/bg_squ_normal_black.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
9 |
10 |
12 |
13 |
17 |
18 |
22 |
23 |
24 |
25 |
26 |
--------------------------------------------------------------------------------
/res/drawable/blue.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
5 |
6 |
--------------------------------------------------------------------------------
/res/drawable/bottom.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/res/layout/activity_blur.xml:
--------------------------------------------------------------------------------
1 |
7 |
8 |
16 |
17 |
23 |
24 |
30 |
36 |
42 |
48 |
49 |
50 |
51 |
52 |
--------------------------------------------------------------------------------
/res/layout/list_item.xml:
--------------------------------------------------------------------------------
1 |
2 |
6 |
7 |
18 |
19 |
28 |
29 |
--------------------------------------------------------------------------------
/res/menu/blur.xml:
--------------------------------------------------------------------------------
1 |
10 |
--------------------------------------------------------------------------------
/res/values-sw600dp/dimens.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/res/values-sw720dp-land/dimens.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
7 | 128dp
8 |
9 |
10 |
--------------------------------------------------------------------------------
/res/values-v11/styles.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
7 |
10 |
11 |
12 |
--------------------------------------------------------------------------------
/res/values-v14/styles.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
8 |
12 |
13 |
14 |
--------------------------------------------------------------------------------
/res/values/attrs.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
--------------------------------------------------------------------------------
/res/values/dimens.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | 16dp
5 | 16dp
6 |
7 |
8 |
--------------------------------------------------------------------------------
/res/values/strings.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | LiveBlurListViewDemo
5 | Settings
6 | Hello world!
7 |
8 |
9 |
--------------------------------------------------------------------------------
/res/values/styles.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
7 |
15 |
16 |
17 |
20 |
21 |
24 |
25 |
26 |
--------------------------------------------------------------------------------
/screenshot/device-2014-02-18-162218.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/xuchdeid/LiveBlurListView/28609338dbfc93430cdd1cb8eed45254375f4d84/screenshot/device-2014-02-18-162218.png
--------------------------------------------------------------------------------
/screenshot/screenshot1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/xuchdeid/LiveBlurListView/28609338dbfc93430cdd1cb8eed45254375f4d84/screenshot/screenshot1.png
--------------------------------------------------------------------------------
/src/com/koalcat/blurdemo/AppInfo.java:
--------------------------------------------------------------------------------
1 | package com.koalcat.blurdemo;
2 | /**
3 | * @author xuchdeid@gmail.com
4 | * __________________________ \_/
5 | | | /._.\
6 | | Android!Android! > U| |U
7 | | xuchdeid | |___|
8 | |__________________________| U U
9 | * */
10 | import android.content.ComponentName;
11 | import android.content.Intent;
12 | import android.graphics.Bitmap;
13 | import android.graphics.drawable.Drawable;
14 | import android.widget.ImageButton;
15 |
16 | public class AppInfo {
17 |
18 | public static final int NO_ID = -1;
19 | public String title;
20 | public String title_py;
21 | public Intent intent;
22 | public Drawable icon;
23 | public Bitmap bitmap;
24 | public ComponentName mComponentName;
25 | public ImageButton mImageButton;
26 |
27 | public final void setComponentName(ComponentName className) {
28 | this.mComponentName = className;
29 | }
30 |
31 | public final void setActivity(ComponentName className, int launchFlags) {
32 | intent = new Intent(Intent.ACTION_MAIN);
33 | intent.addCategory(Intent.CATEGORY_LAUNCHER);
34 | intent.setComponent(className);
35 | intent.setFlags(launchFlags);
36 | }
37 | }
38 |
--------------------------------------------------------------------------------
/src/com/koalcat/blurdemo/ApplicationsAdapter.java:
--------------------------------------------------------------------------------
1 | package com.koalcat.blurdemo;
2 | /**
3 | * @author xuchdeid@gmail.com
4 | * __________________________ \_/
5 | | | /._.\
6 | | Android!Android! > U| |U
7 | | xuchdeid | |___|
8 | |__________________________| U U
9 | * */
10 | import java.util.ArrayList;
11 |
12 | import android.content.Context;
13 | import android.content.pm.PackageManager;
14 | import android.content.pm.PackageManager.NameNotFoundException;
15 | import android.graphics.Bitmap;
16 | import android.graphics.drawable.Drawable;
17 | import android.support.v4.util.LruCache;
18 | import android.util.SparseArray;
19 | import android.view.LayoutInflater;
20 | import android.view.View;
21 | import android.view.ViewGroup;
22 | import android.widget.AlphabetIndexer;
23 | import android.widget.ArrayAdapter;
24 | import android.widget.ImageView;
25 | import android.widget.SectionIndexer;
26 | import android.widget.TextView;
27 |
28 | public class ApplicationsAdapter extends ArrayAdapter implements SectionIndexer{
29 | private final LayoutInflater mInflater;
30 | //private String mSectionString;
31 | private AlphabetIndexer alphabetIndexer;
32 | public LruCache mMemoryCache;
33 |
34 | public ApplicationsAdapter(Context context, ArrayList apps) {
35 | super(context, 0, apps);
36 | mInflater = LayoutInflater.from(context);
37 | //mSectionString = context.getResources().getString(R.string.fast_scroll_alphabet);
38 | alphabetIndexer = new AlphabetIndexer(new IndexCursor(this), 0, "#ABCDEFGHIJKLMNOPQRSTUVWXYZ");
39 | final int maxMemory = (int) (Runtime.getRuntime().maxMemory() / 1024);
40 | final int cacheSize = maxMemory / 8;
41 |
42 | mMemoryCache = new LruCache(cacheSize) {
43 | @Override
44 | protected int sizeOf(String key, Bitmap bitmap) {
45 | return bitmap.getByteCount()/1024;
46 | }
47 | };
48 | }
49 |
50 | @Override
51 | public View getView(int position, View convertView, ViewGroup parent) {
52 | final AppInfo info = getItem(position);
53 |
54 | if (convertView == null) {
55 | convertView = mInflater.inflate(R.layout.list_item, parent, false);
56 | }
57 |
58 | //info.icon = Utilities.createIconThumbnail(info.icon, getContext());
59 |
60 | final TextView textView = ViewHolder.get(convertView, R.id.item_text);
61 | textView.setText(info.title);
62 |
63 | Bitmap bitmap = mMemoryCache.get(info.title_py);
64 | if (bitmap == null) {
65 | final PackageManager manager = getContext().getPackageManager();
66 | Drawable icon = null;
67 | try {
68 | icon = manager.getActivityIcon(info.mComponentName);
69 | } catch (NameNotFoundException e) {
70 | // TODO Auto-generated catch block
71 | e.printStackTrace();
72 | }
73 | bitmap = Utilities.createIcontoBitmapThumbnail(icon, this.getContext());
74 | mMemoryCache.put(info.title_py, bitmap);
75 | }
76 |
77 | final ImageView imageView = ViewHolder.get(convertView, R.id.item_image);
78 | //imageView.setImageDrawable(info.icon);
79 | imageView.setImageBitmap(bitmap);
80 | // imageView.setImageResource(R.drawable.ic_launcher);
81 | return convertView;
82 | }
83 |
84 | @Override
85 | public int getPositionForSection(int section) {
86 | // TODO Auto-generated method stub
87 | return alphabetIndexer.getPositionForSection(section);
88 | }
89 |
90 | @Override
91 | public int getSectionForPosition(int position) {
92 | // TODO Auto-generated method stub
93 | return alphabetIndexer.getSectionForPosition(position);
94 | }
95 |
96 | @Override
97 | public Object[] getSections() {
98 | // TODO Auto-generated method stub
99 | return alphabetIndexer.getSections();
100 | }
101 |
102 | public static class ViewHolder {
103 | @SuppressWarnings("unchecked")
104 | public static T get(View view, int id) {
105 | SparseArray viewHolder = (SparseArray) view.getTag();
106 | if (viewHolder == null) {
107 | viewHolder = new SparseArray();
108 | view.setTag(viewHolder);
109 | }
110 | View childView = viewHolder.get(id);
111 | if (childView == null) {
112 | childView = view.findViewById(id);
113 | viewHolder.put(id, childView);
114 | }
115 | return (T) childView;
116 | }
117 | }
118 | }
119 |
--------------------------------------------------------------------------------
/src/com/koalcat/blurdemo/BlurActivity.java:
--------------------------------------------------------------------------------
1 | package com.koalcat.blurdemo;
2 | /**
3 | * @author xuchdeid@gmail.com
4 | * __________________________ \_/
5 | | | /._.\
6 | | Android!Android! > U| |U
7 | | xuchdeid | |___|
8 | |__________________________| U U
9 | * */
10 | import java.text.Collator;
11 | import java.util.ArrayList;
12 | import java.util.Comparator;
13 | import java.util.HashMap;
14 | import java.util.List;
15 |
16 | import com.koalcat.blurdemo.HanziToPinyin.Token;
17 | import com.koalcat.view.LiveBlurListView;
18 |
19 | import android.os.Bundle;
20 | import android.os.Handler;
21 | import android.os.HandlerThread;
22 | import android.app.ActionBar;
23 | import android.app.ActionBar.LayoutParams;
24 | import android.app.Activity;
25 | import android.content.ActivityNotFoundException;
26 | import android.content.ComponentName;
27 | import android.content.Context;
28 | import android.content.Intent;
29 | import android.content.pm.PackageManager;
30 | import android.content.pm.ResolveInfo;
31 | import android.content.res.Resources;
32 | import android.graphics.Bitmap;
33 | import android.view.Menu;
34 | import android.view.MenuInflater;
35 | import android.view.View;
36 | import android.view.Window;
37 | import android.view.WindowManager;
38 | import android.widget.AdapterView;
39 | import android.widget.AdapterView.OnItemClickListener;
40 | import android.widget.TextView;
41 |
42 | public class BlurActivity extends Activity implements OnItemClickListener {
43 |
44 | private static final int INITIAL_ICON_CACHE_CAPACITY = 50;
45 | private static final int UI_NOTIFICATION_RATE = 4;
46 |
47 | private static Collator sCollator;
48 | private Handler mUIHandler, mHandler;
49 |
50 | private final int Intent_Flag = Intent.FLAG_ACTIVITY_NEW_TASK |
51 | Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED;
52 |
53 | ApplicationsAdapter mApplicationsAdapter;
54 | private ArrayList mApplications;
55 | private ApplicationsLoader mApplicationsLoader;
56 | private final HashMap mAppInfoCache =
57 | new HashMap(INITIAL_ICON_CACHE_CAPACITY);
58 |
59 | LiveBlurListView mList;
60 | private ActionBar mActionBar;
61 |
62 | @Override
63 | public void onCreate(Bundle savedInstanceState) {
64 | canSetTranslucentFlag();
65 | mActionBar = getActionBar();
66 | mActionBar.hide();
67 | //mActionBar.setDisplayShowCustomEnabled(true);
68 | //mActionBar.setBackgroundDrawable(null);
69 |
70 | //TextView v = new TextView(this);
71 | //v.setText("hello world");
72 | //v.setTextSize(25);
73 | //LayoutParams l = new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT);
74 |
75 | //mActionBar.setCustomView(v, l);
76 |
77 |
78 | super.onCreate(savedInstanceState);
79 | setContentView(R.layout.activity_blur);
80 |
81 | sCollator = Collator.getInstance();
82 | mUIHandler = new Handler(this.getMainLooper());
83 | mList = (LiveBlurListView)findViewById(R.id.list);
84 | mApplications = new ArrayList();
85 | mApplicationsAdapter = new ApplicationsAdapter(this, mApplications);
86 | mList.setAdapter(mApplicationsAdapter);
87 | mList.setOnItemClickListener(this);
88 | mApplicationsLoader = new ApplicationsLoader(this);
89 | HandlerThread mthread = new HandlerThread("launcher");
90 | mthread.start();
91 | mHandler = new Handler(mthread.getLooper());
92 | mHandler.postDelayed(mApplicationsLoader, 500);
93 | }
94 |
95 | public boolean onCreateOptionsMenu(Menu menu) {
96 | MenuInflater inflater = getMenuInflater();
97 | inflater.inflate(R.menu.blur, menu);
98 | return true;
99 | }
100 |
101 | @Override
102 | public void onDestroy() {
103 | super.onDestroy();
104 | }
105 |
106 | class ApplicationsLoader implements Runnable {
107 |
108 | private Context mLauncher;
109 | private volatile boolean mStopped;
110 | private volatile boolean mRunning;
111 |
112 | public ApplicationsLoader(Context launcher) {
113 | mLauncher = launcher;
114 | mRunning = true;
115 | }
116 |
117 | void stop() {
118 | mStopped = true;
119 | }
120 |
121 | boolean isRunning() {
122 | return mRunning;
123 | }
124 |
125 | public void run() {
126 |
127 | Intent mainIntent;
128 |
129 | //get apk main and can launcher activity
130 | mainIntent = new Intent(Intent.ACTION_MAIN, null);
131 | mainIntent.addCategory(Intent.CATEGORY_LAUNCHER);
132 |
133 | final PackageManager manager = mLauncher.getPackageManager();
134 | final List apps = manager.queryIntentActivities(mainIntent, 0);
135 |
136 | if (apps != null && !mStopped) {
137 | final int count = apps.size();
138 | // Can be set to null on the UI thread by the unbind() method
139 | // Do not access without checking for null first
140 | final ApplicationsAdapter applicationList = mApplicationsAdapter;
141 | ChangeNotifier action = new ChangeNotifier(applicationList, true);
142 | final HashMap appInfoCache = mAppInfoCache;
143 |
144 | for (int i = 0; i < count && !mStopped; i++) {
145 | ResolveInfo info = apps.get(i);
146 | //if (!info.activityInfo.packageName.equals(getPackageName())) {
147 | AppInfo application =
148 | makeAndCacheApplicationInfo(mApplicationsAdapter, manager, appInfoCache, info, mLauncher);
149 | if (action.add(application) && !mStopped) {
150 | mUIHandler.post(action);
151 | action = new ChangeNotifier(applicationList, false);
152 | }
153 | //}
154 | }
155 | mUIHandler.post(action);
156 |
157 | }
158 |
159 | mRunning = false;
160 | }
161 | }
162 |
163 | private static class ChangeNotifier implements Runnable {
164 | private final ApplicationsAdapter mApplicationList;
165 | private final ArrayList mBuffer;
166 |
167 | private boolean mFirst = true;
168 |
169 | ChangeNotifier(ApplicationsAdapter applicationList, boolean first) {
170 | mApplicationList = applicationList;
171 | mFirst = first;
172 | mBuffer = new ArrayList(UI_NOTIFICATION_RATE);
173 | }
174 |
175 | public void run() {
176 | final ApplicationsAdapter applicationList = mApplicationList;
177 | // Can be set to null on the UI thread by the unbind() method
178 | if (applicationList == null) return;
179 |
180 | if (mFirst) {
181 | applicationList.setNotifyOnChange(false);
182 | applicationList.clear();
183 | mFirst = false;
184 | }
185 |
186 | final ArrayList buffer = mBuffer;
187 | final int count = buffer.size();
188 |
189 | for (int i = 0; i < count; i++) {
190 | // applicationList.setNotifyOnChange(false);
191 | applicationList.add(buffer.get(i));
192 | }
193 |
194 | buffer.clear();
195 |
196 | applicationList.sort(new ApplicationInfoComparator());
197 | applicationList.notifyDataSetChanged();
198 | }
199 |
200 | boolean add(AppInfo application) {
201 | final ArrayList buffer = mBuffer;
202 | buffer.add(application);
203 | return buffer.size() >= UI_NOTIFICATION_RATE;
204 | }
205 | }
206 |
207 | private static AppInfo makeAndCacheApplicationInfo(ApplicationsAdapter mApplicationsAdapter, PackageManager manager,
208 | HashMap appInfoCache, ResolveInfo info,
209 | Context context) {
210 |
211 | ComponentName componentName = new ComponentName(
212 | info.activityInfo.applicationInfo.packageName,
213 | info.activityInfo.name);
214 | /*if (info.activityInfo.packageName.equals(context.getPackageName())) {
215 | info.activityInfo.name = "com.koalcat.launcher.activity.Setting";
216 | }*/
217 | AppInfo application = appInfoCache.get(componentName);
218 |
219 | if (application == null) {
220 | application = new AppInfo();
221 |
222 | updateApplicationInfoTitleAndIcon(mApplicationsAdapter, manager, info, application, context);
223 | application.setComponentName(componentName);
224 |
225 | appInfoCache.put(componentName, application);
226 | }
227 |
228 | return application;
229 | }
230 |
231 | private static void updateApplicationInfoTitleAndIcon(ApplicationsAdapter mApplicationsAdapter, PackageManager manager, ResolveInfo info,
232 | AppInfo application, Context context) {
233 | application.title = info.loadLabel(manager).toString();
234 | if (application.title.charAt(0) == ' ') {
235 | application.title = application.title.substring(1);
236 | }
237 | if (application.title == null) {
238 | application.title = info.activityInfo.name;
239 |
240 | }
241 | if (application.title_py == null) {
242 | application.title_py = getPinYin(application.title);
243 | if (application.title_py.equals("")) {
244 | application.title_py = application.title;
245 | }
246 | }
247 |
248 | //application.icon =
249 | // Utilities.createIconThumbnail(info.activityInfo.loadIcon(manager), context);
250 | if (mApplicationsAdapter.mMemoryCache.get(application.title_py) == null) {
251 | Bitmap bitmap = Utilities.createIcontoBitmapThumbnail(info.activityInfo.loadIcon(manager), context);
252 | mApplicationsAdapter.mMemoryCache.put(application.title_py, bitmap);
253 | }
254 |
255 | }
256 |
257 | static class ApplicationInfoComparator implements Comparator {
258 | public final int compare(AppInfo a, AppInfo b) {
259 | return sCollator.compare(a.title_py, b.title_py);
260 | }
261 | }
262 |
263 | public static String getPinYin(String input) {
264 | ArrayList tokens = HanziToPinyin.getInstance().get(input);
265 | StringBuilder sb = new StringBuilder();
266 | if (tokens != null && tokens.size() > 0) {
267 | for (Token token : tokens) {
268 | if (Token.PINYIN == token.type) {
269 | sb.append(token.target);
270 | } else {
271 | sb.append(token.source);
272 | }
273 | }
274 | }
275 | return sb.toString();
276 | }
277 |
278 | @Override
279 | public void onBackPressed() {
280 | super.onBackPressed();
281 | if (mApplicationsLoader != null) {
282 | mApplicationsLoader.stop();
283 | }
284 | }
285 |
286 | private int canSetTranslucentFlag() {
287 | Resources resources = getResources();
288 | int id = resources.getIdentifier("config_enableTranslucentDecor", "bool", "android");
289 | if (id != 0) {
290 | boolean enabled = resources.getBoolean(id);
291 | if (enabled) {
292 | Window w = getWindow();
293 | w.setFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS |
294 | WindowManager.LayoutParams.FLAG_TRANSLUCENT_NAVIGATION,
295 | WindowManager.LayoutParams.FLAG_TRANSLUCENT_NAVIGATION |
296 | WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);
297 |
298 | //w.setFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS,
299 | //WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);
300 |
301 | id = resources.getIdentifier("config_showNavigationBar", "bool", "android");
302 | if (id > 0) {
303 | if (!resources.getBoolean(id)) return 0;
304 | } else {
305 | return 0;
306 | }
307 |
308 | id = resources.getIdentifier("navigation_bar_height", "dimen", "android");
309 |
310 | if (id > 0) {
311 | return resources.getDimensionPixelSize(id);
312 | }
313 | }
314 | }
315 | return 0;
316 | }
317 |
318 | @Override
319 | public void onItemClick(AdapterView> arg0, View arg1, int arg2, long arg3) {
320 | // TODO Auto-generated method stub
321 | AppInfo mAppInfo = (AppInfo)arg0.getItemAtPosition(arg2);
322 | launch_app(mAppInfo);
323 | }
324 |
325 | private void launch_app(AppInfo app) {
326 | app.setActivity(app.mComponentName, Intent_Flag);
327 | try {
328 | startActivity(app.intent);
329 | } catch (ActivityNotFoundException e) {
330 |
331 | }
332 | finish();
333 | }
334 | }
335 |
--------------------------------------------------------------------------------
/src/com/koalcat/blurdemo/FastBitmapDrawable.java:
--------------------------------------------------------------------------------
1 | package com.koalcat.blurdemo;
2 | /**
3 | * @author xuchdeid@gmail.com
4 | * __________________________ \_/
5 | | | /._.\
6 | | Android!Android! > U| |U
7 | | xuchdeid | |___|
8 | |__________________________| U U
9 | * */
10 | import android.graphics.drawable.Drawable;
11 | import android.graphics.PixelFormat;
12 | import android.graphics.Bitmap;
13 | import android.graphics.Canvas;
14 | import android.graphics.ColorFilter;
15 |
16 | public class FastBitmapDrawable extends Drawable {
17 | private Bitmap mBitmap;
18 |
19 | public FastBitmapDrawable(Bitmap b) {
20 | mBitmap = b;
21 | }
22 |
23 | @Override
24 | public void draw(Canvas canvas) {
25 | canvas.drawBitmap(mBitmap, 0.0f, 0.0f, null);
26 | }
27 |
28 | @Override
29 | public int getOpacity() {
30 | return PixelFormat.TRANSLUCENT;
31 | }
32 |
33 | @Override
34 | public void setAlpha(int alpha) {}
35 |
36 | @Override
37 | public void setColorFilter(ColorFilter cf) {}
38 |
39 | @Override
40 | public int getIntrinsicWidth() {
41 | return mBitmap.getWidth();
42 | }
43 |
44 | @Override
45 | public int getIntrinsicHeight() {
46 | return mBitmap.getHeight();
47 | }
48 |
49 | @Override
50 | public int getMinimumWidth() {
51 | return mBitmap.getWidth();
52 | }
53 |
54 | @Override
55 | public int getMinimumHeight() {
56 | return mBitmap.getHeight();
57 | }
58 |
59 | public Bitmap getBitmap() {
60 | return mBitmap;
61 | }
62 | }
63 |
64 |
65 |
--------------------------------------------------------------------------------
/src/com/koalcat/blurdemo/HanziToPinyin.java:
--------------------------------------------------------------------------------
1 | package com.koalcat.blurdemo;
2 |
3 | import android.text.TextUtils;
4 | import android.util.Log;
5 |
6 | import java.text.Collator;
7 | import java.util.ArrayList;
8 | import java.util.Locale;
9 | /**
10 | * An object to convert Chinese character to its corresponding pinyin string. For characters with
11 | * multiple possible pinyin string, only one is selected according to collator. Polyphone is not
12 | * supported in this implementation. This class is implemented to achieve the best runtime
13 | * performance and minimum runtime resources with tolerable sacrifice of accuracy. This
14 | * implementation highly depends on zh_CN ICU collation data and must be always synchronized with
15 | * ICU.
16 | *
17 | * Currently this file is aligned to zh.txt in ICU 4.6
18 | */
19 | public class HanziToPinyin {
20 | private static final String TAG = "HanziToPinyin";
21 |
22 | // Turn on this flag when we want to check internal data structure.
23 | private static final boolean DEBUG = true;
24 |
25 | /**
26 | * Unihans array. Each unihans is the first one within same pinyin. Use it to determine pinyin
27 | * for all ~20k unihans.
28 | */
29 | public static final char[] UNIHANS = {
30 | '\u5475', '\u54ce', '\u5b89', '\u80ae', '\u51f9',
31 | '\u516b', '\u6300', '\u6273', '\u90a6', '\u5305', '\u5351', '\u5954', '\u4f3b',
32 | '\u5c44', '\u8fb9', '\u6807', '\u618b', '\u90a0', '\u69df', '\u7676', '\u5cec',
33 | '\u5693', '\u5a47', '\u98e1', '\u4ed3', '\u64cd', '\u518a', '\u5d7e', '\u564c',
34 | '\u53c9', '\u9497', '\u8fbf', '\u4f25', '\u6284', '\u8f66', '\u62bb', '\u67fd',
35 | '\u5403', '\u5145', '\u62bd', '\u51fa', '\u6b3b', '\u63e3', '\u5ddd', '\u75ae',
36 | '\u5439', '\u6776', '\u9034', '\u75b5', '\u5306', '\u51d1', '\u7c97', '\u6c46',
37 | '\u5d14', '\u90a8', '\u6413', '\u5491', '\u5927', '\u75b8', '\u5f53', '\u5200',
38 | '\u6dc2', '\u5f97', '\u6265', '\u706f', '\u6c10', '\u55f2', '\u7538', '\u5201',
39 | '\u7239', '\u4ec3', '\u4e1f', '\u4e1c', '\u5517', '\u561f', '\u5073', '\u5806',
40 | '\u9413', '\u591a', '\u5a40', '\u8bf6', '\u5940', '\u97a5', '\u800c', '\u53d1',
41 | '\u5e06', '\u65b9', '\u98de', '\u5206', '\u4e30', '\u8985', '\u4ecf', '\u7d11',
42 | '\u4f15', '\u65ee', '\u8be5', '\u7518', '\u5188', '\u768b', '\u6208', '\u7d66',
43 | '\u6839', '\u5e9a', '\u5de5', '\u52fe', '\u4f30', '\u74dc', '\u7f6b', '\u5173',
44 | '\u5149', '\u5f52', '\u886e', '\u5459', '\u54c8', '\u54b3', '\u9878', '\u82c0',
45 | '\u84bf', '\u8bc3', '\u9ed2', '\u62eb', '\u4ea8', '\u5677', '\u543d', '\u9f41',
46 | '\u5322', '\u82b1', '\u6000', '\u72bf', '\u5ddf', '\u7070', '\u660f', '\u5419',
47 | '\u4e0c', '\u52a0', '\u620b', '\u6c5f', '\u827d', '\u9636', '\u5dfe', '\u52a4',
48 | '\u5182', '\u52fc', '\u530a', '\u5a1f', '\u5658', '\u519b', '\u5494', '\u5f00',
49 | '\u520a', '\u95f6', '\u5c3b', '\u533c', '\u524b', '\u80af', '\u962c', '\u7a7a',
50 | '\u62a0', '\u5233', '\u5938', '\u84af', '\u5bbd', '\u5321', '\u4e8f', '\u5764',
51 | '\u6269', '\u5783', '\u6765', '\u5170', '\u5577', '\u635e', '\u4ec2', '\u52d2',
52 | '\u5844', '\u5215', '\u5006', '\u5941', '\u826f', '\u64a9', '\u5217', '\u62ce',
53 | '\u3007', '\u6e9c', '\u9f99', '\u779c', '\u565c', '\u5a08', '\u7567', '\u62a1',
54 | '\u7f57', '\u5463', '\u5988', '\u973e', '\u5ada', '\u9099', '\u732b', '\u9ebc',
55 | '\u6c92', '\u95e8', '\u753f', '\u54aa', '\u7720', '\u55b5', '\u54a9', '\u6c11',
56 | '\u540d', '\u8c2c', '\u6478', '\u54de', '\u6bea', '\u62cf', '\u5b7b', '\u56e1',
57 | '\u56ca', '\u5b6c', '\u8bb7', '\u9981', '\u6041', '\u80fd', '\u59ae', '\u62c8',
58 | '\u5b22', '\u9e1f', '\u634f', '\u60a8', '\u5b81', '\u599e', '\u519c', '\u7fba',
59 | '\u5974', '\u597b', '\u8650', '\u632a', '\u5594', '\u8bb4', '\u8db4', '\u62cd',
60 | '\u7705', '\u4e53', '\u629b', '\u5478', '\u55b7', '\u5309', '\u4e15', '\u504f',
61 | '\u527d', '\u6c15', '\u59d8', '\u4e52', '\u948b', '\u5256', '\u4ec6', '\u4e03',
62 | '\u6390', '\u5343', '\u545b', '\u6084', '\u767f', '\u4fb5', '\u9751', '\u909b',
63 | '\u4e18', '\u66f2', '\u5f2e', '\u7f3a', '\u590b', '\u5465', '\u7a63', '\u5a06',
64 | '\u60f9', '\u4eba', '\u6254', '\u65e5', '\u8338', '\u53b9', '\u5982', '\u5827',
65 | '\u6875', '\u95f0', '\u82e5', '\u4ee8', '\u6be2', '\u4e09', '\u6852', '\u63bb',
66 | '\u8272', '\u68ee', '\u50e7', '\u6740', '\u7b5b', '\u5c71', '\u4f24', '\u5f30',
67 | '\u5962', '\u7533', '\u5347', '\u5c38', '\u53ce', '\u4e66', '\u5237', '\u6454',
68 | '\u95e9', '\u53cc', '\u8c01', '\u542e', '\u5981', '\u53b6', '\u5fea', '\u635c',
69 | '\u82cf', '\u72fb', '\u590a', '\u5b59', '\u5506', '\u4ed6', '\u82d4', '\u574d',
70 | '\u94f4', '\u5932', '\u5fd1', '\u71a5', '\u5254', '\u5929', '\u4f7b', '\u5e16',
71 | '\u5385', '\u56f2', '\u5077', '\u92c0', '\u6e4d', '\u63a8', '\u541e', '\u6258',
72 | '\u6316', '\u6b6a', '\u5f2f', '\u5c2a', '\u5371', '\u586d', '\u7fc1', '\u631d',
73 | '\u5140', '\u5915', '\u867e', '\u4eda', '\u4e61', '\u7071', '\u4e9b', '\u5fc3',
74 | '\u661f', '\u51f6', '\u4f11', '\u65f4', '\u8f69', '\u75b6', '\u52cb', '\u4e2b',
75 | '\u6079', '\u592e', '\u5e7a', '\u8036', '\u4e00', '\u6b2d', '\u5e94', '\u54df',
76 | '\u4f63', '\u4f18', '\u625c', '\u9e22', '\u66f0', '\u6655', '\u531d', '\u707d',
77 | '\u7ccc', '\u7242', '\u50ae', '\u5219', '\u8d3c', '\u600e', '\u5897', '\u5412',
78 | '\u635a', '\u6cbe', '\u5f20', '\u948a', '\u8707', '\u8d1e', '\u4e89', '\u4e4b',
79 | '\u4e2d', '\u5dde', '\u6731', '\u6293', '\u8de9', '\u4e13', '\u5986', '\u96b9',
80 | '\u5b92', '\u5353', '\u5b5c', '\u5b97', '\u90b9', '\u79df', '\u94bb', '\u539c',
81 | '\u5c0a', '\u6628', };
82 |
83 | /**
84 | * Pinyin array. Each pinyin is corresponding to unihans of same offset in the unihans array.
85 | */
86 | public static final byte[][] PINYINS = {
87 | { 65, 0, 0, 0, 0, 0 }, { 65, 73, 0, 0, 0, 0 }, { 65, 78, 0, 0, 0, 0 },
88 | { 65, 78, 71, 0, 0, 0 }, { 65, 79, 0, 0, 0, 0 }, { 66, 65, 0, 0, 0, 0 },
89 | { 66, 65, 73, 0, 0, 0 }, { 66, 65, 78, 0, 0, 0 }, { 66, 65, 78, 71, 0, 0 },
90 | { 66, 65, 79, 0, 0, 0 }, { 66, 69, 73, 0, 0, 0 }, { 66, 69, 78, 0, 0, 0 },
91 | { 66, 69, 78, 71, 0, 0 }, { 66, 73, 0, 0, 0, 0 }, { 66, 73, 65, 78, 0, 0 },
92 | { 66, 73, 65, 79, 0, 0 }, { 66, 73, 69, 0, 0, 0 }, { 66, 73, 78, 0, 0, 0 },
93 | { 66, 73, 78, 71, 0, 0 }, { 66, 79, 0, 0, 0, 0 }, { 66, 85, 0, 0, 0, 0 },
94 | { 67, 65, 0, 0, 0, 0 }, { 67, 65, 73, 0, 0, 0 },
95 | { 67, 65, 78, 0, 0, 0 }, { 67, 65, 78, 71, 0, 0 }, { 67, 65, 79, 0, 0, 0 },
96 | { 67, 69, 0, 0, 0, 0 }, { 67, 69, 78, 0, 0, 0 }, { 67, 69, 78, 71, 0, 0 },
97 | { 67, 72, 65, 0, 0, 0 }, { 67, 72, 65, 73, 0, 0 }, { 67, 72, 65, 78, 0, 0 },
98 | { 67, 72, 65, 78, 71, 0 }, { 67, 72, 65, 79, 0, 0 }, { 67, 72, 69, 0, 0, 0 },
99 | { 67, 72, 69, 78, 0, 0 }, { 67, 72, 69, 78, 71, 0 }, { 67, 72, 73, 0, 0, 0 },
100 | { 67, 72, 79, 78, 71, 0 }, { 67, 72, 79, 85, 0, 0 }, { 67, 72, 85, 0, 0, 0 },
101 | { 67, 72, 85, 65, 0, 0 }, { 67, 72, 85, 65, 73, 0 }, { 67, 72, 85, 65, 78, 0 },
102 | { 67, 72, 85, 65, 78, 71 }, { 67, 72, 85, 73, 0, 0 }, { 67, 72, 85, 78, 0, 0 },
103 | { 67, 72, 85, 79, 0, 0 }, { 67, 73, 0, 0, 0, 0 }, { 67, 79, 78, 71, 0, 0 },
104 | { 67, 79, 85, 0, 0, 0 }, { 67, 85, 0, 0, 0, 0 }, { 67, 85, 65, 78, 0, 0 },
105 | { 67, 85, 73, 0, 0, 0 }, { 67, 85, 78, 0, 0, 0 }, { 67, 85, 79, 0, 0, 0 },
106 | { 68, 65, 0, 0, 0, 0 }, { 68, 65, 73, 0, 0, 0 }, { 68, 65, 78, 0, 0, 0 },
107 | { 68, 65, 78, 71, 0, 0 }, { 68, 65, 79, 0, 0, 0 }, { 68, 69, 0, 0, 0, 0 },
108 | { 68, 69, 73, 0, 0, 0 }, { 68, 69, 78, 0, 0, 0 }, { 68, 69, 78, 71, 0, 0 },
109 | { 68, 73, 0, 0, 0, 0 }, { 68, 73, 65, 0, 0, 0 }, { 68, 73, 65, 78, 0, 0 },
110 | { 68, 73, 65, 79, 0, 0 }, { 68, 73, 69, 0, 0, 0 }, { 68, 73, 78, 71, 0, 0 },
111 | { 68, 73, 85, 0, 0, 0 }, { 68, 79, 78, 71, 0, 0 }, { 68, 79, 85, 0, 0, 0 },
112 | { 68, 85, 0, 0, 0, 0 }, { 68, 85, 65, 78, 0, 0 }, { 68, 85, 73, 0, 0, 0 },
113 | { 68, 85, 78, 0, 0, 0 }, { 68, 85, 79, 0, 0, 0 }, { 69, 0, 0, 0, 0, 0 },
114 | { 69, 73, 0, 0, 0, 0 }, { 69, 78, 0, 0, 0, 0 }, { 69, 78, 71, 0, 0, 0 },
115 | { 69, 82, 0, 0, 0, 0 }, { 70, 65, 0, 0, 0, 0 }, { 70, 65, 78, 0, 0, 0 },
116 | { 70, 65, 78, 71, 0, 0 }, { 70, 69, 73, 0, 0, 0 }, { 70, 69, 78, 0, 0, 0 },
117 | { 70, 69, 78, 71, 0, 0 }, { 70, 73, 65, 79, 0, 0 }, { 70, 79, 0, 0, 0, 0 },
118 | { 70, 79, 85, 0, 0, 0 }, { 70, 85, 0, 0, 0, 0 }, { 71, 65, 0, 0, 0, 0 },
119 | { 71, 65, 73, 0, 0, 0 }, { 71, 65, 78, 0, 0, 0 }, { 71, 65, 78, 71, 0, 0 },
120 | { 71, 65, 79, 0, 0, 0 }, { 71, 69, 0, 0, 0, 0 }, { 71, 69, 73, 0, 0, 0 },
121 | { 71, 69, 78, 0, 0, 0 }, { 71, 69, 78, 71, 0, 0 }, { 71, 79, 78, 71, 0, 0 },
122 | { 71, 79, 85, 0, 0, 0 }, { 71, 85, 0, 0, 0, 0 }, { 71, 85, 65, 0, 0, 0 },
123 | { 71, 85, 65, 73, 0, 0 }, { 71, 85, 65, 78, 0, 0 }, { 71, 85, 65, 78, 71, 0 },
124 | { 71, 85, 73, 0, 0, 0 }, { 71, 85, 78, 0, 0, 0 }, { 71, 85, 79, 0, 0, 0 },
125 | { 72, 65, 0, 0, 0, 0 }, { 72, 65, 73, 0, 0, 0 }, { 72, 65, 78, 0, 0, 0 },
126 | { 72, 65, 78, 71, 0, 0 }, { 72, 65, 79, 0, 0, 0 }, { 72, 69, 0, 0, 0, 0 },
127 | { 72, 69, 73, 0, 0, 0 }, { 72, 69, 78, 0, 0, 0 }, { 72, 69, 78, 71, 0, 0 },
128 | { 72, 77, 0, 0, 0, 0 }, { 72, 79, 78, 71, 0, 0 }, { 72, 79, 85, 0, 0, 0 },
129 | { 72, 85, 0, 0, 0, 0 }, { 72, 85, 65, 0, 0, 0 }, { 72, 85, 65, 73, 0, 0 },
130 | { 72, 85, 65, 78, 0, 0 }, { 72, 85, 65, 78, 71, 0 }, { 72, 85, 73, 0, 0, 0 },
131 | { 72, 85, 78, 0, 0, 0 }, { 72, 85, 79, 0, 0, 0 }, { 74, 73, 0, 0, 0, 0 },
132 | { 74, 73, 65, 0, 0, 0 }, { 74, 73, 65, 78, 0, 0 }, { 74, 73, 65, 78, 71, 0 },
133 | { 74, 73, 65, 79, 0, 0 }, { 74, 73, 69, 0, 0, 0 }, { 74, 73, 78, 0, 0, 0 },
134 | { 74, 73, 78, 71, 0, 0 }, { 74, 73, 79, 78, 71, 0 }, { 74, 73, 85, 0, 0, 0 },
135 | { 74, 85, 0, 0, 0, 0 }, { 74, 85, 65, 78, 0, 0 }, { 74, 85, 69, 0, 0, 0 },
136 | { 74, 85, 78, 0, 0, 0 }, { 75, 65, 0, 0, 0, 0 }, { 75, 65, 73, 0, 0, 0 },
137 | { 75, 65, 78, 0, 0, 0 }, { 75, 65, 78, 71, 0, 0 }, { 75, 65, 79, 0, 0, 0 },
138 | { 75, 69, 0, 0, 0, 0 }, { 75, 69, 73, 0, 0, 0 }, { 75, 69, 78, 0, 0, 0 },
139 | { 75, 69, 78, 71, 0, 0 }, { 75, 79, 78, 71, 0, 0 }, { 75, 79, 85, 0, 0, 0 },
140 | { 75, 85, 0, 0, 0, 0 }, { 75, 85, 65, 0, 0, 0 }, { 75, 85, 65, 73, 0, 0 },
141 | { 75, 85, 65, 78, 0, 0 }, { 75, 85, 65, 78, 71, 0 }, { 75, 85, 73, 0, 0, 0 },
142 | { 75, 85, 78, 0, 0, 0 }, { 75, 85, 79, 0, 0, 0 }, { 76, 65, 0, 0, 0, 0 },
143 | { 76, 65, 73, 0, 0, 0 }, { 76, 65, 78, 0, 0, 0 }, { 76, 65, 78, 71, 0, 0 },
144 | { 76, 65, 79, 0, 0, 0 }, { 76, 69, 0, 0, 0, 0 }, { 76, 69, 73, 0, 0, 0 },
145 | { 76, 69, 78, 71, 0, 0 }, { 76, 73, 0, 0, 0, 0 }, { 76, 73, 65, 0, 0, 0 },
146 | { 76, 73, 65, 78, 0, 0 }, { 76, 73, 65, 78, 71, 0 }, { 76, 73, 65, 79, 0, 0 },
147 | { 76, 73, 69, 0, 0, 0 }, { 76, 73, 78, 0, 0, 0 }, { 76, 73, 78, 71, 0, 0 },
148 | { 76, 73, 85, 0, 0, 0 }, { 76, 79, 78, 71, 0, 0 }, { 76, 79, 85, 0, 0, 0 },
149 | { 76, 85, 0, 0, 0, 0 }, { 76, 85, 65, 78, 0, 0 }, { 76, 85, 69, 0, 0, 0 },
150 | { 76, 85, 78, 0, 0, 0 }, { 76, 85, 79, 0, 0, 0 }, { 77, 0, 0, 0, 0, 0 },
151 | { 77, 65, 0, 0, 0, 0 }, { 77, 65, 73, 0, 0, 0 }, { 77, 65, 78, 0, 0, 0 },
152 | { 77, 65, 78, 71, 0, 0 }, { 77, 65, 79, 0, 0, 0 }, { 77, 69, 0, 0, 0, 0 },
153 | { 77, 69, 73, 0, 0, 0 }, { 77, 69, 78, 0, 0, 0 }, { 77, 69, 78, 71, 0, 0 },
154 | { 77, 73, 0, 0, 0, 0 }, { 77, 73, 65, 78, 0, 0 }, { 77, 73, 65, 79, 0, 0 },
155 | { 77, 73, 69, 0, 0, 0 }, { 77, 73, 78, 0, 0, 0 }, { 77, 73, 78, 71, 0, 0 },
156 | { 77, 73, 85, 0, 0, 0 }, { 77, 79, 0, 0, 0, 0 }, { 77, 79, 85, 0, 0, 0 },
157 | { 77, 85, 0, 0, 0, 0 }, { 78, 65, 0, 0, 0, 0 }, { 78, 65, 73, 0, 0, 0 },
158 | { 78, 65, 78, 0, 0, 0 }, { 78, 65, 78, 71, 0, 0 }, { 78, 65, 79, 0, 0, 0 },
159 | { 78, 69, 0, 0, 0, 0 }, { 78, 69, 73, 0, 0, 0 }, { 78, 69, 78, 0, 0, 0 },
160 | { 78, 69, 78, 71, 0, 0 }, { 78, 73, 0, 0, 0, 0 }, { 78, 73, 65, 78, 0, 0 },
161 | { 78, 73, 65, 78, 71, 0 }, { 78, 73, 65, 79, 0, 0 }, { 78, 73, 69, 0, 0, 0 },
162 | { 78, 73, 78, 0, 0, 0 }, { 78, 73, 78, 71, 0, 0 }, { 78, 73, 85, 0, 0, 0 },
163 | { 78, 79, 78, 71, 0, 0 }, { 78, 79, 85, 0, 0, 0 }, { 78, 85, 0, 0, 0, 0 },
164 | { 78, 85, 65, 78, 0, 0 }, { 78, 85, 69, 0, 0, 0 }, { 78, 85, 79, 0, 0, 0 },
165 | { 79, 0, 0, 0, 0, 0 }, { 79, 85, 0, 0, 0, 0 }, { 80, 65, 0, 0, 0, 0 },
166 | { 80, 65, 73, 0, 0, 0 }, { 80, 65, 78, 0, 0, 0 }, { 80, 65, 78, 71, 0, 0 },
167 | { 80, 65, 79, 0, 0, 0 }, { 80, 69, 73, 0, 0, 0 }, { 80, 69, 78, 0, 0, 0 },
168 | { 80, 69, 78, 71, 0, 0 }, { 80, 73, 0, 0, 0, 0 }, { 80, 73, 65, 78, 0, 0 },
169 | { 80, 73, 65, 79, 0, 0 }, { 80, 73, 69, 0, 0, 0 }, { 80, 73, 78, 0, 0, 0 },
170 | { 80, 73, 78, 71, 0, 0 }, { 80, 79, 0, 0, 0, 0 }, { 80, 79, 85, 0, 0, 0 },
171 | { 80, 85, 0, 0, 0, 0 }, { 81, 73, 0, 0, 0, 0 }, { 81, 73, 65, 0, 0, 0 },
172 | { 81, 73, 65, 78, 0, 0 }, { 81, 73, 65, 78, 71, 0 }, { 81, 73, 65, 79, 0, 0 },
173 | { 81, 73, 69, 0, 0, 0 }, { 81, 73, 78, 0, 0, 0 }, { 81, 73, 78, 71, 0, 0 },
174 | { 81, 73, 79, 78, 71, 0 }, { 81, 73, 85, 0, 0, 0 }, { 81, 85, 0, 0, 0, 0 },
175 | { 81, 85, 65, 78, 0, 0 }, { 81, 85, 69, 0, 0, 0 }, { 81, 85, 78, 0, 0, 0 },
176 | { 82, 65, 78, 0, 0, 0 }, { 82, 65, 78, 71, 0, 0 }, { 82, 65, 79, 0, 0, 0 },
177 | { 82, 69, 0, 0, 0, 0 }, { 82, 69, 78, 0, 0, 0 }, { 82, 69, 78, 71, 0, 0 },
178 | { 82, 73, 0, 0, 0, 0 }, { 82, 79, 78, 71, 0, 0 }, { 82, 79, 85, 0, 0, 0 },
179 | { 82, 85, 0, 0, 0, 0 }, { 82, 85, 65, 78, 0, 0 }, { 82, 85, 73, 0, 0, 0 },
180 | { 82, 85, 78, 0, 0, 0 }, { 82, 85, 79, 0, 0, 0 }, { 83, 65, 0, 0, 0, 0 },
181 | { 83, 65, 73, 0, 0, 0 }, { 83, 65, 78, 0, 0, 0 }, { 83, 65, 78, 71, 0, 0 },
182 | { 83, 65, 79, 0, 0, 0 }, { 83, 69, 0, 0, 0, 0 }, { 83, 69, 78, 0, 0, 0 },
183 | { 83, 69, 78, 71, 0, 0 }, { 83, 72, 65, 0, 0, 0 }, { 83, 72, 65, 73, 0, 0 },
184 | { 83, 72, 65, 78, 0, 0 }, { 83, 72, 65, 78, 71, 0 }, { 83, 72, 65, 79, 0, 0 },
185 | { 83, 72, 69, 0, 0, 0 }, { 83, 72, 69, 78, 0, 0 }, { 83, 72, 69, 78, 71, 0 },
186 | { 83, 72, 73, 0, 0, 0 }, { 83, 72, 79, 85, 0, 0 }, { 83, 72, 85, 0, 0, 0 },
187 | { 83, 72, 85, 65, 0, 0 }, { 83, 72, 85, 65, 73, 0 }, { 83, 72, 85, 65, 78, 0 },
188 | { 83, 72, 85, 65, 78, 71 }, { 83, 72, 85, 73, 0, 0 }, { 83, 72, 85, 78, 0, 0 },
189 | { 83, 72, 85, 79, 0, 0 }, { 83, 73, 0, 0, 0, 0 }, { 83, 79, 78, 71, 0, 0 },
190 | { 83, 79, 85, 0, 0, 0 }, { 83, 85, 0, 0, 0, 0 }, { 83, 85, 65, 78, 0, 0 },
191 | { 83, 85, 73, 0, 0, 0 }, { 83, 85, 78, 0, 0, 0 }, { 83, 85, 79, 0, 0, 0 },
192 | { 84, 65, 0, 0, 0, 0 }, { 84, 65, 73, 0, 0, 0 }, { 84, 65, 78, 0, 0, 0 },
193 | { 84, 65, 78, 71, 0, 0 }, { 84, 65, 79, 0, 0, 0 }, { 84, 69, 0, 0, 0, 0 },
194 | { 84, 69, 78, 71, 0, 0 }, { 84, 73, 0, 0, 0, 0 }, { 84, 73, 65, 78, 0, 0 },
195 | { 84, 73, 65, 79, 0, 0 }, { 84, 73, 69, 0, 0, 0 }, { 84, 73, 78, 71, 0, 0 },
196 | { 84, 79, 78, 71, 0, 0 }, { 84, 79, 85, 0, 0, 0 }, { 84, 85, 0, 0, 0, 0 },
197 | { 84, 85, 65, 78, 0, 0 }, { 84, 85, 73, 0, 0, 0 }, { 84, 85, 78, 0, 0, 0 },
198 | { 84, 85, 79, 0, 0, 0 }, { 87, 65, 0, 0, 0, 0 }, { 87, 65, 73, 0, 0, 0 },
199 | { 87, 65, 78, 0, 0, 0 }, { 87, 65, 78, 71, 0, 0 }, { 87, 69, 73, 0, 0, 0 },
200 | { 87, 69, 78, 0, 0, 0 }, { 87, 69, 78, 71, 0, 0 }, { 87, 79, 0, 0, 0, 0 },
201 | { 87, 85, 0, 0, 0, 0 }, { 88, 73, 0, 0, 0, 0 }, { 88, 73, 65, 0, 0, 0 },
202 | { 88, 73, 65, 78, 0, 0 }, { 88, 73, 65, 78, 71, 0 }, { 88, 73, 65, 79, 0, 0 },
203 | { 88, 73, 69, 0, 0, 0 }, { 88, 73, 78, 0, 0, 0 }, { 88, 73, 78, 71, 0, 0 },
204 | { 88, 73, 79, 78, 71, 0 }, { 88, 73, 85, 0, 0, 0 }, { 88, 85, 0, 0, 0, 0 },
205 | { 88, 85, 65, 78, 0, 0 }, { 88, 85, 69, 0, 0, 0 }, { 88, 85, 78, 0, 0, 0 },
206 | { 89, 65, 0, 0, 0, 0 }, { 89, 65, 78, 0, 0, 0 }, { 89, 65, 78, 71, 0, 0 },
207 | { 89, 65, 79, 0, 0, 0 }, { 89, 69, 0, 0, 0, 0 }, { 89, 73, 0, 0, 0, 0 },
208 | { 89, 73, 78, 0, 0, 0 }, { 89, 73, 78, 71, 0, 0 }, { 89, 79, 0, 0, 0, 0 },
209 | { 89, 79, 78, 71, 0, 0 }, { 89, 79, 85, 0, 0, 0 }, { 89, 85, 0, 0, 0, 0 },
210 | { 89, 85, 65, 78, 0, 0 }, { 89, 85, 69, 0, 0, 0 }, { 89, 85, 78, 0, 0, 0 },
211 | { 90, 65, 0, 0, 0, 0 }, { 90, 65, 73, 0, 0, 0 }, { 90, 65, 78, 0, 0, 0 },
212 | { 90, 65, 78, 71, 0, 0 }, { 90, 65, 79, 0, 0, 0 }, { 90, 69, 0, 0, 0, 0 },
213 | { 90, 69, 73, 0, 0, 0 }, { 90, 69, 78, 0, 0, 0 }, { 90, 69, 78, 71, 0, 0 },
214 | { 90, 72, 65, 0, 0, 0 }, { 90, 72, 65, 73, 0, 0 }, { 90, 72, 65, 78, 0, 0 },
215 | { 90, 72, 65, 78, 71, 0 }, { 90, 72, 65, 79, 0, 0 }, { 90, 72, 69, 0, 0, 0 },
216 | { 90, 72, 69, 78, 0, 0 }, { 90, 72, 69, 78, 71, 0 }, { 90, 72, 73, 0, 0, 0 },
217 | { 90, 72, 79, 78, 71, 0 }, { 90, 72, 79, 85, 0, 0 }, { 90, 72, 85, 0, 0, 0 },
218 | { 90, 72, 85, 65, 0, 0 }, { 90, 72, 85, 65, 73, 0 }, { 90, 72, 85, 65, 78, 0 },
219 | { 90, 72, 85, 65, 78, 71 }, { 90, 72, 85, 73, 0, 0 }, { 90, 72, 85, 78, 0, 0 },
220 | { 90, 72, 85, 79, 0, 0 }, { 90, 73, 0, 0, 0, 0 }, { 90, 79, 78, 71, 0, 0 },
221 | { 90, 79, 85, 0, 0, 0 }, { 90, 85, 0, 0, 0, 0 }, { 90, 85, 65, 78, 0, 0 },
222 | { 90, 85, 73, 0, 0, 0 }, { 90, 85, 78, 0, 0, 0 }, { 90, 85, 79, 0, 0, 0 }, };
223 |
224 | /** First and last Chinese character with known Pinyin according to zh collation */
225 | private static final String FIRST_PINYIN_UNIHAN = "\u963F";
226 | private static final String LAST_PINYIN_UNIHAN = "\u84D9";
227 | /** The first Chinese character in Unicode block */
228 | private static final char FIRST_UNIHAN = '\u3400';
229 | private static final Collator COLLATOR = Collator.getInstance(Locale.CHINA);
230 |
231 | private static HanziToPinyin sInstance;
232 | private final boolean mHasChinaCollator;
233 |
234 | public static class Token {
235 | /**
236 | * Separator between target string for each source char
237 | */
238 | public static final String SEPARATOR = " ";
239 |
240 | public static final int LATIN = 1;
241 | public static final int PINYIN = 2;
242 | public static final int UNKNOWN = 3;
243 |
244 | public Token() {
245 | }
246 |
247 | public Token(int type, String source, String target) {
248 | this.type = type;
249 | this.source = source;
250 | this.target = target;
251 | }
252 |
253 | /**
254 | * Type of this token, ASCII, PINYIN or UNKNOWN.
255 | */
256 | public int type;
257 | /**
258 | * Original string before translation.
259 | */
260 | public String source;
261 | /**
262 | * Translated string of source. For Han, target is corresponding Pinyin. Otherwise target is
263 | * original string in source.
264 | */
265 | public String target;
266 | }
267 |
268 | protected HanziToPinyin(boolean hasChinaCollator) {
269 | mHasChinaCollator = hasChinaCollator;
270 | }
271 |
272 | public static HanziToPinyin getInstance() {
273 | synchronized (HanziToPinyin.class) {
274 | if (sInstance != null) {
275 | return sInstance;
276 | }
277 | // Check if zh_CN collation data is available
278 | /*final Locale locale[] = Collator.getAvailableLocales();
279 | for (int i = 0; i < locale.length; i++) {
280 | if (locale[i].equals(Locale.CHINA)) {
281 | // Do self validation just once.
282 | if (DEBUG) {
283 | Log.d(TAG, "Self validation. Result: " + doSelfValidation());
284 | }*/
285 | sInstance = new HanziToPinyin(true);
286 | return sInstance;
287 | /* }
288 | }
289 | Log.w(TAG, "There is no Chinese collator, HanziToPinyin is disabled");
290 | sInstance = new HanziToPinyin(false);
291 | return sInstance;*/
292 | }
293 | }
294 |
295 | /**
296 | * Validate if our internal table has some wrong value.
297 | *
298 | * @return true when the table looks correct.
299 | */
300 | private static boolean doSelfValidation() {
301 | char lastChar = UNIHANS[0];
302 | String lastString = Character.toString(lastChar);
303 | for (char c : UNIHANS) {
304 | if (lastChar == c) {
305 | continue;
306 | }
307 | final String curString = Character.toString(c);
308 | int cmp = COLLATOR.compare(lastString, curString);
309 | if (cmp >= 0) {
310 | Log.e(TAG, "Internal error in Unihan table. " + "The last string \"" + lastString
311 | + "\" is greater than current string \"" + curString + "\".");
312 | return false;
313 | }
314 | lastString = curString;
315 | }
316 | return true;
317 | }
318 |
319 | private Token getToken(char character) {
320 | Token token = new Token();
321 | final String letter = Character.toString(character);
322 | token.source = letter;
323 | int offset = -1;
324 | int cmp;
325 | if (character < 256) {
326 | token.type = Token.LATIN;
327 | token.target = letter;
328 | return token;
329 | } else if (character < FIRST_UNIHAN) {
330 | token.type = Token.UNKNOWN;
331 | token.target = letter;
332 | return token;
333 | } else {
334 | cmp = COLLATOR.compare(letter, FIRST_PINYIN_UNIHAN);
335 | if (cmp < 0) {
336 | token.type = Token.UNKNOWN;
337 | token.target = letter;
338 | return token;
339 | } else if (cmp == 0) {
340 | token.type = Token.PINYIN;
341 | offset = 0;
342 | } else {
343 | cmp = COLLATOR.compare(letter, LAST_PINYIN_UNIHAN);
344 | if (cmp > 0) {
345 | token.type = Token.UNKNOWN;
346 | token.target = letter;
347 | return token;
348 | } else if (cmp == 0) {
349 | token.type = Token.PINYIN;
350 | offset = UNIHANS.length - 1;
351 | }
352 | }
353 | }
354 |
355 | token.type = Token.PINYIN;
356 | if (offset < 0) {
357 | int begin = 0;
358 | int end = UNIHANS.length - 1;
359 | while (begin <= end) {
360 | offset = (begin + end) / 2;
361 | final String unihan = Character.toString(UNIHANS[offset]);
362 | cmp = COLLATOR.compare(letter, unihan);
363 | if (cmp == 0) {
364 | break;
365 | } else if (cmp > 0) {
366 | begin = offset + 1;
367 | } else {
368 | end = offset - 1;
369 | }
370 | }
371 | }
372 | if (cmp < 0) {
373 | offset--;
374 | }
375 | StringBuilder pinyin = new StringBuilder();
376 | for (int j = 0; j < PINYINS[offset].length && PINYINS[offset][j] != 0; j++) {
377 | pinyin.append((char) PINYINS[offset][j]);
378 | }
379 | token.target = pinyin.toString();
380 | return token;
381 | }
382 |
383 | /**
384 | * Convert the input to a array of tokens. The sequence of ASCII or Unknown characters without
385 | * space will be put into a Token, One Hanzi character which has pinyin will be treated as a
386 | * Token. If these is no China collator, the empty token array is returned.
387 | */
388 | public ArrayList get(final String input) {
389 | ArrayList tokens = new ArrayList();
390 | if (!mHasChinaCollator || TextUtils.isEmpty(input)) {
391 | // return empty tokens.
392 | return tokens;
393 | }
394 | final int inputLength = input.length();
395 | final StringBuilder sb = new StringBuilder();
396 | int tokenType = Token.LATIN;
397 | // Go through the input, create a new token when
398 | // a. Token type changed
399 | // b. Get the Pinyin of current charater.
400 | // c. current character is space.
401 | for (int i = 0; i < inputLength; i++) {
402 | final char character = input.charAt(i);
403 | if (character == ' ') {
404 | if (sb.length() > 0) {
405 | addToken(sb, tokens, tokenType);
406 | }
407 | } else if (character < 256) {
408 | if (tokenType != Token.LATIN && sb.length() > 0) {
409 | addToken(sb, tokens, tokenType);
410 | }
411 | tokenType = Token.LATIN;
412 | sb.append(character);
413 | } else if (character < FIRST_UNIHAN) {
414 | if (tokenType != Token.UNKNOWN && sb.length() > 0) {
415 | addToken(sb, tokens, tokenType);
416 | }
417 | tokenType = Token.UNKNOWN;
418 | sb.append(character);
419 | } else {
420 | Token t = getToken(character);
421 | if (t.type == Token.PINYIN) {
422 | if (sb.length() > 0) {
423 | addToken(sb, tokens, tokenType);
424 | }
425 | tokens.add(t);
426 | tokenType = Token.PINYIN;
427 | } else {
428 | if (tokenType != t.type && sb.length() > 0) {
429 | addToken(sb, tokens, tokenType);
430 | }
431 | tokenType = t.type;
432 | sb.append(character);
433 | }
434 | }
435 | }
436 | if (sb.length() > 0) {
437 | addToken(sb, tokens, tokenType);
438 | }
439 | return tokens;
440 | }
441 |
442 | private void addToken(
443 | final StringBuilder sb, final ArrayList tokens, final int tokenType) {
444 | String str = sb.toString();
445 | tokens.add(new Token(tokenType, str, str));
446 | sb.setLength(0);
447 | }
448 |
449 |
450 | //The fillowing lines are provided and maintained by Mediatek inc.
451 | private class DialerSearchToken extends Token {
452 | static final int FIRSTCASE = 0;
453 | static final int UPPERCASE = 1;
454 | static final int LOWERCASE = 2;
455 | }
456 |
457 | public String getTokensForDialerSearch(final String input, StringBuilder offsets){
458 |
459 | if(offsets == null || input == null || TextUtils.isEmpty(input)){
460 | // return empty tokens
461 | return null;
462 | }
463 |
464 | StringBuilder subStrSet = new StringBuilder();
465 | ArrayList tokens = new ArrayList();
466 | ArrayList shortSubStrOffset = new ArrayList();
467 | final int inputLength = input.length();
468 | final StringBuilder subString = new StringBuilder();
469 | final StringBuilder subStrOffset = new StringBuilder();
470 | int tokenType = Token.LATIN;
471 | int caseTypePre = DialerSearchToken.FIRSTCASE;
472 | int caseTypeCurr = DialerSearchToken.UPPERCASE;
473 | int mPos = 0;
474 |
475 | // Go through the input, create a new token when
476 | // a. Token type changed
477 | // b. Get the Pinyin of current charater.
478 | // c. current character is space.
479 | // d. Token case changed from lower case to upper case,
480 | // e. the first character is always a separated one
481 | // f character == '+' || character == '#' || character == '*' || character == ',' || character == ';'
482 | for (int i = 0; i < inputLength; i++) {
483 | final char character = input.charAt(i);
484 | if (character == '-' || character == ',' ){
485 | mPos++;
486 | } else if (character == ' ') {
487 | if (subString.length() > 0) {
488 | addToken(subString, tokens, tokenType);
489 | addOffsets(subStrOffset, shortSubStrOffset);
490 | }
491 | addSubString(tokens,shortSubStrOffset,subStrSet,offsets);
492 | mPos++;
493 | caseTypePre = DialerSearchToken.FIRSTCASE;
494 | } else if (character < 256) {
495 | if (tokenType != Token.LATIN && subString.length() > 0) {
496 | addToken(subString, tokens, tokenType);
497 | addOffsets(subStrOffset, shortSubStrOffset);
498 | }
499 | caseTypeCurr = (character>='A' && character<='Z')?DialerSearchToken.UPPERCASE:DialerSearchToken.LOWERCASE;
500 | if(caseTypePre == DialerSearchToken.LOWERCASE && caseTypeCurr == DialerSearchToken.UPPERCASE){
501 | addToken(subString, tokens, tokenType);
502 | addOffsets(subStrOffset, shortSubStrOffset);
503 | }
504 | caseTypePre = caseTypeCurr;
505 | tokenType = Token.LATIN;
506 | Character c = Character.toUpperCase(character);
507 | if(c != null){
508 | subString.append(c);
509 | subStrOffset.append((char)mPos);
510 | }
511 | mPos++;
512 | } else if (character < FIRST_UNIHAN) {
513 | //Comment out. Do not cover unknown characters SINCE they can not be input.
514 | // if (tokenType != Token.UNKNOWN && subString.length() > 0) {
515 | // addToken(subString, tokens, tokenType);
516 | // addOffsets(subStrOffset, shortSubStrOffset);
517 | // caseTypePre = Token.FIRSTCASE;
518 | // }
519 | // tokenType = Token.UNKNOWN;
520 | // Character c = Character.toUpperCase(character);
521 | // if(c != null){
522 | // subString.append(c);
523 | // subStrOffset.append((char)(mPos));
524 | // }
525 | mPos++;
526 | } else {
527 | Token t = getToken(character);
528 | int tokenSize = t.target.length();
529 | //Current type is PINYIN
530 | if (t.type == Token.PINYIN) {
531 | if (subString.length() > 0) {
532 | addToken(subString, tokens, tokenType);
533 | addOffsets(subStrOffset, shortSubStrOffset);
534 | }
535 | tokens.add(t);
536 | for(int j=0; j < tokenSize;j++)
537 | subStrOffset.append((char)mPos);
538 | addOffsets(subStrOffset,shortSubStrOffset);
539 | tokenType = Token.PINYIN;
540 | caseTypePre = DialerSearchToken.FIRSTCASE;
541 | mPos++;
542 | } else {
543 | //Comment out. Do not cover special characters SINCE they can not be input.
544 | // if (tokenType != t.type && subString.length() > 0) {
545 | // addToken(subString, tokens, tokenType);
546 | // addOffsets(subStrOffset, shortSubStrOffset);
547 | // caseTypePre = Token.FIRSTCASE;
548 | // }else{
549 | // caseTypeCurr = (character>='A' && character<='Z')?Token.UPPERCASE:Token.LOWERCASE;
550 | // if(caseTypePre == Token.LOWERCASE && caseTypeCurr == Token.UPPERCASE){
551 | // addToken(subString, tokens, tokenType);
552 | // addOffsets(subStrOffset, shortSubStrOffset);
553 | // }
554 | // caseTypePre = caseTypeCurr;
555 | // }
556 | // tokenType = t.type;
557 | // Character c = Character.toUpperCase(character);
558 | // if(c != null){
559 | // subString.append(c);
560 | // subStrOffset.append(mPos);
561 | // }
562 | mPos++;
563 | }
564 | }
565 | //IF the name string is too long, cut it off to meet the storage request of dialer search.
566 | if(mPos > 127)
567 | break;
568 | }
569 | if (subString.length() > 0) {
570 | addToken(subString, tokens, tokenType);
571 | addOffsets(subStrOffset, shortSubStrOffset);
572 | }
573 | addSubString(tokens,shortSubStrOffset,subStrSet,offsets);
574 | return subStrSet.toString();
575 | }
576 |
577 | private void addOffsets(final StringBuilder sb, final ArrayList shortSubStrOffset){
578 | String str = sb.toString();
579 | shortSubStrOffset.add(str);
580 | sb.setLength(0);
581 | }
582 |
583 | private void addSubString(final ArrayList tokens, final ArrayList shortSubStrOffset,
584 | StringBuilder subStrSet, StringBuilder offsets){
585 | if(tokens == null || tokens.isEmpty())
586 | return;
587 |
588 | int size = tokens.size();
589 | int len = 0;
590 | StringBuilder mShortSubStr = new StringBuilder();
591 | StringBuilder mShortSubStrOffsets = new StringBuilder();
592 | StringBuilder mShortSubStrSet = new StringBuilder();
593 | StringBuilder mShortSubStrOffsetsSet = new StringBuilder();
594 |
595 | for(int i=size-1; i>=0 ; i--){
596 | String mTempStr = tokens.get(i).target;
597 | len += mTempStr.length();
598 | String mTempOffset = shortSubStrOffset.get(i);
599 | if(mShortSubStr.length()>0){
600 | mShortSubStr.deleteCharAt(0);
601 | mShortSubStrOffsets.deleteCharAt(0);
602 | }
603 | mShortSubStr.insert(0, mTempStr);
604 | mShortSubStr.insert(0,(char)len);
605 | mShortSubStrOffsets.insert(0,mTempOffset);
606 | mShortSubStrOffsets.insert(0,(char)len);
607 | mShortSubStrSet.insert(0,mShortSubStr);
608 | mShortSubStrOffsetsSet.insert(0, mShortSubStrOffsets);
609 | }
610 |
611 | subStrSet.append(mShortSubStrSet);
612 | offsets.append(mShortSubStrOffsetsSet);
613 | tokens.clear();
614 | shortSubStrOffset.clear();
615 | }
616 | //The previous lines are provided and maintained by Mediatek inc.
617 | }
618 |
--------------------------------------------------------------------------------
/src/com/koalcat/blurdemo/IndexCursor.java:
--------------------------------------------------------------------------------
1 | package com.koalcat.blurdemo;
2 | /**
3 | * @author xuchdeid@gmail.com
4 | * __________________________ \_/
5 | | | /._.\
6 | | Android!Android! > U| |U
7 | | xuchdeid | |___|
8 | |__________________________| U U
9 | * */
10 | import android.content.ContentResolver;
11 | import android.database.CharArrayBuffer;
12 | import android.database.ContentObserver;
13 | import android.database.Cursor;
14 | import android.database.DataSetObserver;
15 | import android.net.Uri;
16 | import android.os.Bundle;
17 | import android.widget.ArrayAdapter;
18 |
19 | public class IndexCursor implements Cursor {
20 |
21 | private ArrayAdapter adapter;
22 | private int position;
23 |
24 | public IndexCursor(ArrayAdapter adapter){
25 | this.adapter = adapter;
26 | }
27 |
28 | @Override
29 | public int getCount() {
30 | return adapter.getCount();
31 | }
32 |
33 | @Override
34 | public String getString(int columnIndex) {
35 | AppInfo app = adapter.getItem(position);
36 | if (app.title_py.length() == 0) {
37 | return app.title.substring(0, 1);
38 | } else {
39 | return app.title_py.substring(0, 1);
40 | }
41 | }
42 |
43 | @Override
44 | public boolean moveToPosition(int position) {
45 | if(position < -1 || position > getCount()){
46 | return false;
47 | }
48 |
49 | this.position = position;
50 | return true;
51 | }
52 |
53 | @Override
54 | public void close() {}
55 | @Override
56 | public void copyStringToBuffer(int arg0, CharArrayBuffer arg1) {}
57 | @Override
58 | public void deactivate() {}
59 | @Override
60 | public byte[] getBlob(int arg0) {return null;}
61 | @Override
62 | public int getColumnCount() {return 0;}
63 | @Override
64 | public int getColumnIndex(String columnName) {return 0;}
65 | @Override
66 | public int getColumnIndexOrThrow(String columnName) throws IllegalArgumentException {return 0;}
67 | @Override
68 | public String getColumnName(int columnIndex) {return null;}
69 | @Override
70 | public String[] getColumnNames() {return null;}
71 | @Override
72 | public double getDouble(int columnIndex) {return 0;}
73 | @Override
74 | public Bundle getExtras() {return null;}
75 | @Override
76 | public float getFloat(int columnIndex) {return 0;}
77 | @Override
78 | public int getInt(int columnIndex) {return 0;}
79 | @Override
80 | public long getLong(int columnIndex) {return 0;}
81 | @Override
82 | public int getPosition() {return position;}
83 | @Override
84 | public short getShort(int columnIndex) {return 0;}
85 | @Override
86 | public boolean getWantsAllOnMoveCalls() {return false;}
87 | @Override
88 | public boolean isAfterLast() {return false;}
89 | @Override
90 | public boolean isBeforeFirst() {return false;}
91 | @Override
92 | public boolean isClosed() {return false;}
93 | @Override
94 | public boolean isFirst() {return false;}
95 | @Override
96 | public boolean isLast() {return false;}
97 | @Override
98 | public boolean isNull(int columnIndex) {return false;}
99 | @Override
100 | public boolean move(int offset) {return false;}
101 | @Override
102 | public boolean moveToFirst() {return false;}
103 | @Override
104 | public boolean moveToLast() {return false;}
105 | @Override
106 | public boolean moveToNext() {return false;}
107 | @Override
108 | public boolean moveToPrevious() {return false;}
109 | @Override
110 | public void registerContentObserver(ContentObserver observer) {}
111 | @Override
112 | public void registerDataSetObserver(DataSetObserver observer) {}
113 | @Override
114 | public boolean requery() {return false;}
115 | @Override
116 | public Bundle respond(Bundle extras) {return null;}
117 | @Override
118 | public void setNotificationUri(ContentResolver cr, Uri uri) {}
119 | @Override
120 | public void unregisterContentObserver(ContentObserver observer) {}
121 | @Override
122 | public void unregisterDataSetObserver(DataSetObserver observer) {}
123 |
124 | @Override
125 | public int getType(int columnIndex) {
126 | // TODO Auto-generated method stub
127 | return 0;
128 | }
129 |
130 | public Uri getNotificationUri() {
131 | // TODO Auto-generated method stub
132 | return null;
133 | }
134 | }
135 |
136 |
--------------------------------------------------------------------------------
/src/com/koalcat/blurdemo/Utilities.java:
--------------------------------------------------------------------------------
1 | package com.koalcat.blurdemo;
2 |
3 | import java.io.File;
4 | import java.io.FileDescriptor;
5 | import java.io.FileNotFoundException;
6 | import java.io.FileOutputStream;
7 | import java.lang.reflect.Method;
8 |
9 | import android.graphics.drawable.BitmapDrawable;
10 | import android.graphics.drawable.Drawable;
11 | import android.graphics.drawable.PaintDrawable;
12 | import android.graphics.drawable.StateListDrawable;
13 | import android.graphics.Bitmap;
14 | import android.graphics.BitmapFactory;
15 | import android.graphics.Color;
16 | import android.graphics.PixelFormat;
17 | import android.graphics.Canvas;
18 | import android.graphics.PaintFlagsDrawFilter;
19 | import android.graphics.Paint;
20 | import android.graphics.Point;
21 | import android.graphics.Rect;
22 | import android.net.Uri;
23 | import android.os.Environment;
24 | import android.os.ParcelFileDescriptor;
25 | import android.provider.MediaStore;
26 | import android.provider.Settings;
27 | import android.provider.Settings.SettingNotFoundException;
28 | import android.util.DisplayMetrics;
29 | //import android.util.Log;
30 | import android.util.StateSet;
31 | import android.view.Display;
32 | import android.view.View;
33 | import android.view.WindowManager;
34 | import android.app.Activity;
35 | import android.content.res.Resources;
36 | import android.content.ContentResolver;
37 | import android.content.ContentUris;
38 | import android.content.Context;
39 | import android.database.Cursor;
40 |
41 | public class Utilities {
42 | private static int sIconWidth = -1;
43 | private static int sIconHeight = -1;
44 |
45 | private static final Paint sPaint = new Paint();
46 | private static final Rect sBounds = new Rect();
47 | private static final Rect sOldBounds = new Rect();
48 | private static Canvas sCanvas = new Canvas();
49 |
50 | static {
51 | sCanvas.setDrawFilter(new PaintFlagsDrawFilter(Paint.DITHER_FLAG,
52 | Paint.FILTER_BITMAP_FLAG));
53 | }
54 |
55 | /**
56 | * Returns a Drawable representing the thumbnail of the specified Drawable.
57 | * The size of the thumbnail is defined by the dimension
58 | * android.R.dimen.launcher_application_icon_size.
59 | *
60 | * This method is not thread-safe and should be invoked on the UI thread only.
61 | *
62 | * @param icon The icon to get a thumbnail of.
63 | * @param context The application's context.
64 | *
65 | * @return A thumbnail for the specified icon or the icon itself if the
66 | * thumbnail could not be created.
67 | */
68 | public static Drawable createIconThumbnail(Drawable icon, Context context) {
69 | if (sIconWidth == -1) {
70 | final Resources resources = context.getResources();
71 | sIconWidth = sIconHeight = (int) resources.getDimension(android.R.dimen.app_icon_size);
72 | }
73 |
74 | int width = sIconWidth;
75 | int height = sIconHeight;
76 |
77 | float scale = 1.0f;
78 | if (icon instanceof PaintDrawable) {
79 | PaintDrawable painter = (PaintDrawable) icon;
80 | painter.setIntrinsicWidth(width);
81 | painter.setIntrinsicHeight(height);
82 | } else if (icon instanceof BitmapDrawable) {
83 | // Ensure the bitmap has a density.
84 | BitmapDrawable bitmapDrawable = (BitmapDrawable) icon;
85 | Bitmap bitmap = bitmapDrawable.getBitmap();
86 | if (bitmap.getDensity() == Bitmap.DENSITY_NONE) {
87 | bitmapDrawable.setTargetDensity(context.getResources().getDisplayMetrics());
88 | }
89 | }
90 | int iconWidth = icon.getIntrinsicWidth();
91 | int iconHeight = icon.getIntrinsicHeight();
92 |
93 | if (width > 0 && height > 0) {
94 | if (width < iconWidth || height < iconHeight || scale != 1.0f) {
95 | final float ratio = (float) iconWidth / iconHeight;
96 |
97 | if (iconWidth > iconHeight) {
98 | height = (int) (width / ratio);
99 | } else if (iconHeight > iconWidth) {
100 | width = (int) (height * ratio);
101 | }
102 |
103 | final Bitmap.Config c = icon.getOpacity() != PixelFormat.OPAQUE ?
104 | Bitmap.Config.ARGB_8888 : Bitmap.Config.RGB_565;
105 | final Bitmap thumb = Bitmap.createBitmap(sIconWidth, sIconHeight, c);
106 | final Canvas canvas = sCanvas;
107 | canvas.setBitmap(thumb);
108 | // Copy the old bounds to restore them later
109 | // If we were to do oldBounds = icon.getBounds(),
110 | // the call to setBounds() that follows would
111 | // change the same instance and we would lose the
112 | // old bounds
113 | sOldBounds.set(icon.getBounds());
114 | final int x = (sIconWidth - width) / 2;
115 | final int y = (sIconHeight - height) / 2;
116 | icon.setBounds(x, y, x + width, y + height);
117 | icon.draw(canvas);
118 | icon.setBounds(sOldBounds);
119 | icon = new FastBitmapDrawable(thumb);
120 | } else if (iconWidth < width && iconHeight < height) {
121 | final Bitmap.Config c = Bitmap.Config.ARGB_8888;
122 | final Bitmap thumb = Bitmap.createBitmap(sIconWidth, sIconHeight, c);
123 | final Canvas canvas = sCanvas;
124 | canvas.setBitmap(thumb);
125 | sOldBounds.set(icon.getBounds());
126 | final int x = (width - iconWidth) / 2;
127 | final int y = (height - iconHeight) / 2;
128 | icon.setBounds(x, y, x + iconWidth, y + iconHeight);
129 | icon.draw(canvas);
130 | icon.setBounds(sOldBounds);
131 | icon = new FastBitmapDrawable(thumb);
132 | }
133 | }
134 |
135 | /*StateListDrawable mDrawable = new StateListDrawable();
136 | Bitmap mBitmap = Bitmap.createBitmap(icon.getIntrinsicWidth(), icon.getIntrinsicHeight(), Bitmap.Config.ARGB_8888);
137 | icon.setAlpha(0x99);
138 | Canvas canvas = new Canvas(mBitmap);
139 | icon.setBounds(new Rect(0, 0, mBitmap.getWidth(), mBitmap.getHeight()));
140 | icon.draw(canvas);
141 | mDrawable.addState(new int[] { android.R.attr.state_pressed }, new BitmapDrawable(context.getResources(), mBitmap));
142 |
143 | icon.setAlpha(0xff);
144 | mDrawable.addState(StateSet.WILD_CARD, icon);
145 | return mDrawable;*/
146 | return icon;
147 | }
148 |
149 | public static Bitmap createIcontoBitmapThumbnail(Drawable icon, Context context) {
150 | if (sIconWidth == -1) {
151 | final Resources resources = context.getResources();
152 | sIconWidth = sIconHeight = (int) resources.getDimension(android.R.dimen.app_icon_size);
153 | }
154 |
155 | int width = sIconWidth;
156 | int height = sIconHeight;
157 |
158 | float scale = 1.0f;
159 | if (icon instanceof PaintDrawable) {
160 | PaintDrawable painter = (PaintDrawable) icon;
161 | painter.setIntrinsicWidth(width);
162 | painter.setIntrinsicHeight(height);
163 | } else if (icon instanceof BitmapDrawable) {
164 | // Ensure the bitmap has a density.
165 | BitmapDrawable bitmapDrawable = (BitmapDrawable) icon;
166 | Bitmap bitmap = bitmapDrawable.getBitmap();
167 | if (bitmap.getDensity() == Bitmap.DENSITY_NONE) {
168 | bitmapDrawable.setTargetDensity(context.getResources().getDisplayMetrics());
169 | }
170 | }
171 | int iconWidth = icon.getIntrinsicWidth();
172 | int iconHeight = icon.getIntrinsicHeight();
173 |
174 | if (width > 0 && height > 0) {
175 | if (width < iconWidth || height < iconHeight || scale != 1.0f) {
176 | final float ratio = (float) iconWidth / iconHeight;
177 |
178 | if (iconWidth > iconHeight) {
179 | height = (int) (width / ratio);
180 | } else if (iconHeight > iconWidth) {
181 | width = (int) (height * ratio);
182 | }
183 |
184 | final Bitmap.Config c = icon.getOpacity() != PixelFormat.OPAQUE ?
185 | Bitmap.Config.ARGB_8888 : Bitmap.Config.RGB_565;
186 | final Bitmap thumb = Bitmap.createBitmap(sIconWidth, sIconHeight, c);
187 | final Canvas canvas = sCanvas;
188 | canvas.setBitmap(thumb);
189 | // Copy the old bounds to restore them later
190 | // If we were to do oldBounds = icon.getBounds(),
191 | // the call to setBounds() that follows would
192 | // change the same instance and we would lose the
193 | // old bounds
194 | sOldBounds.set(icon.getBounds());
195 | final int x = (sIconWidth - width) / 2;
196 | final int y = (sIconHeight - height) / 2;
197 | icon.setBounds(x, y, x + width, y + height);
198 | icon.draw(canvas);
199 | icon.setBounds(sOldBounds);
200 | icon = new FastBitmapDrawable(thumb);
201 | } else if (iconWidth < width && iconHeight < height) {
202 | final Bitmap.Config c = Bitmap.Config.ARGB_8888;
203 | final Bitmap thumb = Bitmap.createBitmap(sIconWidth, sIconHeight, c);
204 | final Canvas canvas = sCanvas;
205 | canvas.setBitmap(thumb);
206 | sOldBounds.set(icon.getBounds());
207 | final int x = (width - iconWidth) / 2;
208 | final int y = (height - iconHeight) / 2;
209 | icon.setBounds(x, y, x + iconWidth, y + iconHeight);
210 | icon.draw(canvas);
211 | icon.setBounds(sOldBounds);
212 | icon = new FastBitmapDrawable(thumb);
213 | }
214 | }
215 | Bitmap mBitmap = Bitmap.createBitmap(icon.getIntrinsicWidth(), icon.getIntrinsicHeight(), Bitmap.Config.ARGB_8888);
216 | icon.setAlpha(0xff);
217 | Canvas canvas = new Canvas(mBitmap);
218 | icon.setBounds(new Rect(0, 0, mBitmap.getWidth(), mBitmap.getHeight()));
219 | icon.draw(canvas);
220 |
221 | return mBitmap;
222 | }
223 | /**
224 | * Returns a Bitmap representing the thumbnail of the specified Bitmap.
225 | * The size of the thumbnail is defined by the dimension
226 | * android.R.dimen.launcher_application_icon_size.
227 | *
228 | * This method is not thread-safe and should be invoked on the UI thread only.
229 | *
230 | * @param bitmap The bitmap to get a thumbnail of.
231 | * @param context The application's context.
232 | *
233 | * @return A thumbnail for the specified bitmap or the bitmap itself if the
234 | * thumbnail could not be created.
235 | */
236 | public static Bitmap createBitmapThumbnail(Bitmap bitmap, Context context) {
237 |
238 | if (bitmap == null) {
239 | return null;
240 | }
241 |
242 | if (sIconWidth == -1) {
243 | final Resources resources = context.getResources();
244 | sIconWidth = sIconHeight = (int) resources.getDimension(
245 | android.R.dimen.app_icon_size);
246 | }
247 |
248 | int width = sIconWidth;
249 | int height = sIconHeight;
250 |
251 | final int bitmapWidth = bitmap.getWidth();
252 | final int bitmapHeight = bitmap.getHeight();
253 |
254 | if (width > 0 && height > 0 && (width < bitmapWidth || height < bitmapHeight)) {
255 | final float ratio = (float) bitmapWidth / bitmapHeight;
256 |
257 | if (bitmapWidth > bitmapHeight) {
258 | height = (int) (width / ratio);
259 | } else if (bitmapHeight > bitmapWidth) {
260 | width = (int) (height * ratio);
261 | }
262 |
263 | final Bitmap.Config c = (width == sIconWidth && height == sIconHeight) ?
264 | bitmap.getConfig() : Bitmap.Config.ARGB_8888;
265 | final Bitmap thumb = Bitmap.createBitmap(sIconWidth, sIconHeight, c);
266 | final Canvas canvas = sCanvas;
267 | final Paint paint = sPaint;
268 | canvas.setBitmap(thumb);
269 | paint.setDither(false);
270 | paint.setFilterBitmap(true);
271 | sBounds.set((sIconWidth - width) / 2, (sIconHeight - height) / 2, width, height);
272 | sOldBounds.set(0, 0, bitmapWidth, bitmapHeight);
273 | canvas.drawBitmap(bitmap, sOldBounds, sBounds, paint);
274 | return thumb;
275 | }
276 |
277 | return bitmap;
278 | }
279 |
280 | @SuppressWarnings("deprecation")
281 | public static StateListDrawable CreateAddDrawable(Context context) {
282 | DisplayMetrics dm = context.getResources().getDisplayMetrics();
283 | float dip = ((float)dm.densityDpi / 160.0f);
284 | int dock_height = (int) (context.getResources().getDimension(android.R.dimen.app_icon_size) * dip);
285 | StateListDrawable mDrawable = new StateListDrawable();
286 |
287 | Bitmap mBitmap = Bitmap.createBitmap((int)dock_height, (int)dock_height, Bitmap.Config.ARGB_8888);
288 | Canvas canvas = new Canvas(mBitmap);
289 | Drawable d = context.getResources().getDrawable(R.drawable.bg_squ_click);
290 | d.setBounds(new Rect(0, 0, mBitmap.getWidth(), mBitmap.getHeight()));
291 | d.draw(canvas);
292 | mDrawable.addState(new int[] { android.R.attr.state_pressed }, new BitmapDrawable(mBitmap));
293 |
294 | mBitmap = Bitmap.createBitmap((int)dock_height, (int)dock_height, Bitmap.Config.ARGB_8888);
295 | canvas = new Canvas(mBitmap);
296 | d = context.getResources().getDrawable(R.drawable.bg_squ_normal);
297 | d.setBounds(new Rect(0, 0, mBitmap.getWidth(), mBitmap.getHeight()));
298 | d.draw(canvas);
299 | Paint paint = new Paint();
300 | paint.setColor(Color.WHITE);
301 | //paint.setStyle(Paint.Style.STROKE);
302 | paint.setStrokeWidth(4 * dip);
303 | float startX = mBitmap.getWidth() / 4;
304 | float startY = mBitmap.getHeight() / 4;
305 | float stopX = startX * 3;
306 | float stopY = startY * 3;
307 | canvas.drawLine(startX , startY * 2, stopX, startY * 2, paint);
308 | canvas.drawLine(startX * 2 , startY, startX * 2, stopY, paint);
309 | mDrawable.addState(StateSet.WILD_CARD, new BitmapDrawable(mBitmap));
310 |
311 | return mDrawable;
312 | }
313 |
314 | @SuppressWarnings("deprecation")
315 | public static StateListDrawable CreateSettingAddDrawable(Context context) {
316 | DisplayMetrics dm = context.getResources().getDisplayMetrics();
317 | float dip = ((float)dm.densityDpi / 160.0f);
318 | int dock_height = (int) (context.getResources().getDimension(android.R.dimen.app_icon_size) * dip);
319 | StateListDrawable mDrawable = new StateListDrawable();
320 |
321 | Bitmap mBitmap = Bitmap.createBitmap((int)dock_height, (int)dock_height, Bitmap.Config.ARGB_8888);
322 | Canvas canvas = new Canvas(mBitmap);
323 | Drawable d = context.getResources().getDrawable(R.drawable.bg_squ_click_black);
324 | d.setBounds(new Rect(0, 0, mBitmap.getWidth(), mBitmap.getHeight()));
325 | d.draw(canvas);
326 | mDrawable.addState(new int[] { android.R.attr.state_pressed }, new BitmapDrawable(mBitmap));
327 |
328 | mBitmap = Bitmap.createBitmap((int)dock_height, (int)dock_height, Bitmap.Config.ARGB_8888);
329 | canvas = new Canvas(mBitmap);
330 | d = context.getResources().getDrawable(R.drawable.bg_squ_normal_black);
331 | d.setBounds(new Rect(0, 0, mBitmap.getWidth(), mBitmap.getHeight()));
332 | d.draw(canvas);
333 | Paint paint = new Paint();
334 | paint.setColor(Color.BLACK);
335 | //paint.setStyle(Paint.Style.STROKE);
336 | paint.setStrokeWidth(4 * dip);
337 | float startX = mBitmap.getWidth() / 4;
338 | float startY = mBitmap.getHeight() / 4;
339 | float stopX = startX * 3;
340 | float stopY = startY * 3;
341 | canvas.drawLine(startX , startY * 2, stopX, startY * 2, paint);
342 | canvas.drawLine(startX * 2 , startY, startX * 2, stopY, paint);
343 | mDrawable.addState(StateSet.WILD_CARD, new BitmapDrawable(mBitmap));
344 |
345 | return mDrawable;
346 | }
347 |
348 | public static boolean isAutoBrightness(ContentResolver aContentResolver) {
349 | boolean automicBrightness = false;
350 | try {
351 | automicBrightness = Settings.System.getInt(aContentResolver,
352 | Settings.System.SCREEN_BRIGHTNESS_MODE) == Settings.System.SCREEN_BRIGHTNESS_MODE_AUTOMATIC;
353 | } catch (SettingNotFoundException e) {
354 | e.printStackTrace();
355 | }
356 | return automicBrightness;
357 | }
358 |
359 | public static int getScreenBrightness(Activity activity) {
360 | int nowBrightnessValue = 255 / 2;
361 | ContentResolver resolver = activity.getContentResolver();
362 | try {
363 | nowBrightnessValue = android.provider.Settings.System.getInt(
364 | resolver, Settings.System.SCREEN_BRIGHTNESS);
365 | } catch (Exception e) {
366 | e.printStackTrace();
367 | }
368 | return nowBrightnessValue;
369 | }
370 |
371 | public static void setBrightness(Activity activity, int brightness) {
372 | if (brightness < 10) {
373 | brightness = 10;
374 | }
375 | WindowManager.LayoutParams lp = activity.getWindow().getAttributes();
376 | lp.screenBrightness = Float.valueOf(brightness) * (1f / 255f);
377 | activity.getWindow().setAttributes(lp);
378 | }
379 |
380 | public static void saveBrightness(ContentResolver resolver, int brightness) {
381 | Uri uri = android.provider.Settings.System
382 | .getUriFor("screen_brightness");
383 | android.provider.Settings.System.putInt(resolver, "screen_brightness",
384 | brightness);
385 | resolver.notifyChange(uri, null);
386 | }
387 |
388 | public static void startAutoBrightness(Activity activity) {
389 | Uri uri = android.provider.Settings.System
390 | .getUriFor("screen_brightness");
391 | Settings.System.putInt(activity.getContentResolver(),
392 | Settings.System.SCREEN_BRIGHTNESS_MODE,
393 | Settings.System.SCREEN_BRIGHTNESS_MODE_AUTOMATIC);
394 | activity.getContentResolver().notifyChange(uri, null);
395 | }
396 |
397 | public static void stopAutoBrightness(Activity activity) {
398 | Uri uri = android.provider.Settings.System
399 | .getUriFor("screen_brightness");
400 | Settings.System.putInt(activity.getContentResolver(),
401 | Settings.System.SCREEN_BRIGHTNESS_MODE,
402 | Settings.System.SCREEN_BRIGHTNESS_MODE_MANUAL);
403 | activity.getContentResolver().notifyChange(uri, null);
404 | }
405 |
406 | private static final Uri sArtworkUri = Uri.parse("content://media/external/audio/albumart");
407 | private static final BitmapFactory.Options sBitmapOptions = new BitmapFactory.Options();
408 |
409 | private static Bitmap getArtworkFromFile(Context context, long songid, long albumid) {
410 |
411 | Bitmap bm = null;
412 | //Log.d("xuchdeid", "getArtworkFromFile songid:" + songid + " albumid:" + albumid);
413 | if (albumid < 0 && songid < 0) {
414 | throw new IllegalArgumentException("Must specify an album or a song id");
415 | }
416 |
417 | try {
418 | if (albumid < 0) {
419 | Uri uri = Uri.parse("content://media/external/audio/media/" + songid + "/albumart");
420 | ParcelFileDescriptor pfd = context.getContentResolver().openFileDescriptor(uri, "r");
421 |
422 | if (pfd != null) {
423 | FileDescriptor fd = pfd.getFileDescriptor();
424 | bm = BitmapFactory.decodeFileDescriptor(fd);
425 | }
426 | } else {
427 | Uri uri = ContentUris.withAppendedId(sArtworkUri, albumid);
428 | ParcelFileDescriptor pfd = context.getContentResolver().openFileDescriptor(uri, "r");
429 | if (pfd != null) {
430 | FileDescriptor fd = pfd.getFileDescriptor();
431 | bm = BitmapFactory.decodeFileDescriptor(fd);
432 | }
433 | }
434 | } catch (IllegalStateException ex) {
435 | } catch (FileNotFoundException ex) {
436 | }
437 | if (bm != null) {
438 |
439 | }
440 |
441 | return bm;
442 | }
443 |
444 | public static long getAlbumIdbySong(Context context, String artist, String album) {
445 | long albumid = -1;
446 | String[] projection = new String[] {
447 | MediaStore.Audio.Media._ID,
448 | MediaStore.Audio.Media.ALBUM_ID,
449 | MediaStore.Audio.Media.ARTIST,
450 | MediaStore.Audio.Media.ALBUM};
451 |
452 | String selection = MediaStore.Audio.Media.ARTIST + " = ? AND " +
453 | MediaStore.Audio.Media.ALBUM + " = ?";
454 | String[] args = new String[]{artist, album};
455 | Cursor cursor;
456 | try {
457 | cursor = context.getContentResolver().query(
458 | MediaStore.Audio.Media.EXTERNAL_CONTENT_URI,
459 | projection, selection, args, null);
460 | } catch (Exception e) {
461 | return albumid;
462 | }
463 | if (cursor != null && cursor.getCount() > 0) {
464 | //Log.d("xuchdeid", "cursor != null");
465 | if (cursor.moveToFirst()) {
466 | albumid = cursor.getLong(cursor.getColumnIndex(MediaStore.Audio.Media.ALBUM_ID));
467 | //Log.d("xuchdeid", "artist:" + cursor.getString(cursor.getColumnIndex(MediaStore.Audio.Media.ARTIST)));
468 | //Log.d("xuchdeid", "ALBUM:" + cursor.getString(cursor.getColumnIndex(MediaStore.Audio.Media.ALBUM)));
469 | //Log.d("xuchdeid", "albumid " + albumid);
470 | }
471 | cursor.close();
472 | }
473 | //Log.d("xuchdeid", "getAlbumIdbySongId:" + albumid);
474 | return albumid;
475 | }
476 |
477 | public static Point getDpi(Activity context) {
478 | Point point = new Point(0, 0);
479 | Display display = context.getWindowManager().getDefaultDisplay();
480 | DisplayMetrics dm = new DisplayMetrics();
481 | Class> c;
482 | try {
483 | c = Class.forName("android.view.Display");
484 | Method method = c.getMethod("getRealMetrics", DisplayMetrics.class);
485 | method.invoke(display, dm);
486 |
487 | point.x = dm.widthPixels;
488 | point.y = dm.heightPixels;
489 | }catch(Exception e){
490 | e.printStackTrace();
491 | }
492 | return point;
493 | }
494 |
495 | public static Bitmap screenshot(int width, int height) {
496 | Class> c;
497 | Bitmap picture = null;
498 | try {
499 | c = Class.forName("android.view.Surface");
500 | Method method = c.getMethod("screenshot", new Class[] {int.class, int.class});
501 | picture = (Bitmap) method.invoke(c, new Object[] {width, height});
502 | }catch(Exception e){
503 | e.printStackTrace();
504 | }
505 | return picture;
506 | }
507 |
508 | public static Bitmap takeScreenShot(Activity activity){
509 | View view = activity.getWindow().getDecorView();
510 | view.setDrawingCacheEnabled(true);
511 | view.buildDrawingCache();
512 | Bitmap bitmap = Bitmap.createBitmap(view.getDrawingCache());
513 | view.setDrawingCacheEnabled(false);
514 | return bitmap;
515 | }
516 |
517 | public static void SaveScreen(Activity activity) {
518 | Bitmap bitmap;
519 | /*View v1 = activity.findViewById(android.R.id.content);
520 | v1.setDrawingCacheEnabled(true);
521 | bitmap = Bitmap.createBitmap(v1.getDrawingCache());
522 | v1.setDrawingCacheEnabled(false);*/
523 |
524 | bitmap = takeScreenShot(activity);
525 | //bitmap = screenshot(100, 100);
526 |
527 | File path = Environment.getExternalStorageDirectory();
528 | File file = new File(path, "Dump.png");
529 |
530 | FileOutputStream outputStream;
531 |
532 | try {
533 | outputStream = new FileOutputStream(file);
534 | bitmap.compress(Bitmap.CompressFormat.PNG, 100, outputStream);
535 | outputStream.flush();
536 | outputStream.close();
537 | } catch (Exception e) {
538 | e.printStackTrace();
539 | }
540 | }
541 | }
542 |
543 |
--------------------------------------------------------------------------------
/src/com/koalcat/view/BaseRender.java:
--------------------------------------------------------------------------------
1 | package com.koalcat.view;
2 |
3 | import android.graphics.Bitmap;
4 |
5 | public interface BaseRender {
6 | public abstract void blur(float radius, Bitmap in, Bitmap out);
7 | public abstract void destroy() ;
8 | }
9 |
--------------------------------------------------------------------------------
/src/com/koalcat/view/Blur.java:
--------------------------------------------------------------------------------
1 | package com.koalcat.view;
2 | /**
3 | * @author xuchdeid@gmail.com
4 | * __________________________ \_/
5 | | | /._.\
6 | | Android!Android! > U| |U
7 | | xuchdeid | |___|
8 | |__________________________| U U
9 | * */
10 |
11 | import android.content.Context;
12 | import android.graphics.Bitmap;
13 | import android.os.Build;
14 | //import android.os.Build;
15 | import android.support.v4.util.LruCache;
16 |
17 | public class Blur {
18 |
19 | private static final String TAG = "Blur";
20 |
21 | private boolean USE_JNI = true;
22 |
23 | private static final float BITMAP_SCALE_NOMAL = 0.8f;
24 | private static final float BLUR_RADIUS_NOMAL = 12.0f;
25 |
26 | private static final float BITMAP_SCALE_FAST = 0.5f;
27 | private static final float BLUR_RADIUS_FAST = 10.0f;
28 |
29 | private BaseRender mRender;
30 |
31 | private LruCache mMemoryCache;
32 |
33 | public Blur(Context context) {
34 |
35 | if (!USE_JNI) {
36 | int sdk = Build.VERSION.SDK_INT;
37 | if (sdk < 17) {
38 | USE_JNI = true;
39 | }
40 | }
41 |
42 | if (!USE_JNI) {
43 | mRender = new ScriptIntrinsicBlurRender(context);
44 | //mRender = new BlurRSRender(context);
45 | } else {
46 | mRender = new JNIRender();
47 | }
48 |
49 | final int maxMemory = (int) (Runtime.getRuntime().maxMemory() / 1024);
50 | final int cacheSize = maxMemory / 16;
51 |
52 | mMemoryCache = new LruCache(cacheSize) {
53 | @Override
54 | protected int sizeOf(String key, Bitmap bitmap) {
55 | return bitmap.getByteCount() / 1024;
56 | }
57 | };
58 | }
59 |
60 | public Bitmap blur(Bitmap image, boolean fast) {
61 |
62 | float scale = BITMAP_SCALE_NOMAL;
63 | float radius = BLUR_RADIUS_NOMAL;
64 |
65 | if (fast) {
66 | scale = BITMAP_SCALE_FAST;
67 | radius = BLUR_RADIUS_FAST;
68 | }
69 |
70 | int width = Math.round(image.getWidth() * scale);
71 | int height = Math.round(image.getHeight() * scale);
72 |
73 | Bitmap bitmap = Bitmap.createScaledBitmap(image, width, height, true);
74 | Bitmap outputBitmap = getBitmapFromMemCache("" + width + height);
75 | if (outputBitmap == null) {
76 | outputBitmap = bitmap.copy(bitmap.getConfig(), true);
77 | addBitmapToMemoryCache("" + width + height, outputBitmap);
78 | }
79 |
80 | mRender.blur(radius, bitmap, outputBitmap);
81 | bitmap.recycle();
82 |
83 | return outputBitmap;
84 | }
85 |
86 | private void addBitmapToMemoryCache(String key, Bitmap bitmap) {
87 | if (getBitmapFromMemCache(key) == null) {
88 | mMemoryCache.put(key, bitmap);
89 | }
90 | }
91 |
92 | private Bitmap getBitmapFromMemCache(String key) {
93 | return mMemoryCache.get(key);
94 | }
95 |
96 | public void Destroy() {
97 | if (mRender != null) mRender.destroy();
98 | }
99 |
100 | /* public Bitmap Blur_openGL(Bitmap image, boolean fast) {
101 | float scale = BITMAP_SCALE_NOMAL;
102 | float radius = BLUR_RADIUS_NOMAL;
103 |
104 | if (fast) {
105 | scale = BITMAP_SCALE_FAST;
106 | radius = BLUR_RADIUS_FAST;
107 | }
108 |
109 | int width = Math.round(image.getWidth() * scale);
110 | int height = Math.round(image.getHeight() * scale);
111 |
112 | /* Bitmap bitmap = Bitmap.createScaledBitmap(image, width, height, true);
113 | Bitmap outputBitmap = getBitmapFromMemCache("" + width + height);
114 | if (outputBitmap == null) {
115 | outputBitmap = bitmap.copy(bitmap.getConfig(), true);
116 | addBitmapToMemoryCache("" + width + height, outputBitmap);
117 | }
118 | */
119 | /* if (gl == null) {
120 | gl = new GLRender(image.getWidth(), image.getHeight());
121 | }
122 |
123 | gl.Blur(image, fast);
124 |
125 | return image;
126 |
127 | }
128 | */
129 | }
130 |
131 |
--------------------------------------------------------------------------------
/src/com/koalcat/view/BlurRSRender.java:
--------------------------------------------------------------------------------
1 | package com.koalcat.view;
2 |
3 | import com.koalcat.blurdemo.R;
4 | import com.koalcat.blurdemo.ScriptC_blur;
5 | import com.koalcat.blurdemo.ScriptField_ConvolveParams_s;
6 |
7 | import android.content.Context;
8 | import android.renderscript.Allocation;
9 |
10 | public class BlurRSRender extends RSRender {
11 |
12 | private ScriptC_blur mScript;
13 | private ScriptField_ConvolveParams_s cp;
14 |
15 | public BlurRSRender(Context context) {
16 | super(context);
17 | mScript = new ScriptC_blur(rs, context.getResources(), R.raw.blur);
18 | //cp = new ScriptField_ConvolveParams_s(rs, 1);
19 | //mScript.bind_cp(cp);
20 | //mScript.invoke_setup();
21 | }
22 |
23 | @Override
24 | public void blur(float radius, Allocation tmpIn, Allocation tmpOut) {
25 | //mScript.set_radius(radius);
26 | mScript.forEach_root(tmpIn, tmpOut);
27 | }
28 |
29 | @Override
30 | public void destroy() {
31 | // TODO Auto-generated method stub
32 | super.destroy();
33 | mScript.destroy();
34 | }
35 | }
36 |
--------------------------------------------------------------------------------
/src/com/koalcat/view/GLRender.java:
--------------------------------------------------------------------------------
1 | package com.koalcat.view;
2 |
3 | import java.nio.ByteBuffer;
4 | import java.nio.ByteOrder;
5 | import java.nio.FloatBuffer;
6 | import java.nio.IntBuffer;
7 |
8 | import javax.microedition.khronos.egl.EGL10;
9 | import javax.microedition.khronos.egl.EGLConfig;
10 | import javax.microedition.khronos.egl.EGLContext;
11 | import javax.microedition.khronos.egl.EGLDisplay;
12 | import javax.microedition.khronos.egl.EGLSurface;
13 | import javax.microedition.khronos.opengles.GL10;
14 |
15 | import android.graphics.Bitmap;
16 | import android.util.Log;
17 |
18 | public class GLRender {
19 |
20 | private static final String TAG = "GLRender";
21 |
22 | private EGL10 mEgl;
23 | private EGLDisplay mEglDisplay;
24 | private EGLContext mEglContext;
25 | private EGLSurface mEglPBSurface;
26 | private GL10 mGL;
27 |
28 | private IntBuffer PixelBuffer;
29 |
30 | public GLRender(int width, int height) {
31 |
32 | int[] version = new int[2];
33 | EGLConfig[] configs = new EGLConfig[1];
34 | int[] num_config = new int[1];
35 |
36 | int[] configSpec ={
37 | EGL10.EGL_SURFACE_TYPE, EGL10.EGL_PBUFFER_BIT,
38 | EGL10.EGL_RED_SIZE, 8,
39 | EGL10.EGL_GREEN_SIZE, 8,
40 | EGL10.EGL_BLUE_SIZE, 8,
41 | EGL10.EGL_ALPHA_SIZE, 8,
42 | EGL10.EGL_NONE
43 | };
44 |
45 | int attribListPbuffer[] = {
46 | EGL10.EGL_WIDTH, width,
47 | EGL10.EGL_HEIGHT, height,
48 | EGL10.EGL_NONE
49 | };
50 |
51 | mEgl = (EGL10)EGLContext.getEGL();
52 | mEglDisplay = mEgl.eglGetDisplay(EGL10.EGL_DEFAULT_DISPLAY);
53 |
54 | mEgl.eglInitialize(mEglDisplay, version);
55 |
56 | mEgl.eglChooseConfig(mEglDisplay, configSpec, configs, 1, num_config);
57 |
58 | EGLConfig mEglConfig = configs[0];
59 |
60 | mEglContext = mEgl.eglCreateContext(mEglDisplay, mEglConfig, EGL10.EGL_NO_CONTEXT, null);
61 | if (mEglContext == EGL10.EGL_NO_CONTEXT) {
62 | Log.d(TAG, "EGL_NO_CONTEXT");
63 | }
64 |
65 | mEglPBSurface = mEgl.eglCreatePbufferSurface(mEglDisplay, mEglConfig, attribListPbuffer);
66 | if (mEglPBSurface == EGL10.EGL_NO_SURFACE) {
67 | int errorcode = mEgl.eglGetError();
68 | switch(errorcode) {
69 | case EGL10.EGL_BAD_DISPLAY:
70 | Log.d(TAG, "EGL_BAD_DISPLAY");
71 | break;
72 | case EGL10.EGL_NOT_INITIALIZED:
73 | Log.d(TAG, "EGL_NOT_INITIALIZED");
74 | break;
75 | case EGL10.EGL_BAD_CONFIG:
76 | Log.d(TAG, "EGL_BAD_CONFIG");
77 | break;
78 | case EGL10.EGL_BAD_ATTRIBUTE:
79 | Log.d(TAG, "EGL_BAD_ATTRIBUTE");
80 | break;
81 | case EGL10.EGL_BAD_ALLOC:
82 | Log.d(TAG, "EGL_BAD_ALLOC");
83 | break;
84 | case EGL10.EGL_BAD_MATCH:
85 | Log.d(TAG, "EGL_BAD_MATCH");
86 | break;
87 | }
88 | }
89 |
90 |
91 | if (!mEgl.eglMakeCurrent(mEglDisplay, mEglPBSurface, mEglPBSurface, mEglContext)) {
92 | Log.d(TAG, "bind failed code:" + mEgl.eglGetError());
93 | }
94 |
95 | mGL = (GL10) mEglContext.getGL();
96 | PixelBuffer = IntBuffer.allocate(width * height);
97 | }
98 |
99 | private void process(Bitmap bitmap, boolean fast) {
100 | final GL10 gl = mGL;
101 |
102 | gl.glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
103 | gl.glShadeModel(GL10.GL_SMOOTH);
104 | gl.glEnable(GL10.GL_DEPTH_TEST);
105 | gl.glClearDepthf(1.0f);
106 | gl.glDepthFunc(GL10.GL_LEQUAL);
107 | gl.glHint(GL10.GL_PERSPECTIVE_CORRECTION_HINT, GL10.GL_NICEST);
108 | gl.glEnable(GL10.GL_TEXTURE_2D);
109 | gl.glEnable(GL10.GL_LEQUAL);
110 |
111 | float[] color = new float[16];
112 | FloatBuffer colorBuffer;
113 | float[] texVertex = new float[12];
114 | FloatBuffer vertexBuffer;
115 |
116 | ByteBuffer texByteBuffer = ByteBuffer.allocateDirect(texVertex.length * 4);
117 | texByteBuffer.order(ByteOrder.nativeOrder());
118 | vertexBuffer = texByteBuffer.asFloatBuffer();
119 | vertexBuffer.put(texVertex);
120 | vertexBuffer.position(0);
121 |
122 | ByteBuffer colorByteBuffer = ByteBuffer.allocateDirect(color.length * 4);
123 | colorByteBuffer.order(ByteOrder.nativeOrder());
124 | colorBuffer = colorByteBuffer.asFloatBuffer();
125 | colorBuffer.put(color);
126 | colorBuffer.position(0);
127 |
128 | gl.glClear(GL10.GL_COLOR_BUFFER_BIT | GL10.GL_DEPTH_BUFFER_BIT);
129 | gl.glPushMatrix();
130 | gl.glTranslatef(0.0f, 0.0f, 0.0f);
131 |
132 |
133 |
134 | colorBuffer.clear();
135 | colorBuffer.put(1.0f);
136 | colorBuffer.put(0.0f);
137 | colorBuffer.put(0.0f);
138 | colorBuffer.put(1.0f);
139 |
140 | colorBuffer.put(1.0f);
141 | colorBuffer.put(0.0f);
142 | colorBuffer.put(0.0f);
143 | colorBuffer.put(1.0f);
144 |
145 | colorBuffer.put(1.0f);
146 | colorBuffer.put(0.0f);
147 | colorBuffer.put(0.0f);
148 | colorBuffer.put(1.0f);
149 |
150 | colorBuffer.put(1.0f);
151 | colorBuffer.put(0.0f);
152 | colorBuffer.put(0.0f);
153 | colorBuffer.put(1.0f);
154 |
155 | vertexBuffer.clear();
156 | vertexBuffer.put(0);
157 | vertexBuffer.put(0);
158 | vertexBuffer.put(0);
159 | vertexBuffer.put(5f);
160 | vertexBuffer.put(0);
161 | vertexBuffer.put(0);
162 | vertexBuffer.put(5f);
163 | vertexBuffer.put(5f);
164 | vertexBuffer.put(0);
165 | vertexBuffer.put(0);
166 | vertexBuffer.put(5f);
167 | vertexBuffer.put(0);
168 |
169 | gl.glEnableClientState(GL10.GL_VERTEX_ARRAY);
170 | gl.glEnableClientState(GL10.GL_COLOR_ARRAY);
171 | gl.glVertexPointer(3, GL10.GL_FLOAT, 0, vertexBuffer);
172 |
173 |
174 |
175 | gl.glColorPointer(4, GL10.GL_FLOAT, 0, colorBuffer);
176 |
177 | gl.glDrawArrays(GL10.GL_LINE_LOOP, 0, 4);
178 | gl.glDisableClientState(GL10.GL_COLOR_ARRAY);
179 |
180 | gl.glDisableClientState(GL10.GL_VERTEX_ARRAY);
181 | gl.glPopMatrix();
182 | }
183 |
184 | private Bitmap pullpixs(Bitmap bitmap) {
185 | final int width = bitmap.getWidth();
186 | final int height = bitmap.getHeight();
187 | PixelBuffer.position(0);
188 | mGL.glReadPixels(0, 0, width, height, GL10.GL_RGBA, GL10.GL_UNSIGNED_BYTE, PixelBuffer);
189 | PixelBuffer.position(0);
190 | bitmap.copyPixelsFromBuffer(PixelBuffer);
191 |
192 | return bitmap;
193 | }
194 |
195 | public Bitmap Blur(Bitmap bitmap, boolean fast) {
196 | process(bitmap, fast);
197 | return pullpixs(bitmap);
198 | }
199 | }
200 |
--------------------------------------------------------------------------------
/src/com/koalcat/view/JNIRender.java:
--------------------------------------------------------------------------------
1 | package com.koalcat.view;
2 |
3 | import android.graphics.Bitmap;
4 |
5 | public class JNIRender implements BaseRender {
6 |
7 | static {
8 | System.loadLibrary("blurjni");
9 | }
10 |
11 | private static native void Blur(Bitmap in, Bitmap out, int r);
12 |
13 | @Override
14 | public void blur(float radius, Bitmap in, Bitmap out) {
15 | // TODO Auto-generated method stub
16 | Blur(in, out, (int)radius);
17 | }
18 |
19 | @Override
20 | public void destroy() {
21 | // TODO Auto-generated method stub
22 |
23 | }
24 |
25 | }
26 |
--------------------------------------------------------------------------------
/src/com/koalcat/view/LiveBlurListView.java:
--------------------------------------------------------------------------------
1 | package com.koalcat.view;
2 | /**
3 | * @author xuchdeid@gmail.com
4 | * __________________________ \_/
5 | | | /._.\
6 | | Android!Android! > U| |U
7 | | xuchdeid | |___|
8 | |__________________________| U U
9 | * */
10 | import com.koalcat.blurdemo.R;
11 |
12 | import android.content.Context;
13 | import android.content.res.TypedArray;
14 | import android.graphics.Bitmap;
15 | import android.graphics.Bitmap.Config;
16 | import android.graphics.BlurMaskFilter;
17 | import android.graphics.Canvas;
18 | import android.graphics.Color;
19 | import android.graphics.Paint;
20 | import android.graphics.PorterDuff.Mode;
21 | import android.graphics.Rect;
22 | import android.util.AttributeSet;
23 | import android.view.View;
24 | import android.view.ViewGroup;
25 | import android.widget.ListView;
26 |
27 | public class LiveBlurListView extends ListView {
28 |
29 | /**
30 | * Information about how tall the blur on bottom of the view wants to be.
31 | */
32 | private int blur_bottom_height = 0;
33 |
34 | /**
35 | * Information about how tall the blur on top of the view wants to be.
36 | */
37 | private int blur_top_height = 0;
38 |
39 | /**
40 | * Paint used for draw blur bitmap.
41 | */
42 | private Paint paint;
43 |
44 | /**
45 | * Rect for blur on bottom
46 | */
47 | private Rect mRectBlurForBottom;
48 |
49 | /**
50 | * Rect for blur on top
51 | */
52 | private Rect mRectBlurForTop;
53 |
54 | /**
55 | * Rect for clip Canvas.
56 | */
57 | private Rect mRect;
58 |
59 | /*
60 | * Bitmap for blur on bottom.
61 | */
62 | private Bitmap mCanvasBitmapforBottom;
63 |
64 | /**
65 | * Canvas for blur on bottom.
66 | */
67 | private Canvas mCanvasforBottom;
68 |
69 | /*
70 | * Bitmap for blur on top.
71 | */
72 | private Bitmap mCanvasBitmapforTop;
73 |
74 | /**
75 | * Canvas for blur on top.
76 | */
77 | private Canvas mCanvasforTop;
78 |
79 | /**
80 | * Blur bitmap
81 | */
82 | private Blur mBlur;
83 |
84 | /**
85 | * switch
86 | */
87 | private boolean enableBlur = true;
88 |
89 | public LiveBlurListView(Context context) {
90 | super(context);
91 | }
92 |
93 | public LiveBlurListView(Context context, AttributeSet attrs) {
94 | super(context, attrs);
95 | setup(context, attrs, 0);
96 | }
97 |
98 | public LiveBlurListView(Context context, AttributeSet attrs, int defStyle) {
99 | super(context, attrs, defStyle);
100 | setup(context, attrs, defStyle);
101 | }
102 |
103 | private void setup(Context context, AttributeSet attrs, int defStyle) {
104 | TypedArray a = context.obtainStyledAttributes(attrs,
105 | R.styleable.BlurView, defStyle, 0);
106 | blur_bottom_height = a.getDimensionPixelSize(R.styleable.BlurView_blur_bottom_height, 0);
107 | blur_top_height = a.getDimensionPixelSize(R.styleable.BlurView_blur_top_height, 0);
108 | enableBlur = a.getBoolean(R.styleable.BlurView_blur_enable, false);
109 | a.recycle();
110 |
111 | if (enableBlur) {
112 | //mBlur = new Blur(context);
113 | }
114 |
115 | if (blur_bottom_height > 0) {
116 | View footer = new View(getContext());
117 | LayoutParams params = new LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, blur_bottom_height);
118 | footer.setLayoutParams(params);
119 | addFooterView(footer, null, false);
120 | }
121 |
122 | if (blur_top_height > 0) {
123 | View header = new View(getContext());
124 | LayoutParams params = new LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, blur_top_height);
125 | header.setLayoutParams(params);
126 | addHeaderView(header, null, false);
127 | }
128 |
129 | setLayerType(View.LAYER_TYPE_HARDWARE, null);
130 | }
131 |
132 | @Override
133 | public void draw(Canvas canvas) {
134 | if (enableBlur) {
135 |
136 | final Rect rect = mRect;
137 | final Paint mPaint = paint;
138 |
139 | final Rect blurbottom = mRectBlurForBottom;
140 | final Bitmap canvasBitmapbottom = mCanvasBitmapforBottom;
141 | final Canvas mTempCanvasbottom = mCanvasforBottom;
142 | if (blur_bottom_height > 0) {
143 | mTempCanvasbottom.save();
144 | mTempCanvasbottom.translate(0, -blurbottom.top);
145 | super.draw(mTempCanvasbottom);
146 | mTempCanvasbottom.restore();
147 | }
148 |
149 | final Rect blurtop = mRectBlurForTop;
150 | final Bitmap canvasBitmaptop = mCanvasBitmapforTop;
151 | final Canvas mTempCanvastop = mCanvasforTop;
152 | if (blur_top_height > 0) {
153 | mTempCanvastop.save();
154 | super.draw(mTempCanvastop);
155 | mTempCanvastop.restore();
156 | }
157 |
158 | canvas.save();
159 | canvas.clipRect(rect);
160 | super.draw(canvas);
161 | canvas.restore();
162 |
163 | if (blur_bottom_height > 0) {
164 | Bitmap mBitmap = mBlur.blur(canvasBitmapbottom, true);
165 | canvas.drawBitmap(mBitmap, null, blurbottom, mPaint);
166 | //canvas.drawBitmap(canvasBitmapbottom, null, blurbottom, mPaint);
167 |
168 | mPaint.setColor(0x18888888);
169 | canvas.drawLine(blurbottom.left, blurbottom.top, blurbottom.right, blurbottom.top, mPaint);
170 | mPaint.setColor(Color.BLACK);
171 |
172 | mTempCanvasbottom.drawColor(Color.TRANSPARENT, Mode.CLEAR);
173 | }
174 | if (blur_top_height > 0) {
175 | Bitmap mBitmap = mBlur.blur(canvasBitmaptop, true);
176 | canvas.drawBitmap(mBitmap, null, blurtop, mPaint);
177 | //canvas.drawBitmap(canvasBitmaptop, null, blurtop, mPaint);
178 |
179 | mPaint.setColor(0x18888888);
180 | canvas.drawLine(blurtop.left, blurtop.bottom, blurtop.right, blurtop.bottom, mPaint);
181 | mPaint.setColor(Color.BLACK);
182 |
183 | mTempCanvastop.drawColor(Color.TRANSPARENT, Mode.CLEAR);
184 | }
185 | } else {
186 | super.draw(canvas);
187 | }
188 | }
189 |
190 | @Override
191 | public void onFinishInflate() {
192 | super.onFinishInflate();
193 | }
194 |
195 | @Override
196 | public void onWindowFocusChanged(boolean hasWindowFocus) {
197 | super.onWindowFocusChanged(hasWindowFocus);
198 | }
199 |
200 | public void onSizeChanged(int w, int h, int oldw, int oldh) {
201 | super.onSizeChanged(w, h, oldw, oldh);
202 | if (w != oldw || h != oldh) {
203 | init();
204 | }
205 | }
206 |
207 | private void init() {
208 | if (enableBlur) {
209 |
210 | if (paint == null) {
211 | paint = new Paint();
212 | paint.setAntiAlias(true);
213 | }
214 |
215 | if (mRectBlurForTop == null) mRectBlurForTop = new Rect();
216 | mRectBlurForTop.left = 0;
217 | mRectBlurForTop.right = getWidth();
218 | mRectBlurForTop.top = 0;
219 | mRectBlurForTop.bottom = blur_top_height;
220 |
221 | if (mRectBlurForBottom == null) mRectBlurForBottom = new Rect();
222 | mRectBlurForBottom.left = 0;
223 | mRectBlurForBottom.right = getWidth();
224 | mRectBlurForBottom.bottom = getHeight();
225 | mRectBlurForBottom.top = mRectBlurForBottom.bottom - blur_bottom_height;
226 |
227 | if (mRect == null) mRect = new Rect();
228 | mRect.left = 0;
229 | mRect.right = getWidth();
230 | mRect.bottom = mRectBlurForBottom.top;
231 | mRect.top = mRectBlurForTop.bottom;
232 |
233 | recycle(false);
234 |
235 | if (blur_bottom_height > 0) {
236 | mCanvasBitmapforBottom = Bitmap.createBitmap(mRectBlurForBottom.right - mRectBlurForBottom.left,
237 | blur_bottom_height, Config.ARGB_8888);
238 | mCanvasforBottom = new Canvas(mCanvasBitmapforBottom);
239 | }
240 |
241 | if (blur_top_height > 0) {
242 | mCanvasBitmapforTop = Bitmap.createBitmap(mRectBlurForTop.right - mRectBlurForTop.left,
243 | blur_top_height, Config.ARGB_8888);
244 | mCanvasforTop = new Canvas(mCanvasBitmapforTop);
245 | }
246 |
247 | if (mBlur == null) {
248 | mBlur = new Blur(getContext());
249 | }
250 | }
251 | }
252 |
253 | @Override
254 | protected void onDetachedFromWindow() {
255 | super.onDetachedFromWindow();
256 | recycle(true);
257 | }
258 |
259 | private void recycle(boolean all) {
260 |
261 | if (mCanvasBitmapforBottom != null && !mCanvasBitmapforBottom.isRecycled()) {
262 | mCanvasBitmapforBottom.recycle();
263 | }
264 |
265 | if (mCanvasBitmapforTop != null && !mCanvasBitmapforTop.isRecycled()) {
266 | mCanvasBitmapforTop.recycle();
267 | }
268 |
269 | if (all) {
270 | if (mBlur != null) {
271 | mBlur.Destroy();
272 | }
273 | }
274 | }
275 | }
276 |
--------------------------------------------------------------------------------
/src/com/koalcat/view/LiveBlurViewGroup.java:
--------------------------------------------------------------------------------
1 | package com.koalcat.view;
2 |
3 | import android.content.Context;
4 | import android.util.AttributeSet;
5 | import android.view.ViewGroup;
6 |
7 | public class LiveBlurViewGroup extends ViewGroup {
8 |
9 | public LiveBlurViewGroup(Context context) {
10 | super(context);
11 | // TODO Auto-generated constructor stub
12 | }
13 |
14 | public LiveBlurViewGroup(Context context, AttributeSet attrs) {
15 | super(context, attrs);
16 | // TODO Auto-generated constructor stub
17 | }
18 |
19 | public LiveBlurViewGroup(Context context, AttributeSet attrs, int defStyle) {
20 | super(context, attrs, defStyle);
21 | // TODO Auto-generated constructor stub
22 | }
23 |
24 | @Override
25 | protected void onLayout(boolean changed, int l, int t, int r, int b) {
26 | // TODO Auto-generated method stub
27 |
28 | }
29 |
30 | }
31 |
--------------------------------------------------------------------------------
/src/com/koalcat/view/RSRender.java:
--------------------------------------------------------------------------------
1 | package com.koalcat.view;
2 |
3 | import android.content.Context;
4 | import android.graphics.Bitmap;
5 | import android.renderscript.Allocation;
6 | import android.renderscript.RenderScript;
7 |
8 | public abstract class RSRender implements BaseRender {
9 | protected RenderScript rs;
10 |
11 | public RSRender(Context context) {
12 | rs = RenderScript.create(context);
13 | }
14 |
15 | @Override
16 | public void blur(float radius, Bitmap in, Bitmap out) {
17 | Allocation tmpIn = Allocation.createFromBitmap(rs, in);
18 | Allocation tmpOut = Allocation.createFromBitmap(rs, out);
19 | blur(radius, tmpIn, tmpOut);
20 | tmpOut.copyTo(out);
21 | tmpIn.destroy();
22 | tmpOut.destroy();
23 | }
24 |
25 | public abstract void blur(float radius, Allocation tmpIn, Allocation tmpOut);
26 |
27 | @Override
28 | public void destroy() {
29 | if (rs != null) rs.destroy();
30 | }
31 | }
32 |
--------------------------------------------------------------------------------
/src/com/koalcat/view/ScriptIntrinsicBlurRender.java:
--------------------------------------------------------------------------------
1 | package com.koalcat.view;
2 |
3 | import android.annotation.SuppressLint;
4 | import android.content.Context;
5 | import android.renderscript.Allocation;
6 | import android.renderscript.Element;
7 | import android.renderscript.ScriptIntrinsicBlur;
8 |
9 | public class ScriptIntrinsicBlurRender extends RSRender {
10 |
11 | private ScriptIntrinsicBlur theIntrinsic;
12 |
13 | @SuppressLint("NewApi")
14 | public ScriptIntrinsicBlurRender(Context context) {
15 | super(context);
16 | // TODO Auto-generated constructor stub
17 | theIntrinsic = ScriptIntrinsicBlur.create(rs, Element.U8_4(rs));
18 | }
19 |
20 | @SuppressLint("NewApi")
21 | @Override
22 | public void blur(float radius, Allocation tmpIn, Allocation tmpOut) {
23 | // TODO Auto-generated method stub
24 | theIntrinsic.setRadius(radius);
25 | theIntrinsic.setInput(tmpIn);
26 | theIntrinsic.forEach(tmpOut);
27 | }
28 |
29 | @Override
30 | public void destroy() {
31 | // TODO Auto-generated method stub
32 | super.destroy();
33 | theIntrinsic.destroy();
34 | }
35 | }
36 |
--------------------------------------------------------------------------------
/src/com/koalcat/view/blur.rs:
--------------------------------------------------------------------------------
1 | #pragma version(1)
2 | #pragma rs java_package_name(com.koalcat.blurdemo)
3 |
4 | #include "rs_graphics.rsh"
5 | #include "rs_cl.rsh"
6 | #include "rs_debug.rsh"
7 |
8 | typedef struct ConvolveParams_s {
9 | float fp[104];
10 | uint32_t ip[104];
11 | float radius;
12 | uint32_t iradius;
13 | } ConvolveParams;
14 |
15 | ConvolveParams *cp;
16 | float radius;
17 | float width;
18 | float height;
19 |
20 |
21 | const static float3 gMonoMult = {0.299f, 0.587f, 0.114f};
22 |
23 | void setup() {
24 |
25 | float e = 2.718281828459045f;
26 | float pi = 3.1415926535897932f;
27 | float sigma = 0.4f * radius + 0.6f;
28 |
29 | float coeff1 = 1.0f / (sqrt(2.0f * pi) * sigma);
30 | float coeff2 = - 1.0f / (2.0f * sigma * sigma);
31 |
32 | float normalizeFactor = 0.0f;
33 | float floatR = 0.0f;
34 | int r;
35 | cp->iradius = (float)ceil(cp->radius) + 0.5f;
36 | for (r = -cp->iradius; r <= cp->iradius; r ++) {
37 | floatR = (float)r;
38 | cp->fp[r + cp->iradius] = coeff1 * pow(e, floatR * floatR * coeff2);
39 | normalizeFactor += cp->fp[r + cp->iradius];
40 | }
41 |
42 | normalizeFactor = 1.0f / normalizeFactor;
43 | for (r = -cp->iradius; r <= cp->iradius; r ++) {
44 | cp->fp[r + cp->iradius] *= normalizeFactor;
45 | cp->ip[r + cp->iradius] = (cp->ip[r + cp->iradius] * 32768);
46 | }
47 |
48 | }
49 |
50 | void init() {
51 | radius = 5;
52 | width = 0;
53 | height = 0;
54 | }
55 |
56 | void root(const uchar4 *v_in, uchar4 *v_out, uint32_t x, uint32_t y) {
57 |
58 | /*uchar4 out1 = v_in[0];
59 | out1.r = 255 - out1.r;
60 | out1.g = 255 - out1.g;
61 | out1.b = 255 - out1.b;
62 |
63 | *v_out = out1;
64 |
65 | return;
66 | */
67 |
68 | if (x == 0 || y == 0 || x == width || y == height) {
69 | *v_out = v_in[0];
70 | return;
71 | }
72 |
73 | uchar4 out;
74 | int R = 0, G = 0, B = 0;
75 |
76 | for (int g = -1; g <= 1; g ++) {
77 | for (int r = -1; r <= 1; r ++) {
78 | if (r == 0 && g == 0) continue;
79 | int p = r + g * 3;
80 |
81 | out = v_in[p];
82 | R += out.r*0.125f;
83 | G += out.g*0.125f;
84 | B += out.b*0.125f;
85 | }
86 | }
87 | out.r = R;
88 | out.g = G;
89 | out.b = B;
90 |
91 | *v_out = out;
92 |
93 | }
94 | /*
95 | uchar4 __attribute__((kernel)) invert(uchar4 in, uint32_t x, uint32_t y) {
96 | uchar4 out = in;
97 | out.r = 255 - in.r;
98 | out.g = 255 - in.g;
99 | out.b = 255 - in.b;
100 | return out;
101 | }
102 | */
--------------------------------------------------------------------------------