Adding notifications to your application

Notifications are great for popping up an alert for the user or providing quick access to either a long running request or an activity that seems like it is long running.

Before I start, a great resource is the Android developer site itself, which I won't rehash much here. I will include some code that you can use as a template to get a running notification with different features.

First, call the getSystemService(NotificationService) on your context or activity to get a handle to the NotificationService.

Next, build your notification by instantiating a Notification object or by using it's Builder.

Finally, call the notify method on your NotificationManager handle.

It's as easy as that. Well, almost.

Here's some template code:

NotificationManager nm = (NotificationManager) getSystemService(this); Notification n = new Notification(R.drawable.myNotificationIcon, "My Ticker Text", System.getTimeInMillis(); Intent i = new Intent(this, MyActivity.class); PendingIntent pi = PendingIntent.getActivity(this, 0, i, Intent.FLAG_ACTIVITY_NEW_TASK); n.setLatestEventInfo(getApplicationContext(), "My Title", "My Notification Text", pi); nm.notify(MY_NOTIFICATION_ID, n);

Line 1 is fairly obvious. This gets our handle to the NotificationManager.

Line 2 instantiates our notification object. The icon will the icon shown in the status bar. The "ticker text" is the text that appears over top of the status bar when the notification is shown. The time field is the time that appears in the notification and can indicate the time of the event. Use 0 to not show a time.

Line 3 creates an intent that will be fired when the user selects your notification from the notifications window, not the status bar. Usually you'll just want this to fire an Activity in your application, likely something to do with the event (if it's an event).

Line 4 creates the PendingIntent, which in Google's terms is a description of an intent and action to perform with it. Make sure to check out the flags in the API docs depending on what you're doing. The flag I've used for example will clear the stack and place the new activity on top.

Line 5 puts most of it together. The method setLatestEventInfo, which may be called multiple times in your app if you have to update the notification text, sets the contents of your notification. I've associated the context with the application context so it doesn't hold a reference to our activity once it's gone. The other fields are simply the title and the text of the notification which appear in the window, and the PendingIntent which tells the notification what to do when selected.

Line 6 is where our notification is actually sent out and appears on the status bar. You will have a unique id that references that particular notification, which you can use later to either cancel the notification programatically, or update the text if more events happen, such as more email or text messages arrive.

For some reason, I struggled with getting notifications to generate a sound or vibrate at first. Reading the documentation, I didn't catch that you set the DEFAULT_SOUND or DEFAULT_VIBRATE flags to the property "defaults" and not to flags. It's obvious now and perhaps I just read the docs too fast, but it threw me at first until I looked into the code and realized my mistake. Either way, it provided experience in using custom sounds. In the following example, I used a URI referencing the default sound, but you can use any URI here. Set the INSISTENT flag, and it will keep repeating until the user pulls down the notification window.

Uri defaultURI = RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION); n.sound = defaultURI; long[] vibratePattern = {0, 400}; n.vibrate = vibratePattern;

The vibrate pattern is just pairs of longs that indicate how long to wait to vibrate and how long to vibrate for. If you had { 0, 100, 100, 100} instead, this would give you two quick buzzes. Apparently, there is no coded limit to the length of the array, so have fun with that!

If you're setting flags, the syntax is fairly simple too. Just use something like the following:

n.flags |= Notification.FLAG_ONGOING_EVENT;

And of course, lights gave me a bit of trouble right away too. Using the FLAG_SHOW_LIGHTS flag and setting the values of ledOnMS and ledOffMS didn't work as well, nor using the DEFAULT_LIGHTS flag by itself. Doing some reading, it looks like light notifications only show up on my Nexus One when the screen is off, at least with 2.3.3. I'll have to find out if that's consistent with older phones.