Creating a Notification

To build handheld notifications that are also sent to wearables, use NotificationCompat.Builder. When you build notifications with this class, the system takes care of displaying notifications properly, whether they appear on a handheld or wearable.

Note: Notifications using RemoteViews are stripped of custom layouts and the wearable only displays the text and icons. However, you can create create custom notifications that use custom card layouts by creating a wearable app that runs on the wearable device.

Import the necessary classes

To import the necessary packages, add this line to your build.gradlefile:

compile "com.android.support:support-v4:20.0.+"

Now that your project has access to the necessary packages, import the necessary classes from the support library:

import android.support.v4.app.NotificationCompat;
import android.support.v4.app.NotificationManagerCompat;
import android.support.v4.app.NotificationCompat.WearableExtender;

Create Notifications with the Notification Builder

The v4 support library allows you to create notifications using the latest notification features such as action buttons and large icons, while remaining compatible with Android 1.6 (API level 4) and higher.

To create a notification with the support library, you create an instance of NotificationCompat.Builder and issue the notification by passing it to notify(). For example:

int notificationId = 001;
// Build intent for notification content
Intent viewIntent = new Intent(this, ViewEventActivity.class);
viewIntent.putExtra(EXTRA_EVENT_ID, eventId);
PendingIntent viewPendingIntent =
        PendingIntent.getActivity(this, 0, viewIntent, 0);

NotificationCompat.Builder notificationBuilder =
        new NotificationCompat.Builder(this)
        .setSmallIcon(R.drawable.ic_event)
        .setContentTitle(eventTitle)
        .setContentText(eventLocation)
        .setContentIntent(viewPendingIntent);

// Get an instance of the NotificationManager service
NotificationManagerCompat notificationManager =
        NotificationManagerCompat.from(this);

// Build the notification and issues it with notification manager.
notificationManager.notify(notificationId, notificationBuilder.build());

When this notification appears on a handheld device, the user can invoke the PendingIntent specified by the setContentIntent() method by touching the notification. When this notification appears on an Android wearable, the user can swipe the notification to the left to reveal the Open action, which invokes the intent on the handheld device.

Add Action Buttons

In addition to the primary content action defined by setContentIntent(), you can add other actions by passing a PendingIntent to the addAction() method.

For example, the following code shows the same type of notification from above, but adds an action to view the event location on a map.

// Build an intent for an action to view a map
Intent mapIntent = new Intent(Intent.ACTION_VIEW);
Uri geoUri = Uri.parse("geo:0,0?q=" + Uri.encode(location));
mapIntent.setData(geoUri);
PendingIntent mapPendingIntent =
        PendingIntent.getActivity(this, 0, mapIntent, 0);

NotificationCompat.Builder notificationBuilder =
        new NotificationCompat.Builder(this)
        .setSmallIcon(R.drawable.ic_event)
        .setContentTitle(eventTitle)
        .setContentText(eventLocation)
        .setContentIntent(viewPendingIntent)
        .addAction(R.drawable.ic_map,
                getString(R.string.map), mapPendingIntent);

On a handheld, the action appears as an additional button attached to the notification. On a wearable, the action appears as a large button when the user swipes the notification to the left. When the user taps the action, the associated intent is invoked on the handheld.

Tip: If your notifications include a "Reply" action (such as for a messaging app), you can enhance the behavior by enabling voice input replies directly from the Android wearable. For more information, read Receiving Voice Input from a Notification.

Specify Wearable-only Actions

If you want the actions available on the wearable to be different from those on the handheld, then use WearableExtender.addAction(). Once you add an action with this method, the wearable does not display any other actions added with NotificationCompat.Builder.addAction(). That is, only the actions added with WearableExtender.addAction() appear on the wearable and they do not appear on the handheld.

// Create an intent for the reply action
Intent actionIntent = new Intent(this, ActionActivity.class);
PendingIntent actionPendingIntent =
        PendingIntent.getActivity(this, 0, actionIntent,
                PendingIntent.FLAG_UPDATE_CURRENT);

// Create the action
NotificationCompat.Action action =
        new NotificationCompat.Action.Builder(R.drawable.ic_action,
                getString(R.string.label, actionPendingIntent))
                .build();

// Build the notification and add the action via WearableExtender
Notification notification =
        new NotificationCompat.Builder(mContext)
                .setSmallIcon(R.drawable.ic_message)
                .setContentTitle(getString(R.string.title))
                .setContentText(getString(R.string.content))
                .extend(new WearableExtender().addAction(action))
                .build();

Add a Big View

You can insert extended text content to your notification by adding one of the "big view" styles to your notification. On a handheld device, users can see the big view content by expanding the notification. On a wearable device, the big view content is visible by default.

To add the extended content to your notification, call setStyle() on the NotificationCompat.Builder object, passing it an instance of either BigTextStyle or InboxStyle.

For example, the following code adds an instance of NotificationCompat.BigTextStyle to the event notification, in order to include the complete event description (which includes more text than can fit into the space provided for setContentText()).

// Specify the 'big view' content to display the long
// event description that may not fit the normal content text.
BigTextStyle bigStyle = new NotificationCompat.BigTextStyle();
bigStyle.bigText(eventDescription);

NotificationCompat.Builder notificationBuilder =
        new NotificationCompat.Builder(this)
        .setSmallIcon(R.drawable.ic_event)
        .setLargeIcon(BitmapFactory.decodeResource(
                getResources(), R.drawable.notif_background))
        .setContentTitle(eventTitle)
        .setContentText(eventLocation)
        .setContentIntent(viewPendingIntent)
        .addAction(R.drawable.ic_map,
                getString(R.string.map), mapPendingIntent)
        .setStyle(bigStyle);

Notice that you can add a large background image to any notification using the setLargeIcon() method. For more information about designing notifications with large images, see the Design Principles of Android Wear.

Add Wearable Features For a Notification

If you ever need to add wearable-specific options to a notification, such as specifying additional pages of content or letting users dictate a text response with voice input, you can use the NotificationCompat.WearableExtender class to specify the options. To use this API:

  1. Create an instance of a WearableExtender, setting the wearable-specific options for the notication.
  2. Create an instance of NotificationCompat.Builder, setting the desired properties for your notification as described earlier in this lesson.
  3. Call extend() on the notification and pass in the WearableExtender. This applies the wearable options to the notification.
  4. Call build() to build the notification.

For example, the following code calls the setHintHideIcon() method to remove the app icon from the notification card.

// Create a WearableExtender to add functionality for wearables
NotificationCompat.WearableExtender wearableExtender =
        new NotificationCompat.WearableExtender()
        .setHintHideIcon(true);

// Create a NotificationCompat.Builder to build a standard notification
// then extend it with the WearableExtender
Notification notif = new NotificationCompat.Builder(mContext)
        .setContentTitle("New mail from " + sender)
        .setContentText(subject)
        .setSmallIcon(R.drawable.new_mail);
        .extend(wearableExtender)
        .build();

The setHintHideIcon() method is just one example of new notification features available with NotificationCompat.WearableExtender.

If you ever need to read wearable-specifc options at a later time, use the corresponding get method for the option. This example calls the getHintHideIcon() method to get whether or not this notification hides the icon:

NotificationCompat.WearableExtender wearableExtender =
        new NotificationCompat.WearableExtender(notif);
boolean hintHideIcon = wearableExtender.getHintHideIcon();

Deliver the Notification

When you want to deliver your notifications, always use the NotificationManagerCompat API instead of NotificationManager:

// Get an instance of the NotificationManager service
NotificationManagerCompat notificationManager =
        NotificationManagerCompat.from(mContext);

// Issue the notification with notification manager.
notificationManager.notify(notificationId, notif);

If you use the framework's NotificationManager, some features from NotificationCompat.WearableExtender do not work, so make sure to use NotificationCompat.

NotificationCompat.WearableExtender wearableExtender =
        new NotificationCompat.WearableExtender(notif);
boolean hintHideIcon = wearableExtender.getHintHideIcon();
 

The NotificationCompat.WearableExtender APIs allow you to add additional pages to notifications, stack notifications, and more. Continue to the following lessons to learn about these features.