Home | History | Annotate | Download | only in notificationshowcase
      1 // dummy notifications for demos
      2 // for anandx (at) google.com by dsandler (at) google.com
      3 
      4 package com.android.example.notificationshowcase;
      5 
      6 import java.util.ArrayList;
      7 import android.app.Activity;
      8 import android.app.Notification;
      9 import android.app.NotificationManager;
     10 import android.app.PendingIntent;
     11 import android.app.Service;
     12 import android.content.ComponentName;
     13 import android.content.Context;
     14 import android.content.Intent;
     15 import android.graphics.Bitmap;
     16 import android.graphics.Canvas;
     17 import android.graphics.Typeface;
     18 import android.graphics.drawable.BitmapDrawable;
     19 import android.graphics.drawable.Drawable;
     20 import android.net.Uri;
     21 import android.os.Binder;
     22 import android.os.Bundle;
     23 import android.os.IBinder;
     24 import android.support.v4.app.NotificationCompat;
     25 import android.text.SpannableString;
     26 import android.text.style.StyleSpan;
     27 import android.util.Log;
     28 import android.view.View;
     29 import android.widget.Toast;
     30 
     31 public class NotificationShowcaseActivity extends Activity {
     32     private static final String TAG = "NotificationShowcase";
     33 
     34     private static final int NOTIFICATION_ID = 31338;
     35 
     36     private static int bigtextId;
     37     private static int uploadId;
     38 
     39     private static final boolean FIRE_AND_FORGET = true;
     40 
     41     public static class ToastFeedbackActivity extends Activity {
     42         @Override
     43         public void onCreate(Bundle icicle) {
     44             super.onCreate(icicle);
     45         }
     46 
     47         @Override
     48         public void onResume() {
     49             super.onResume();
     50             Intent i = getIntent();
     51             Log.v(TAG, "clicked a thing! intent=" + i.toString());
     52             if (i.hasExtra("text")) {
     53                 final String text = i.getStringExtra("text");
     54                 Toast.makeText(this, text, Toast.LENGTH_LONG).show();
     55             }
     56             finish();
     57         }
     58     }
     59 
     60     public static class UpdateService extends Service {
     61         @Override
     62             public IBinder onBind(Intent intent) {
     63             Log.v(TAG, "onbind");
     64             return null;
     65         }
     66 
     67         @Override
     68         public void onStart(Intent i, int startId) {
     69             super.onStart(i, startId);
     70             try {
     71                 // allow the user close the shade, if they want to test that.
     72                 Thread.sleep(3000);
     73             } catch (Exception e) {
     74             }
     75             Log.v(TAG, "clicked a thing! intent=" + i.toString());
     76             if (i.hasExtra("id") && i.hasExtra("when")) {
     77                 final int id = i.getIntExtra("id", 0);
     78                 if (id == bigtextId) {
     79                     NotificationManager noMa =
     80                             (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
     81                     final int update = i.getIntExtra("update", 0);
     82                     final long when = i.getLongExtra("when", 0L);
     83                     Log.v(TAG, "id: " + id + " when: " + when + " update: " + update);
     84                     noMa.notify(NOTIFICATION_ID + id,
     85                                 makeBigTextNotification(this, update, id, when));
     86                 }
     87             } else {
     88                 Log.v(TAG, "id extra was " + (i.hasExtra("id") ? "present" : "missing"));
     89                 Log.v(TAG, "when extra was " + (i.hasExtra("when") ? "present"  : "missing"));
     90             }
     91         }
     92     }
     93 
     94     public static class ProgressService extends Service {
     95         @Override
     96             public IBinder onBind(Intent intent) {
     97             Log.v(TAG, "onbind");
     98             return null;
     99         }
    100 
    101         @Override
    102         public void onStart(Intent i, int startId) {
    103             super.onStart(i, startId);
    104             if (i.hasExtra("id") && i.hasExtra("when") && i.hasExtra("progress")) {
    105                 final int id = i.getIntExtra("id", 0);
    106                 if (id == uploadId) {
    107                     final long when = i.getLongExtra("when", 0L);
    108                     int progress = i.getIntExtra("progress", 0);
    109                     NotificationManager noMa = (NotificationManager)
    110                             getSystemService(Context.NOTIFICATION_SERVICE);
    111                     while (progress <= 100) {
    112                         try {
    113                             // allow the user close the shade, if they want to test that.
    114                             Thread.sleep(1000);
    115                         } catch (Exception e) {
    116                         }
    117                         Log.v(TAG, "id: " + id + " when: " + when + " progress: " + progress);
    118                         noMa.notify(NOTIFICATION_ID + id,
    119                                     makeUploadNotification(this, progress, id, when));
    120                         progress+=10;
    121                     }
    122                 }
    123             } else {
    124                 Log.v(TAG, "id extra " + (i.hasExtra("id") ? "present" : "missing"));
    125                 Log.v(TAG, "when extra " + (i.hasExtra("when") ? "present"  : "missing"));
    126                 Log.v(TAG, "progress extra " + (i.hasExtra("progress") ? "present"  : "missing"));
    127             }
    128         }
    129     }
    130 
    131     private ArrayList<Notification> mNotifications = new ArrayList<Notification>();
    132     NotificationManager mNoMa;
    133 
    134     static int mLargeIconWidth, mLargeIconHeight;
    135     private static Bitmap getBitmap(Context context, int resId) {
    136         Drawable d = context.getResources().getDrawable(resId);
    137         Bitmap b = Bitmap.createBitmap(mLargeIconWidth, mLargeIconHeight, Bitmap.Config.ARGB_8888);
    138         Canvas c = new Canvas(b);
    139         d.setBounds(0, 0, mLargeIconWidth, mLargeIconHeight);
    140         d.draw(c);
    141         return b;
    142     }
    143 
    144     private static PendingIntent makeToastIntent(Context context, String s) {
    145         Intent toastIntent = new Intent(context, ToastFeedbackActivity.class);
    146         toastIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
    147         toastIntent.putExtra("text", s);
    148         PendingIntent pi = PendingIntent.getActivity(
    149                 context, 58, toastIntent, PendingIntent.FLAG_CANCEL_CURRENT);
    150         return pi;
    151     }
    152 
    153     private static PendingIntent makeEmailIntent(Context context, String who) {
    154         final Intent intent = new Intent(android.content.Intent.ACTION_SENDTO,
    155                 Uri.parse("mailto:" + who));
    156         return PendingIntent.getActivity(
    157                 context, 0, intent,
    158                 PendingIntent.FLAG_CANCEL_CURRENT);
    159     }
    160 
    161     // this is a service, it will only close the notification shade if used as a contentIntent.
    162     private static int updateId = 3000;
    163     private static PendingIntent makeUpdateIntent(Context context, int update, int id, long when) {
    164         Intent updateIntent = new Intent();
    165         updateIntent.setComponent(
    166                 new ComponentName(context, UpdateService.class));
    167         updateIntent.putExtra("id", id);
    168         updateIntent.putExtra("when", when);
    169         updateIntent.putExtra("update", update);
    170         Log.v(TAG, "added id extra " + id);
    171         Log.v(TAG, "added when extra " + when);
    172         PendingIntent pi = PendingIntent.getService(
    173                 context, updateId++, updateIntent, PendingIntent.FLAG_UPDATE_CURRENT);
    174         return pi;
    175     }
    176 
    177     private static Notification makeBigTextNotification(Context context, int update, int id,
    178                                                         long when) {
    179         String addendum = update > 0 ? "(updated) " : "";
    180         String longSmsText = "Hey, looks like\nI'm getting kicked out of this conference" +
    181                 " room";
    182         if (update > 1) {
    183             longSmsText += ", so stay in the hangout and I'll rejoin in about 5-10 minutes" +
    184                 ". If you don't see me, assume I got pulled into another meeting. And" +
    185                 " now \u2026 I have to find my shoes.  Four score and seven years "+
    186                 "ago our fathers brought forth on this continent, a new nation, conceived "+
    187                 "in Liberty, and dedicated to the proposition that all men are created "+
    188                 "equal. Now we are engaged in a great civil war, testing whether that "+
    189                 "nation, or any nation so conceived and so dedicated, can long "+
    190                 "endure. We are met on a great battle-field of that war. We have come "+
    191                 "to dedicate a portion of that field, as a final resting place for "+
    192                 "those who here gave their lives that that nation might live. It is "+
    193                 "altogether fitting and proper that we should do this.But, in a larger "+
    194                 "sense, we can not dedicate -- we can not consecrate -- we can not "+
    195                 "hallow -- this ground.The brave men, living and dead, who struggled "+
    196                 "here, have consecrated it, far above our poor power to add or detract."+
    197                 " The world will little note, nor long remember what we say here, but "+
    198                 "it can never forget what they did here. It is for us the living, rather,"+
    199                 " to be dedicated here to the unfinished work which they who fought "+
    200                 "here have thus far so nobly advanced.It is rather for us to be here "+
    201                 "dedicated to the great task remaining before us -- that from these "+
    202                 "honored dead we take increased devotion to that cause for which they "+
    203                 "gave the last full measure of devotion -- that we here highly resolve "+
    204                 "that these dead shall not have died in vain -- that this nation, under "+
    205                 "God, shall have a new birth of freedom -- and that government of "+
    206                 "the people, by the people, for the people, shall not perish from the earth.";
    207         }
    208         if (update > 2) {
    209             when = System.currentTimeMillis();
    210         }
    211         NotificationCompat.BigTextStyle bigTextStyle = new NotificationCompat.BigTextStyle();
    212         bigTextStyle.bigText(addendum + longSmsText);
    213         NotificationCompat.Builder bigTextNotification = new NotificationCompat.Builder(context)
    214                 .setContentTitle(addendum + "Mike Cleron")
    215                 .setContentIntent(makeToastIntent(context, "Clicked on bigText"))
    216                 .setContentText(addendum + longSmsText)
    217                 .setTicker(addendum + "Mike Cleron: " + longSmsText)
    218                 .setWhen(when)
    219                 .setLargeIcon(getBitmap(context, R.drawable.bucket))
    220                 .setPriority(NotificationCompat.PRIORITY_HIGH)
    221                 .addAction(R.drawable.ic_media_next,
    222                            "update: " + update,
    223                            makeUpdateIntent(context, update+1, id, when))
    224                 .setSmallIcon(R.drawable.stat_notify_talk_text)
    225                 .setStyle(bigTextStyle);
    226         return bigTextNotification.build();
    227     }
    228 
    229     // this is a service, it will only close the notification shade if used as a contentIntent.
    230     private static void startProgressUpdater(Context context, int progress, int id, long when) {
    231         Intent progressIntent = new Intent();
    232         progressIntent.setComponent(new ComponentName(context, ProgressService.class));
    233         progressIntent.putExtra("id", id);
    234         progressIntent.putExtra("when", when);
    235         progressIntent.putExtra("progress", progress);
    236         context.startService(progressIntent);
    237     }
    238 
    239     private static Notification makeUploadNotification(Context context, int progress, int id,
    240                                                        long when) {
    241         NotificationCompat.Builder uploadNotification = new NotificationCompat.Builder(context)
    242                 .setContentTitle("File Upload")
    243                 .setContentText("foo.txt")
    244                 .setPriority(NotificationCompat.PRIORITY_MIN)
    245                 .setContentIntent(makeToastIntent(context, "Clicked on Upload"))
    246                 .setWhen(when)
    247                 .setSmallIcon(R.drawable.ic_menu_upload)
    248                 .setProgress(100, Math.min(progress, 100), false);
    249         return uploadNotification.build();
    250     }
    251 
    252     @Override
    253     public void onCreate(Bundle savedInstanceState) {
    254         super.onCreate(savedInstanceState);
    255         setContentView(R.layout.main);
    256 
    257         mLargeIconWidth = (int) getResources().getDimension(R.dimen.notification_large_icon_width);
    258         mLargeIconHeight = (int) getResources().getDimension(R.dimen.notification_large_icon_height);
    259 
    260         mNoMa = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
    261 
    262         bigtextId = mNotifications.size();
    263         mNotifications.add(makeBigTextNotification(this, 0, bigtextId,
    264                                                    System.currentTimeMillis()));
    265 
    266         uploadId = mNotifications.size();
    267         long uploadWhen = System.currentTimeMillis();
    268         mNotifications.add(makeUploadNotification(this, 10, uploadId, uploadWhen));
    269 
    270         mNotifications.add(new NotificationCompat.Builder(this)
    271         .setContentTitle("Incoming call")
    272         .setContentText("Matias Duarte")
    273         .setLargeIcon(getBitmap(this, R.drawable.matias_hed))
    274         .setSmallIcon(R.drawable.stat_sys_phone_call)
    275         .setPriority(NotificationCompat.PRIORITY_MAX)
    276         .setContentIntent(makeToastIntent(this, "Clicked on Matias"))
    277         .addAction(R.drawable.ic_dial_action_call, "Answer", makeToastIntent(this, "call answered"))
    278         .addAction(R.drawable.ic_end_call, "Ignore", makeToastIntent(this, "call ignored"))
    279         .setAutoCancel(true)
    280         .build());
    281 
    282         mNotifications.add(new NotificationCompat.Builder(this)
    283         .setContentTitle("Stopwatch PRO")
    284         .setContentText("Counting up")
    285         .setContentIntent(makeToastIntent(this, "Clicked on Stopwatch"))
    286         .setSmallIcon(R.drawable.stat_notify_alarm)
    287         .setUsesChronometer(true)
    288         .build());
    289 
    290         mNotifications.add(new NotificationCompat.Builder(this)
    291             .setContentTitle("J Planning")
    292             .setContentText("The Botcave")
    293             .setWhen(System.currentTimeMillis())
    294             .setSmallIcon(R.drawable.stat_notify_calendar)
    295             .setContentIntent(makeToastIntent(this, "tapped in the calendar event"))
    296             .setContentInfo("7PM")
    297             .addAction(R.drawable.stat_notify_snooze, "+10 min",
    298                        makeToastIntent(this, "snoozed 10 min"))
    299             .addAction(R.drawable.stat_notify_snooze_longer, "+1 hour",
    300                        makeToastIntent(this, "snoozed 1 hr"))
    301             .addAction(R.drawable.stat_notify_email, "Email",
    302                        makeEmailIntent(this,
    303                                "gabec (at) example.com,mcleron (at) example.com,dsandler (at) example.com"))
    304             .build());
    305 
    306         BitmapDrawable d =
    307                 (BitmapDrawable) getResources().getDrawable(R.drawable.romainguy_rockaway);
    308         mNotifications.add(new NotificationCompat.BigPictureStyle(
    309                 new NotificationCompat.Builder(this)
    310                     .setContentTitle("Romain Guy")
    311                     .setContentText("I was lucky to find a Canon 5D Mk III at a local Bay Area store last "
    312                             + "week but I had not been able to try it in the field until tonight. After a "
    313                             + "few days of rain the sky finally cleared up. Rockaway Beach did not disappoint "
    314                             + "and I was finally able to see what my new camera feels like when shooting "
    315                             + "landscapes.")
    316                     .setSmallIcon(R.drawable.ic_stat_gplus)
    317                     .setContentIntent(makeToastIntent(this, "Clicked on bigPicture"))
    318                     .setLargeIcon(getBitmap(this, R.drawable.romainguy_hed))
    319                     .addAction(R.drawable.add, "Add to Gallery",
    320                                makeToastIntent(this, "added! (just kidding)"))
    321                     .setSubText("talk rocks!")
    322                 )
    323                 .bigPicture(d.getBitmap())
    324                 .build());
    325 
    326         // Note: this may conflict with real email notifications
    327         StyleSpan bold = new StyleSpan(Typeface.BOLD);
    328         SpannableString line1 = new SpannableString("Alice: hey there!");
    329         line1.setSpan(bold, 0, 5, 0);
    330         SpannableString line2 = new SpannableString("Bob: hi there!");
    331         line2.setSpan(bold, 0, 3, 0);
    332         SpannableString line3 = new SpannableString("Charlie: Iz IN UR EMAILZ!!");
    333         line3.setSpan(bold, 0, 7, 0);
    334         mNotifications.add(new NotificationCompat.InboxStyle(
    335                 new NotificationCompat.Builder(this)
    336                 .setContentTitle("24 new messages")
    337                 .setContentText("You have mail!")
    338                 .setSubText("test.hugo2 (at) gmail.com")
    339                 .setContentIntent(makeToastIntent(this, "Clicked on Email"))
    340                 .setSmallIcon(R.drawable.stat_notify_email))
    341            .setSummaryText("+21 more")
    342            .addLine(line1)
    343            .addLine(line2)
    344            .addLine(line3)
    345            .build());
    346 
    347         mNotifications.add(new NotificationCompat.Builder(this)
    348         .setContentTitle("Twitter")
    349         .setContentText("New mentions")
    350         .setContentIntent(makeToastIntent(this, "Clicked on Twitter"))
    351         .setSmallIcon(R.drawable.twitter_icon)
    352         .setNumber(15)
    353         .setPriority(NotificationCompat.PRIORITY_LOW)
    354         .build());
    355 
    356         if (FIRE_AND_FORGET) {
    357             doPost(null);
    358             startProgressUpdater(this, 10, uploadId, uploadWhen);
    359             finish();
    360         }
    361     }
    362 
    363     public void doPost(View v) {
    364         for (int i=0; i<mNotifications.size(); i++) {
    365             mNoMa.notify(NOTIFICATION_ID + i, mNotifications.get(i));
    366         }
    367     }
    368 
    369     public void doRemove(View v) {
    370         for (int i=0; i<mNotifications.size(); i++) {
    371             mNoMa.cancel(NOTIFICATION_ID + i);
    372         }
    373     }
    374 }
    375