1 /*
2  * Copyright (C) 2010 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 package com.android.statusbartest;
18 
19 import java.util.GregorianCalendar;
20 
21 import android.app.Activity;
22 import android.app.Notification;
23 import android.app.NotificationManager;
24 import android.app.PendingIntent;
25 import android.content.Context;
26 import android.content.ContentResolver;
27 import android.content.Intent;
28 import android.graphics.Bitmap;
29 import android.graphics.drawable.BitmapDrawable;
30 import android.net.Uri;
31 import android.os.Bundle;
32 import android.os.Environment;
33 import android.os.Handler;
34 import android.os.Vibrator;
35 import android.os.Handler;
36 import android.text.SpannableStringBuilder;
37 import android.text.TextUtils;
38 import android.util.Log;
39 import android.net.Uri;
40 import android.os.SystemClock;
41 import android.view.View;
42 import android.widget.CompoundButton;
43 import android.widget.RadioButton;
44 import android.widget.RadioGroup;
45 import android.widget.RemoteViews;
46 import android.os.PowerManager;
47 
48 public class NotificationBuilderTest extends Activity
49 {
50     private final static String TAG = "NotificationTestList";
51 
52     private final static String NOTIFY_TAG = "foo";
53 
54     NotificationManager mNM;
55     Handler mHandler;
56     int mStartDelay;
57 
58     @Override
onCreate(Bundle icicle)59     public void onCreate(Bundle icicle) {
60         super.onCreate(icicle);
61         mNM = (NotificationManager)getSystemService(NOTIFICATION_SERVICE);
62         mHandler = new Handler();
63         setContentView(R.layout.notification_builder_test);
64         if (icicle == null) {
65             setDefaults();
66         }
67         for (int id: new int[] {
68                     R.id.clear_1,
69                     R.id.clear_2,
70                     R.id.clear_3,
71                     R.id.clear_4,
72                     R.id.clear_5,
73                     R.id.clear_6,
74                     R.id.clear_7,
75                     R.id.clear_8,
76                     R.id.clear_9,
77                     R.id.clear_10,
78                     R.id.notify_1,
79                     R.id.notify_2,
80                     R.id.notify_3,
81                     R.id.notify_4,
82                     R.id.notify_5,
83                     R.id.notify_6,
84                     R.id.notify_7,
85                     R.id.notify_8,
86                     R.id.notify_9,
87                     R.id.notify_10,
88                     R.id.ten,
89                     R.id.clear_all,
90                 }) {
91             findViewById(id).setOnClickListener(mClickListener);
92         }
93     }
94 
setDefaults()95     private void setDefaults() {
96         setChecked(R.id.when_now);
97         setChecked(R.id.icon_surprise);
98         setChecked(R.id.title_medium);
99         setChecked(R.id.text_medium);
100         setChecked(R.id.info_none);
101         setChecked(R.id.number_0);
102         setChecked(R.id.intent_alert);
103         setChecked(R.id.delete_none);
104         setChecked(R.id.full_screen_none);
105         setChecked(R.id.ticker_none);
106         setChecked(R.id.large_icon_none);
107         setChecked(R.id.sound_none);
108         setChecked(R.id.vibrate_none);
109         setChecked(R.id.pri_default);
110         setChecked(R.id.lights_red);
111         setChecked(R.id.lights_off);
112         setChecked(R.id.delay_none);
113 //        setChecked(R.id.default_vibrate);
114 //        setChecked(R.id.default_sound);
115 //        setChecked(R.id.default_lights);
116     }
117 
118     private View.OnClickListener mClickListener = new View.OnClickListener() {
119         public void onClick(View v) {
120             switch (v.getId()) {
121                 case R.id.clear_1:
122                     cancelNotification(1);
123                     break;
124                 case R.id.clear_2:
125                     cancelNotification(2);
126                     break;
127                 case R.id.clear_3:
128                     cancelNotification(3);
129                     break;
130                 case R.id.clear_4:
131                     cancelNotification(4);
132                     break;
133                 case R.id.clear_5:
134                     cancelNotification(5);
135                     break;
136                 case R.id.clear_6:
137                     cancelNotification(6);
138                     break;
139                 case R.id.clear_7:
140                     cancelNotification(7);
141                     break;
142                 case R.id.clear_8:
143                     cancelNotification(8);
144                     break;
145                 case R.id.clear_9:
146                     cancelNotification(9);
147                     break;
148                 case R.id.clear_10:
149                     cancelNotification(10);
150                     break;
151                 case R.id.notify_1:
152                     sendNotification(1);
153                     break;
154                 case R.id.notify_2:
155                     sendNotification(2);
156                     break;
157                 case R.id.notify_3:
158                     sendNotification(3);
159                     break;
160                 case R.id.notify_4:
161                     sendNotification(4);
162                     break;
163                 case R.id.notify_5:
164                     sendNotification(5);
165                     break;
166                 case R.id.notify_6:
167                     sendNotification(6);
168                     break;
169                 case R.id.notify_7:
170                     sendNotification(7);
171                     break;
172                 case R.id.notify_8:
173                     sendNotification(8);
174                     break;
175                 case R.id.notify_9:
176                     sendNotification(9);
177                     break;
178                 case R.id.notify_10:
179                     sendNotification(10);
180                     break;
181                 case R.id.ten: {
182                     for (int id=1; id<=10; id++) {
183                         sendNotification(id);
184                     }
185                     break;
186                 }
187                 case R.id.clear_all: {
188                     for (int id=1; id<=10; id++) {
189                         mNM.cancel(id);
190                     }
191                     break;
192                 }
193             }
194         }
195     };
196 
sendNotification(final int id)197     private void sendNotification(final int id) {
198         final Notification n = buildNotification(id);
199         mHandler.postDelayed(new Runnable() {
200             public void run() {
201                 mNM.notify(NOTIFY_TAG, id, n);
202             }
203         }, mStartDelay);
204     }
205 
cancelNotification(final int id)206     private void cancelNotification(final int id) {
207         mNM.cancel(NOTIFY_TAG, id);
208     }
209 
subst(CharSequence in, char ch, CharSequence sub)210     private static CharSequence subst(CharSequence in, char ch, CharSequence sub) {
211         int i=0;
212         SpannableStringBuilder edit = new SpannableStringBuilder(in);
213         while (i<edit.length()) {
214             if (edit.charAt(i) == ch) {
215                 edit.replace(i, i+1, sub);
216                 i += sub.length();
217             } else {
218                 i ++;
219             }
220         }
221         return edit;
222     }
223 
buildNotification(int id)224     private Notification buildNotification(int id) {
225         Notification.Builder b = new Notification.Builder(this);
226 
227         // when
228         switch (getRadioChecked(R.id.group_when)) {
229             case R.id.when_midnight: {
230                 GregorianCalendar c = new GregorianCalendar();
231                 c.set(GregorianCalendar.HOUR_OF_DAY, 0);
232                 c.set(GregorianCalendar.MINUTE, 0);
233                 c.set(GregorianCalendar.SECOND, 0);
234                 b.setWhen(c.getTimeInMillis());
235                 break;
236             }
237             case R.id.when_now:
238                 b.setWhen(System.currentTimeMillis());
239                 break;
240             case R.id.when_now_plus_1h:
241                 break;
242             case R.id.when_tomorrow:
243                 break;
244         }
245 
246         // icon
247         switch (getRadioChecked(R.id.group_icon)) {
248             case R.id.icon_im:
249                 b.setSmallIcon(R.drawable.icon1);
250                 break;
251             case R.id.icon_alert:
252                 b.setSmallIcon(R.drawable.icon2);
253                 break;
254             case R.id.icon_surprise:
255                 b.setSmallIcon(R.drawable.emo_im_kissing);
256                 break;
257         }
258 
259         // title
260         final CharSequence title = getRadioTag(R.id.group_title);
261         if (!TextUtils.isEmpty(title)) {
262             b.setContentTitle(title);
263         }
264 
265         // text
266         final CharSequence text = getRadioTag(R.id.group_text);
267         if (!TextUtils.isEmpty(text)) {
268             if (getRadioChecked(R.id.group_text) == R.id.text_emoji) {
269                 // UTF-16 for +1F335
270                 b.setContentText(subst(text,
271                         '_', "\ud83c\udf35"));
272             } else {
273                 b.setContentText(text);
274             }
275         }
276 
277         // info
278         final CharSequence info = getRadioTag(R.id.group_info);
279         if (!TextUtils.isEmpty(info)) {
280             b.setContentInfo(info);
281         }
282 
283         // number
284         b.setNumber(getRadioInt(R.id.group_number, 0));
285 
286         // contentIntent
287         switch (getRadioChecked(R.id.group_intent)) {
288             case R.id.intent_none:
289                 break;
290             case R.id.intent_alert:
291                 b.setContentIntent(makeContentIntent(id));
292                 break;
293         }
294 
295         // deleteIntent
296         switch (getRadioChecked(R.id.group_delete)) {
297             case R.id.delete_none:
298                 break;
299             case R.id.delete_alert:
300                 b.setDeleteIntent(makeDeleteIntent(id));
301                 break;
302         }
303 
304         // fullScreenIntent TODO
305 
306         // ticker
307         switch (getRadioChecked(R.id.group_ticker)) {
308             case R.id.ticker_none:
309                 break;
310             case R.id.ticker_short:
311             case R.id.ticker_wrap:
312             case R.id.ticker_haiku:
313                 b.setTicker(getRadioTag(R.id.group_ticker));
314                 break;
315             case R.id.ticker_emoji:
316                 // UTF-16 for +1F335
317                 b.setTicker(subst(getRadioTag(R.id.group_ticker),
318                         '_', "\ud83c\udf35"));
319                 break;
320             case R.id.ticker_custom:
321                 // TODO
322                 break;
323         }
324 
325         // largeIcon
326         switch (getRadioChecked(R.id.group_large_icon)) {
327             case R.id.large_icon_none:
328                 break;
329             case R.id.large_icon_pineapple:
330                 b.setLargeIcon(loadBitmap(R.drawable.pineapple));
331                 break;
332             case R.id.large_icon_pineapple2:
333                 b.setLargeIcon(loadBitmap(R.drawable.pineapple2));
334                 break;
335             case R.id.large_icon_small:
336                 b.setLargeIcon(loadBitmap(R.drawable.icon2));
337                 break;
338         }
339 
340         // sound TODO
341 
342         // vibrate
343         switch (getRadioChecked(R.id.group_vibrate)) {
344             case R.id.vibrate_none:
345                 b.setVibrate(null);
346                 break;
347             case R.id.vibrate_zero:
348                 b.setVibrate(new long[] { 0 });
349                 break;
350             case R.id.vibrate_short:
351                 b.setVibrate(new long[] { 0, 100 });
352                 break;
353             case R.id.vibrate_long:
354                 b.setVibrate(new long[] { 0, 1000 });
355                 break;
356             case R.id.vibrate_pattern:
357                 b.setVibrate(new long[] { 0, 50,  200, 50,  200, 50,  500,
358                                              500, 200, 500, 200, 500, 500,
359                                              50,  200, 50,  200, 50        });
360                 break;
361         }
362 
363         // lights
364         final int color = getRadioHex(R.id.group_lights_color, 0xff0000);
365         int onMs;
366         int offMs;
367         switch (getRadioChecked(R.id.group_lights_blink)) {
368             case R.id.lights_slow:
369                 onMs = 1300;
370                 offMs = 1300;
371                 break;
372             case R.id.lights_fast:
373                 onMs = 300;
374                 offMs = 300;
375                 break;
376             case R.id.lights_on:
377                 onMs = 1;
378                 offMs = 0;
379                 break;
380             case R.id.lights_off:
381             default:
382                 onMs = 0;
383                 offMs = 0;
384                 break;
385         }
386         if (onMs != 0 && offMs != 0) {
387             b.setLights(color, onMs, offMs);
388         }
389 
390         // priority
391         switch (getRadioChecked(R.id.group_priority)) {
392             case R.id.pri_min:
393                 b.setPriority(Notification.PRIORITY_MIN);
394                 break;
395             case R.id.pri_low:
396                 b.setPriority(Notification.PRIORITY_LOW);
397                 break;
398             case R.id.pri_default:
399                 b.setPriority(Notification.PRIORITY_DEFAULT);
400                 break;
401             case R.id.pri_high:
402                 b.setPriority(Notification.PRIORITY_HIGH);
403                 break;
404             case R.id.pri_max:
405                 b.setPriority(Notification.PRIORITY_MAX);
406                 break;
407         }
408 
409         // start delay
410         switch (getRadioChecked(R.id.group_delay)) {
411             case R.id.delay_none:
412                 mStartDelay = 0;
413                 break;
414             case R.id.delay_5:
415                 mStartDelay = 5000;
416                 break;
417         }
418 
419         // flags
420         b.setOngoing(getChecked(R.id.flag_ongoing));
421         b.setOnlyAlertOnce(getChecked(R.id.flag_once));
422         b.setAutoCancel(getChecked(R.id.flag_auto_cancel));
423 
424         // defaults
425         int defaults = 0;
426         if (getChecked(R.id.default_sound)) {
427             defaults |= Notification.DEFAULT_SOUND;
428         }
429         if (getChecked(R.id.default_vibrate)) {
430             defaults |= Notification.DEFAULT_VIBRATE;
431         }
432         if (getChecked(R.id.default_lights)) {
433             defaults |= Notification.DEFAULT_LIGHTS;
434         }
435         b.setDefaults(defaults);
436 
437         return b.build();
438     }
439 
setChecked(int id)440     private void setChecked(int id) {
441         final CompoundButton b = (CompoundButton)findViewById(id);
442         b.setChecked(true);
443     }
444 
getRadioChecked(int id)445     private int getRadioChecked(int id) {
446         final RadioGroup g = (RadioGroup)findViewById(id);
447         return g.getCheckedRadioButtonId();
448     }
449 
getRadioTag(int id)450     private String getRadioTag(int id) {
451         final RadioGroup g = (RadioGroup)findViewById(id);
452         final View v = findViewById(g.getCheckedRadioButtonId());
453         return (String) v.getTag();
454     }
455 
getRadioInt(int id, int def)456     private int getRadioInt(int id, int def) {
457         String str = getRadioTag(id);
458         if (TextUtils.isEmpty(str)) {
459             return def;
460         } else {
461             try {
462                 return Integer.parseInt(str.toString());
463             } catch (NumberFormatException ex) {
464                 return def;
465             }
466         }
467     }
468 
getRadioHex(int id, int def)469     private int getRadioHex(int id, int def) {
470         String str = getRadioTag(id);
471         if (TextUtils.isEmpty(str)) {
472             return def;
473         } else {
474             if (str.startsWith("0x")) {
475                 str = str.substring(2);
476             }
477             try {
478                 return Integer.parseInt(str.toString(), 16);
479             } catch (NumberFormatException ex) {
480                 return def;
481             }
482         }
483     }
484 
getChecked(int id)485     private boolean getChecked(int id) {
486         final CompoundButton b = (CompoundButton)findViewById(id);
487         return b.isChecked();
488     }
489 
loadBitmap(int id)490     private Bitmap loadBitmap(int id) {
491         final BitmapDrawable bd = (BitmapDrawable)getResources().getDrawable(id);
492         return Bitmap.createBitmap(bd.getBitmap());
493     }
494 
makeDeleteIntent(int id)495     private PendingIntent makeDeleteIntent(int id) {
496         Intent intent = new Intent(this, ConfirmationActivity.class);
497         intent.setData(Uri.fromParts("content", "//status_bar_test/delete/" + id, null));
498         intent.putExtra(ConfirmationActivity.EXTRA_TITLE, "Delete intent");
499         intent.putExtra(ConfirmationActivity.EXTRA_TEXT, "id: " + id);
500         return PendingIntent.getActivity(this, 0, intent, 0);
501     }
502 
makeContentIntent(int id)503     private PendingIntent makeContentIntent(int id) {
504         Intent intent = new Intent(this, ConfirmationActivity.class);
505         intent.setData(Uri.fromParts("content", "//status_bar_test/content/" + id, null));
506         intent.putExtra(ConfirmationActivity.EXTRA_TITLE, "Content intent");
507         intent.putExtra(ConfirmationActivity.EXTRA_TEXT, "id: " + id);
508         return PendingIntent.getActivity(this, 0, intent, 0);
509     }
510 }
511 
512