Monday, April 14, 2014

Notifications Part 1: Introduction

One of the most useful techniques for any developer's mobile toolkit is building notifications. They allow you to quickly get information to your user, bring them into your app, provide controls for media and do a variety of other pretty cool things. They are also the basis for interacting with the new Google Wear hardware. The first part of my notification posts will go over the basics of using the NotificationCompat builder, which is compatible back to Android v4, to display a notification in the status drawer, enable vibrations, show icons and fire an intent to open a specified activity. As with the other posts, all source code for this project can be found on GitHub.

First and foremost, the demo project that I made allows the user to populate different information and enable different features in a notification, as seen here:


The title, content text, subtext and content info are straight forward and demonstrated here:


 and the ticker text is the text that is displayed in the status bar when the notification comes in:


Notifications are created using the builder pattern with NotificationCombat.Builder. Each characteristic is then added to the notification through a series of functions, followed by returning the built notification to the NotificationManager. An example notification can be built as simply as this:

NotificationCompat.Builder builder = new NotificationCompat.Builder( this );
builder.setContentTitle(getString(R.string.app_name));
builder.setContentText(mNotificationTextEditText.getText());
builder.setSmallIcon( R.drawable.ic_launcher );
NotificationManager manager = 
(NotificationManager) getSystemService( Context.NOTIFICATION_SERVICE );
manager.notify( 1, builder.build() );

where the '1' in the notify function is an int that can be incremented to stack notifications, or use the same number to replace any currently active notifications from your activity.


When only the small icon is set, it fills the roll of the large icon on the left. If both the large and small image are defined, then the large image is the left image, and the image next to the content info is the small image. 

Notification sounds can be triggered using the builder.setSound method. Unless you have a compelling reason, you should use the notification sound defined by the user if your notification is to be audible.

builder.setSound( RingtoneManager.getDefaultUri( RingtoneManager.TYPE_NOTIFICATION ) );

Vibrations can also be set for the notification using the builder.setVibrate method. This method takes an array of longs where every even index is the number of milliseconds that the device should not vibrate, and every odd index is the number of milliseconds that the device should vibrate. In the demo, the notification will vibrate for half of a second, pause for a quarter of a second, and then vibrate a second time for half of a second. The 0 at index 0 means that the vibration will start as soon as the notification is received, rather than waiting.

builder.setSound( RingtoneManager.getDefaultUri( RingtoneManager.TYPE_NOTIFICATION ) );

One of the more useful features of Android notifications is that they can be set with an intent that allows the user to open an activity on click, and then the notification can be cleared from the notification drawer.

Intent intent = new Intent( this, MainActivity.class );
TaskStackBuilder stackBuilder = TaskStackBuilder.create( this );
stackBuilder.addNextIntent( intent );
PendingIntent resultIntent =  
        stackBuilder.getPendingIntent(0, PendingIntent.FLAG_UPDATE_CURRENT);
builder.setContentIntent( resultIntent );
builder.setAutoCancel( true );

The time section of the notification can be overwritten to count the time since the notification posted by using the builder.setUsesChronometer method.


The last feature I want to go over that comes with basic notifications is the ability to use some predefined styles. In the demo project, I apply the Big Picture style and apply an image for the picture area

NotificationCompat.BigPictureStyle style = new NotificationCompat.BigPictureStyle();
style.bigPicture(BitmapFactory.decodeResource(this.getResources(), R.drawable.ic_launcher));
builder.setStyle(style);

This creates a notification that contains a large image under all of the standard information:


Aside from the basic features that I have just gone over, notifications allow for custom views that can contain items, such as buttons, to perform special actions. They can also be used with the new Google Wear hardware. I plan to go over these features in a later post, as notifications are one of the most powerful tools in the Android SDK.