| page.title=Notifications |
| @jd:body |
| |
| <div id="qv-wrapper"> |
| <div id="qv"> |
| <h2>In this document</h2> |
| <ol> |
| <li><a href="#Design">Design Considerations</a></li> |
| <li><a href="#CreateNotification">Creating a Notification</a> |
| <ol> |
| <li><a href="#Required">Required notification contents</a></li> |
| <li><a href="#Optional">Optional notification contents and settings</a></li> |
| <li><a href="#Actions">Notification actions</a></li> |
| <li><a href="#Priority">Notification priority</a></li> |
| <li><a href="#SimpleNotification">Creating a simple notification</a></li> |
| <li><a href="#ApplyStyle">Applying an expanded layout to a notification</a></li> |
| <li><a href="#Compatibility">Handling compatibility</a></li> |
| </ol> |
| </li> |
| <li><a href="#Managing">Managing Notifications</a> |
| <ol> |
| <li><a href="#Updating">Updating notifications</a></li> |
| <li><a href="#Removing">Removing notifications</a></li> |
| <li><a href="#direct">Replying to notifications</a></li> |
| <li><a href="#bundle">Bundling notifications</a></li> |
| </ol> |
| </li> |
| <li><a href="#NotificationResponse">Preserving Navigation when Starting an Activity</a> |
| <ol> |
| <li><a href="#DirectEntry">Setting up a regular activity PendingIntent</a></li> |
| <li><a href="#ExtendedNotification">Setting up a special activity PendingIntent</a></li> |
| </ol> |
| </li> |
| <li><a href="#Progress">Displaying Progress in a Notification</a> |
| <ol> |
| <li><a href="#FixedProgress">Displaying a fixed-duration progress indicator</a></li> |
| <li><a href="#ActivityIndicator">Displaying a continuing activity indicator</a></li> |
| </ol> |
| </li> |
| <li><a href="#metadata">Notification Metadata</a></li> |
| <li><a href="#Heads-up">Heads-up Notifications</a></li> |
| <li><a href="#lockscreenNotification">Lock Screen Notifications</a> |
| <ol> |
| <li><a href="#visibility">Setting Visibility</a></li> |
| <li><a href="#controllingMedia">Controlling Media Playback on the Lock Screen</a></li> |
| </ol> |
| </li> |
| <li><a href="#CustomNotification">Customizing Notifications</a> |
| <ol> |
| <li><a href="#custom">Custom Views</a></li> |
| <li><a href="#style">Messaging Style</a></li> |
| </ol> |
| </li> |
| </ol> |
| |
| <h2>Key classes</h2> |
| <ol> |
| <li>{@link android.app.NotificationManager}</li> |
| <li>{@link android.support.v4.app.NotificationCompat}</li> |
| </ol> |
| <h2>Videos</h2> |
| <ol> |
| <li> |
| <a href="http://www.youtube.com/watch?v=Yc8YrVc47TI&feature=player_detailpage#t=1672s"> |
| Notifications in 4.1</a> |
| </li> |
| </ol> |
| <h2>See also</h2> |
| <ol> |
| <li> |
| <a href="https://material.google.com/patterns/notifications.html">Material Design: Notifications</a> |
| </li> |
| </ol> |
| </div> |
| </div> |
| <p> |
| A notification is a message you can display to the user outside of your application's |
| normal UI. When you tell the system to issue a notification, it first appears as an icon in the |
| <strong>notification area</strong>. To see the details of the notification, the user opens the |
| <strong>notification drawer</strong>. Both the notification area and the notification drawer |
| are system-controlled areas that the user can view at any time. |
| </p> |
| <img |
| id="figure1" |
| src="{@docRoot}images/ui/notifications/notification_area.png" |
| height="" alt="" /> |
| <p class="img-caption"> |
| <strong>Figure 1.</strong> Notifications in the notification area. |
| </p> |
| <img id="figure2" src="{@docRoot}images/ui/notifications/notification_drawer.png" |
| width="280px" alt="" /> |
| <p class="img-caption"> |
| <strong>Figure 2.</strong> Notifications in the notification drawer. |
| </p> |
| |
| <p class="note"><strong>Note:</strong> Except where noted, this guide refers to the |
| {@link android.support.v4.app.NotificationCompat.Builder NotificationCompat.Builder} class |
| in the version 4 <a href="{@docRoot}tools/support-library/index.html">Support Library</a>. |
| The class {@link android.app.Notification.Builder Notification.Builder} was added in Android |
| 3.0 (API level 11).</p> |
| |
| <h2 id="Design">Design Considerations</h2> |
| |
| <p>Notifications, as an important part of the Android user interface, have their own design guidelines. |
| The material design changes introduced in Android 5.0 (API level 21) are of particular |
| importance, and you should review the <a href="{@docRoot}training/material/index.html">Material |
| Design</a> training for more information. To learn how to design notifications and their interactions, |
| read the <a href="https://material.google.com/patterns/notifications.html">Notifications</a> design guide.</p> |
| |
| <h2 id="CreateNotification">Creating a Notification</h2> |
| |
| <p>You specify the UI information and actions for a notification in a |
| {@link android.support.v4.app.NotificationCompat.Builder NotificationCompat.Builder} object. |
| To create the notification itself, you call |
| {@link android.support.v4.app.NotificationCompat.Builder#build NotificationCompat.Builder.build()}, |
| which returns a {@link android.app.Notification} object containing your specifications. To issue the |
| notification, you pass the {@link android.app.Notification} object to the system by calling |
| {@link android.app.NotificationManager#notify(int, android.app.Notification) NotificationManager.notify()}.</p> |
| |
| <h3 id="Required">Required notification contents</h3> |
| <p> |
| A {@link android.app.Notification} object <em>must</em> contain the following: |
| </p> |
| <ul> |
| <li> |
| A small icon, set by |
| {@link android.support.v4.app.NotificationCompat.Builder#setSmallIcon setSmallIcon()} |
| </li> |
| <li> |
| A title, set by |
| {@link android.support.v4.app.NotificationCompat.Builder#setContentTitle setContentTitle()} |
| </li> |
| <li> |
| Detail text, set by |
| {@link android.support.v4.app.NotificationCompat.Builder#setContentText setContentText()} |
| </li> |
| </ul> |
| <h3 id="Optional">Optional notification contents and settings</h3> |
| <p> |
| All other notification settings and contents are optional. To learn more about them, |
| see the reference documentation for {@link android.support.v4.app.NotificationCompat.Builder}. |
| </p> |
| <!-- ------------------------------------------------------------------------------------------ --> |
| <h3 id="Actions">Notification actions</h3> |
| <p> |
| Although they're optional, you should add at least one action to your notification. |
| An action allows users to go directly from the notification to an |
| {@link android.app.Activity} in your application, where they can look at one or more events |
| or do further work. |
| </p> |
| <p> |
| A notification can provide multiple actions. You should always define the action that's |
| triggered when the user clicks the notification; usually this action opens an |
| {@link android.app.Activity} in your application. You can also add buttons to the notification |
| that perform additional actions such as snoozing an alarm or responding immediately to a text |
| message; this feature is available as of Android 4.1. If you use additional action buttons, you |
| must also make their functionality available in an {@link android.app.Activity} in your app; see |
| the section <a href="#Compatibility">Handling compatibility</a> for more details. |
| </p> |
| <p> |
| Inside a {@link android.app.Notification}, the action itself is defined by a |
| {@link android.app.PendingIntent} containing an |
| {@link android.content.Intent} that starts |
| an {@link android.app.Activity} in your application. To associate the |
| {@link android.app.PendingIntent} with a gesture, call the appropriate method of |
| {@link android.support.v4.app.NotificationCompat.Builder}. For example, if you want to start |
| {@link android.app.Activity} when the user clicks the notification text in |
| the notification drawer, you add the {@link android.app.PendingIntent} by calling |
| {@link android.support.v4.app.NotificationCompat.Builder#setContentIntent setContentIntent()}. |
| </p> |
| <p> |
| Starting an {@link android.app.Activity} when the user clicks the notification is the most |
| common action scenario. You can also start an {@link android.app.Activity} when the user |
| dismisses a notification. In Android 4.1 and later, you can start an |
| {@link android.app.Activity} from an action button. To learn more, read the reference guide for |
| {@link android.support.v4.app.NotificationCompat.Builder}. |
| </p> |
| <!-- ------------------------------------------------------------------------------------------ --> |
| <h3 id="Priority">Notification priority</h3> |
| <p> |
| If you wish, you can set the priority of a notification. The priority acts |
| as a hint to the device UI about how the notification should be displayed. |
| To set a notification's priority, call {@link |
| android.support.v4.app.NotificationCompat.Builder#setPriority(int) |
| NotificationCompat.Builder.setPriority()} and pass in one of the {@link |
| android.support.v4.app.NotificationCompat} priority constants. There are |
| five priority levels, ranging from {@link |
| android.support.v4.app.NotificationCompat#PRIORITY_MIN} (-2) to {@link |
| android.support.v4.app.NotificationCompat#PRIORITY_MAX} (2); if not set, the |
| priority defaults to {@link |
| android.support.v4.app.NotificationCompat#PRIORITY_DEFAULT} (0). |
| </p> |
| <p> For information about setting an appropriate priority level, see "Correctly |
| set and manage notification priority" in the <a |
| href="https://material.google.com/patterns/notifications.html">Notifications</a> Design |
| guide. |
| </p> |
| <!-- ------------------------------------------------------------------------------------------ --> |
| <h3 id="SimpleNotification">Creating a simple notification</h3> |
| <p> |
| The following snippet illustrates a simple notification that specifies an activity to open when |
| the user clicks the notification. Notice that the code creates a |
| {@link android.support.v4.app.TaskStackBuilder} object and uses it to create the |
| {@link android.app.PendingIntent} for the action. This pattern is explained in more detail |
| in the section <a href="#NotificationResponse"> |
| Preserving Navigation when Starting an Activity</a>: |
| </p> |
| <pre> |
| NotificationCompat.Builder mBuilder = |
| new NotificationCompat.Builder(this) |
| .setSmallIcon(R.drawable.notification_icon) |
| .setContentTitle("My notification") |
| .setContentText("Hello World!"); |
| // Creates an explicit intent for an Activity in your app |
| Intent resultIntent = new Intent(this, ResultActivity.class); |
| |
| // The stack builder object will contain an artificial back stack for the |
| // started Activity. |
| // This ensures that navigating backward from the Activity leads out of |
| // your application to the Home screen. |
| TaskStackBuilder stackBuilder = TaskStackBuilder.create(this); |
| // Adds the back stack for the Intent (but not the Intent itself) |
| stackBuilder.addParentStack(ResultActivity.class); |
| // Adds the Intent that starts the Activity to the top of the stack |
| stackBuilder.addNextIntent(resultIntent); |
| PendingIntent resultPendingIntent = |
| stackBuilder.getPendingIntent( |
| 0, |
| PendingIntent.FLAG_UPDATE_CURRENT |
| ); |
| mBuilder.setContentIntent(resultPendingIntent); |
| NotificationManager mNotificationManager = |
| (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE); |
| // mId allows you to update the notification later on. |
| mNotificationManager.notify(mId, mBuilder.build()); |
| </pre> |
| <p>That's it. Your user has now been notified.</p> |
| <!-- ------------------------------------------------------------------------------------------ --> |
| <h3 id="ApplyStyle">Applying an expanded layout to a notification</h3> |
| <p> |
| To have a notification appear in an expanded view, first create a |
| {@link android.support.v4.app.NotificationCompat.Builder} object with the normal view options |
| you want. Next, call {@link android.support.v4.app.NotificationCompat.Builder#setStyle |
| Builder.setStyle()} with an expanded layout object as its argument. |
| </p> |
| <p> |
| Remember that expanded notifications are not available on platforms prior to Android 4.1. To |
| learn how to handle notifications for Android 4.1 and for earlier platforms, read the |
| section <a href="#Compatibility">Handling compatibility</a>. |
| </p> |
| <p> |
| For example, the following code snippet demonstrates how to alter the notification created |
| in the previous snippet to use the expanded layout: |
| </p> |
| <pre> |
| NotificationCompat.Builder mBuilder = new NotificationCompat.Builder(this) |
| .setSmallIcon(R.drawable.notification_icon) |
| .setContentTitle("Event tracker") |
| .setContentText("Events received") |
| NotificationCompat.InboxStyle inboxStyle = |
| new NotificationCompat.InboxStyle(); |
| String[] events = new String[6]; |
| // Sets a title for the Inbox in expanded layout |
| inboxStyle.setBigContentTitle("Event tracker details:"); |
| ... |
| // Moves events into the expanded layout |
| for (int i=0; i < events.length; i++) { |
| |
| inboxStyle.addLine(events[i]); |
| } |
| // Moves the expanded layout object into the notification object. |
| mBuilder.setStyle(inBoxStyle); |
| ... |
| // Issue the notification here. |
| </pre> |
| |
| <h3 id="Compatibility">Handling compatibility</h3> |
| |
| <p> |
| Not all notification features are available for a particular version, even though |
| the methods to set them are in the support library class |
| {@link android.support.v4.app.NotificationCompat.Builder NotificationCompat.Builder}. |
| For example, action buttons, which depend on expanded notifications, only appear on Android |
| 4.1 and higher, because expanded notifications themselves are only available on |
| Android 4.1 and higher. |
| </p> |
| <p> |
| To ensure the best compatibility, create notifications with |
| {@link android.support.v4.app.NotificationCompat NotificationCompat} and its subclasses, |
| particularly {@link android.support.v4.app.NotificationCompat.Builder |
| NotificationCompat.Builder}. In addition, follow this process when you implement a notification: |
| </p> |
| <ol> |
| <li> |
| Provide all of the notification's functionality to all users, regardless of the version |
| they're using. To do this, verify that all of the functionality is available from an |
| {@link android.app.Activity} in your app. You may want to add a new |
| {@link android.app.Activity} to do this. |
| <p> |
| For example, if you want to use |
| {@link android.support.v4.app.NotificationCompat.Builder#addAction addAction()} to |
| provide a control that stops and starts media playback, first implement this |
| control in an {@link android.app.Activity} in your app. |
| </p> |
| </li> |
| <li> |
| Ensure that all users can get to the functionality in the {@link android.app.Activity}, |
| by having it start when users click the notification. To do this, |
| create a {@link android.app.PendingIntent} |
| for the {@link android.app.Activity}. Call |
| {@link android.support.v4.app.NotificationCompat.Builder#setContentIntent |
| setContentIntent()} to add the {@link android.app.PendingIntent} to the notification. |
| </li> |
| <li> |
| Now add the expanded notification features you want to use to the notification. Remember |
| that any functionality you add also has to be available in the {@link android.app.Activity} |
| that starts when users click the notification. |
| </li> |
| </ol> |
| |
| |
| <!-- ------------------------------------------------------------------------------------------ --> |
| <!-- ------------------------------------------------------------------------------------------ --> |
| <h2 id="Managing">Managing Notifications</h2> |
| <p> |
| When you need to issue a notification multiple times for the same type of event, you |
| should avoid making a completely new notification. Instead, you should consider updating a |
| previous notification, either by changing some of its values or by adding to it, or both. |
| </p> |
| <p> |
| For example, Gmail notifies the user that new emails have arrived by increasing its count of |
| unread messages and by adding a summary of each email to the notification. This is called |
| "stacking" the notification; it's described in more detail in the |
| <a href="https://material.google.com/patterns/notifications.html">Notifications</a> Design guide. |
| </p> |
| <p class="note"> |
| <strong>Note:</strong> This Gmail feature requires the "inbox" expanded layout, which is part |
| of the expanded notification feature. |
| </p> |
| <p> |
| The following section describes how to update notifications and also how to remove them. |
| </p> |
| <h3 id="Updating">Updating notifications</h3> |
| <p> |
| To set up a notification so it can be updated, issue it with a notification ID by |
| calling {@link android.app.NotificationManager#notify(int, android.app.Notification) NotificationManager.notify()}. |
| To update this notification once you've issued |
| it, update or create a {@link android.support.v4.app.NotificationCompat.Builder} object, |
| build a {@link android.app.Notification} object from it, and issue the |
| {@link android.app.Notification} with the same ID you used previously. If |
| the previous notification is still visible, the system updates it from the contents of |
| the {@link android.app.Notification} object. If the previous notification has been dismissed, a |
| new notification is created instead. |
| </p> |
| <p> |
| The following snippet demonstrates a notification that is updated to reflect the |
| number of events that have occurred. It stacks the notification, showing a summary: |
| </p> |
| <pre> |
| mNotificationManager = |
| (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE); |
| // Sets an ID for the notification, so it can be updated |
| int notifyID = 1; |
| mNotifyBuilder = new NotificationCompat.Builder(this) |
| .setContentTitle("New Message") |
| .setContentText("You've received new messages.") |
| .setSmallIcon(R.drawable.ic_notify_status) |
| numMessages = 0; |
| // Start of a loop that processes data and then notifies the user |
| ... |
| mNotifyBuilder.setContentText(currentText) |
| .setNumber(++numMessages); |
| // Because the ID remains unchanged, the existing notification is |
| // updated. |
| mNotificationManager.notify( |
| notifyID, |
| mNotifyBuilder.build()); |
| ... |
| </pre> |
| |
| <!-- ------------------------------------------------------------------------------------------ --> |
| <h3 id="Removing">Removing notifications</h3> |
| <p> |
| Notifications remain visible until one of the following happens: |
| </p> |
| <ul> |
| <li> |
| The user dismisses the notification either individually or by using "Clear All" (if |
| the notification can be cleared). |
| </li> |
| <li> |
| The user clicks the notification, and you called |
| {@link android.support.v4.app.NotificationCompat.Builder#setAutoCancel setAutoCancel()} when |
| you created the notification. |
| </li> |
| <li> |
| You call {@link android.app.NotificationManager#cancel(int) cancel()} for a specific |
| notification ID. This method also deletes ongoing notifications. |
| </li> |
| <li> |
| You call {@link android.app.NotificationManager#cancelAll() cancelAll()}, which removes |
| all of the notifications you previously issued. |
| </li> |
| </ul> |
| |
| <!--------------------------------------------------------------- --> |
| <h2 id="direct">Replying to notifications</h2> |
| |
| <p> |
| Starting in Android 7.0 (API level 24), |
| users can respond directly to text messages or update task lists |
| from within the notification |
| dialog. On a handheld, the inline reply action appears as an additional |
| button |
| displayed in the notification. When a user replies via keyboard, the system |
| attaches the text response to the intent |
| you had specified for the notification action and sends the intent to your |
| handheld app. |
| </p> |
| |
| <img id="fig-reply-button" src="{@docRoot}images/android-7.0/inline-reply.png" |
| srcset="{@docRoot}images/android-7.0/inline-reply.png 1x, |
| {@docRoot}images/android-7.0/inline-reply_2x.png 2x" |
| width="400"> |
| <p class="img-caption"> |
| <strong>Figure 1.</strong> The <strong>Reply</strong> action button. |
| </p> |
| |
| <h3>Adding inline reply actions</h3> |
| |
| <p>To create a notification action that supports direct reply: |
| </p> |
| |
| <ol> |
| <li>Create an instance of {@link android.support.v4.app.RemoteInput.Builder} |
| that you can add to your notification |
| action. This class's constructor accepts a string that the system uses as the key |
| for the text input. Later, your handheld app uses that key to retrieve the text |
| of the input. |
| |
| <pre> |
| // Key for the string that's delivered in the action's intent. |
| private static final String KEY_TEXT_REPLY = "key_text_reply"; |
| String replyLabel = getResources().getString(R.string.reply_label); |
| RemoteInput remoteInput = new RemoteInput.Builder(KEY_TEXT_REPLY) |
| .setLabel(replyLabel) |
| .build(); |
| </pre> |
| </li> |
| <li>Attach the {@link android.support.v4.app.RemoteInput} |
| object to an action using <code>addRemoteInput()</code>. |
| |
| <pre> |
| // Create the reply action and add the remote input. |
| Notification.Action action = |
| new Notification.Action.Builder(R.drawable.ic_reply_icon, |
| getString(R.string.label), replyPendingIntent) |
| .addRemoteInput(remoteInput) |
| .build(); |
| </pre> |
| </li> |
| |
| <li>Apply the action to a notification and issue the notification. |
| |
| <pre> |
| // Build the notification and add the action. |
| Notification newMessageNotification = |
| new Notification.Builder(mContext) |
| .setSmallIcon(R.drawable.ic_message) |
| .setContentTitle(getString(R.string.title)) |
| .setContentText(getString(R.string.content)) |
| .addAction(action)) |
| .build(); |
| |
| // Issue the notification. |
| NotificationManager notificationManager = |
| NotificationManager.from(mContext); |
| notificationManager.notify(notificationId, newMessageNotification); |
| |
| </pre> |
| </li> |
| |
| </ol> |
| |
| |
| <p> The system prompts the user to input a response when they trigger the |
| notification action. </p> |
| |
| <img id="fig-user-input" src="{@docRoot}images/android-7.0/inline-type-reply.png" |
| srcset="{@docRoot}images/android-7.0/inline-type-reply.png 1x, |
| {@docRoot}images/android-7.0/inline-type-reply_2x.png 2x" |
| width="300"> |
| <p class="img-caption"> |
| <strong>Figure 2.</strong> The user inputs text from the notification shade. |
| </p> |
| |
| <h3> |
| Retrieving user input from the inline reply |
| </h3> |
| |
| <p> |
| To receive user input from the notification interface to the activity you |
| declared in the reply action's intent: |
| </p> |
| |
| <ol> |
| <li>Call {@link android.support.v4.app.RemoteInput#getResultsFromIntent |
| getResultsFromIntent()} by passing the notification action’s intent as the |
| input parameter. This method returns a {@link android.os.Bundle} that |
| contains the text response. |
| |
| <pre> |
| Bundle remoteInput = RemoteInput.getResultsFromIntent(intent); |
| </pre> |
| </li> |
| |
| <li>Query the bundle using the result key (provided to the {@link |
| android.support.v4.app.RemoteInput.Builder} constructor). You can complete |
| this process and retrieve the input text by creating a method, as in the |
| following code snippet: |
| |
| <pre> |
| // Obtain the intent that started this activity by calling |
| // Activity.getIntent() and pass it into this method to |
| // get the associated string. |
| |
| private CharSequence getMessageText(Intent intent) { |
| Bundle remoteInput = RemoteInput.getResultsFromIntent(intent); |
| if (remoteInput != null) { |
| return remoteInput.getCharSequence(KEY_TEXT_REPLY); |
| } |
| return null; |
| } |
| </pre> |
| </li> |
| |
| <li>Build and issue another notification, using the same notification ID that |
| you provided for the previous notification. The progress indicator |
| disappears from the notification interface to inform users of a successful |
| reply. When working with this new notification, use the context that gets |
| passed to the receiver's {@code onReceive()} method. |
| |
| <pre> |
| // Build a new notification, which informs the user that the system |
| // handled their interaction with the previous notification. |
| Notification repliedNotification = |
| new Notification.Builder(context) |
| .setSmallIcon(R.drawable.ic_message) |
| .setContentText(getString(R.string.replied)) |
| .build(); |
| |
| // Issue the new notification. |
| NotificationManager notificationManager = |
| NotificationManager.from(context); |
| notificationManager.notify(notificationId, repliedNotification); |
| </pre> |
| </li> |
| </ol> |
| |
| <p> |
| For interactive apps, such as chats, you can include additional |
| context when handling retrieved text. For example, these apps could show |
| multiple lines of chat history. When the user responds via {@link |
| android.support.v4.app.RemoteInput}, you can update the reply history |
| using the {@code setRemoteInputHistory()} method. |
| </p> |
| |
| <p> |
| The notification must be either updated or cancelled after the app has |
| received remote input. When the user replies to a remote update |
| using Direct Reply, |
| do not cancel the notification. Instead, update the notification |
| to display the user's reply. |
| For notifications using {@code MessagingStyle}, you should add |
| the reply as the latest message. When using other templates, you can |
| append the user's reply to the remote-input history. |
| </p> |
| |
| <!-------------------------------------------------------------------------- --> |
| |
| <h2 id="bundle">Bundling notifications</h2> |
| |
| <p> |
| Starting in Android 7.0 (API level 24), |
| Android provides developers with a new way to represent |
| a queue of notifications: <i>bundled notifications</i>. This is similar to the |
| <a href="{@docRoot}training/wearables/notifications/stacks.html">Notification |
| Stacks</a> feature in Android Wear. For example, if your app |
| creates notifications |
| for received messages, when more than one message is received, bundle the |
| notifications together as a single group. You can |
| use the {@link android.support.v4.app.NotificationCompat.Builder#setGroup |
| Builder.setGroup()} method to bundle similar notifications.</p> |
| |
| <p> |
| A notification group imposes a hierarchy on the notifications comprising it. |
| At the top of that hierarchy is a parent notification that displays summary |
| information for the group. The user can progressively |
| expand the notification group, and the system shows more information as the |
| user drills deeper. When the user expands the bundle, the system reveals more |
| information for all its child notifications; when the user |
| expands one of those notifications, the system reveals its entire content. |
| </p> |
| |
| <img id="fig-bundles" src="{@docRoot}images/android-7.0/bundles.png" |
| srcset="{@docRoot}images/android-7.0/bundles.png 1x, |
| {@docRoot}images/android-7.0/bundles_2x.png 2x" |
| width="300"> |
| <p class="img-caption"> |
| <strong>Figure 3.</strong> The user can progressively expand the notification |
| group. |
| </p> |
| |
| <p class="note"> |
| <strong>Note:</strong> If the same app sends four or more notifications |
| and does not specify a grouping, the |
| system automatically groups them together. |
| </p> |
| |
| <p>To learn how to add notifications to a group, see |
| <a href="{@docRoot}training/wearables/notifications/stacks.html#AddGroup">Add |
| Each Notification to a Group</a>.</p> |
| |
| |
| <h3 id="best-practices">Best practices for bundled notifications</h3> |
| <p>This section provides guidelines about when to use notification groups instead |
| of the {@link android.app.Notification.InboxStyle InboxStyle} |
| notifications available in Android 6.0 and previous versions.</p> |
| |
| <h3>When to use bundled notifications</h3> |
| |
| <p>You should use notification groups only if all of the following conditions are |
| true for your use case:</p> |
| |
| <ul> |
| <li>The child notifications are complete notifications and can be displayed |
| individually without the need for a group summary.</li> |
| <li>There is a benefit to surfacing the child notifications individually. For |
| example: |
| </li> |
| <ul> |
| <li>They are actionable, with actions specific to each child.</li> |
| <li>There is more information to the child that the user wants to read.</li> |
| </ul> |
| </ul> |
| |
| <p>Examples of good use cases for notification groups include: a messaging app |
| displaying a list of incoming messages, or an email app displaying a list of |
| received emails.</p> |
| |
| <p> |
| Examples of cases where a single notification is preferable |
| include individual messages from a single person, or a list representation of |
| single-line text items. You can use |
| ({@link android.app.Notification.InboxStyle InboxStyle} or |
| {@link android.app.Notification.BigTextStyle BigTextStyle}) to accomplish |
| this. |
| </p> |
| |
| <h3 id ="post">Displaying bundled notifications</h3> |
| |
| <p> |
| The app should always post a group summary, even if the group contains just a |
| single child. The system will suppress the summary and directly display the |
| child notification if it only contains a single notification. This ensures |
| that the system can provide a consistent experience when the user swipes away |
| children of a group. |
| </p> |
| |
| <h3>Peeking notifications</h3> |
| |
| <p>While the system usually displays child notifications as a group, you can set |
| them to temporarily appear as |
| <a href="{@docRoot}guide/topics/ui/notifiers/notifications.html#Heads-up"> |
| heads-up notifications</a>. This feature is especially useful because it allows |
| immediate access to the most recent child and the actions associated with it. |
| </p> |
| |
| |
| <h3>Backwards compatibility</h3> |
| |
| <p> |
| Both notification groups and remote input have been a part of the {@link |
| android.app.Notification} API since Android 5.0 (API level 21) to support |
| Android Wear devices. If you've already built notifications with these APIs, |
| the only action you must take is to verify that the app behavior corresponds |
| to the guidelines described above, and to consider implementing {@code |
| setRemoteInputHistory()}. |
| </p> |
| |
| <p> |
| In order to support backward compatibility, the same APIs are available with |
| the support library's {@link android.support.v4.app.NotificationCompat} |
| class, allowing you to build notifications that works on versions of Android |
| less than 5.0 (API level 21). |
| On handhelds and tablets, users only see the summary notification, |
| so an app should still have an inbox style or an equivalent notification |
| representative for the whole information content of the group. As Android |
| Wear devices allow users to see all child notifications even on older |
| platform levels, you should build child notifications regardless of API |
| level. |
| </p> |
| |
| <!-- ------------------------------------------------------------------------------------------ --> |
| <!-- ------------------------------------------------------------------------------------------ --> |
| <h2 id="NotificationResponse">Preserving Navigation when Starting an Activity</h2> |
| <p> |
| When you start an {@link android.app.Activity} from a notification, you must preserve the |
| user's expected navigation experience. Clicking <i>Back</i> should take the user back through |
| the application's normal work flow to the Home screen, and clicking <i>Recents</i> should show |
| the {@link android.app.Activity} as a separate task. To preserve the navigation experience, you |
| should start the {@link android.app.Activity} in a fresh task. How you set up the |
| {@link android.app.PendingIntent} to give you a fresh task depends on the nature of the |
| {@link android.app.Activity} you're starting. There are two general situations: |
| </p> |
| <dl> |
| <dt> |
| Regular activity |
| </dt> |
| <dd> |
| You're starting an {@link android.app.Activity} that's part of the application's normal |
| workflow. In this situation, set up the {@link android.app.PendingIntent} to |
| start a fresh task, and provide the {@link android.app.PendingIntent} with a back stack |
| that reproduces the application's normal <i>Back</i> behavior. |
| <p> |
| Notifications from the Gmail app demonstrate this. When you click a notification for |
| a single email message, you see the message itself. Touching <b>Back</b> takes you |
| backwards through Gmail to the Home screen, just as if you had entered Gmail from the |
| Home screen rather than entering it from a notification. |
| </p> |
| <p> |
| This happens regardless of the application you were in when you touched the |
| notification. For example, if you're in Gmail composing a message, and you click a |
| notification for a single email, you go immediately to that email. Touching <i>Back</i> |
| takes you to the inbox and then the Home screen, rather than taking you to the |
| message you were composing. |
| </p> |
| </dd> |
| <dt> |
| Special activity |
| </dt> |
| <dd> |
| The user only sees this {@link android.app.Activity} if it's started from a notification. |
| In a sense, the {@link android.app.Activity} extends the notification by providing |
| information that would be hard to display in the notification itself. For this situation, |
| set up the {@link android.app.PendingIntent} to start in a fresh task. There's no need to |
| create a back stack, though, because the started {@link android.app.Activity} isn't part of |
| the application's activity flow. Clicking <i>Back</i> will still take the user to the |
| Home screen. |
| </dd> |
| </dl> |
| <!-- ------------------------------------------------------------------------------------------ --> |
| <h3 id="DirectEntry">Setting up a regular activity PendingIntent</h3> |
| <p> |
| To set up a {@link android.app.PendingIntent} that starts a direct entry |
| {@link android.app.Activity}, follow these steps: |
| </p> |
| <ol> |
| <li> |
| Define your application's {@link android.app.Activity} hierarchy in the manifest. |
| <ol style="list-style-type: lower-alpha;"> |
| <li> |
| Add support for Android 4.0.3 and earlier. To do this, specify the parent of the |
| {@link android.app.Activity} you're starting by adding a |
| <code><a href="{@docRoot}guide/topics/manifest/meta-data-element.html"><meta-data></a></code> |
| element as the child of the |
| <code><a href="{@docRoot}guide/topics/manifest/activity-element.html"><activity></a></code>. |
| <p> |
| For this element, set |
| <code><a href="{@docRoot}guide/topics/manifest/meta-data-element.html#nm">android:name</a>="android.support.PARENT_ACTIVITY"</code>. |
| Set |
| <code><a href="{@docRoot}guide/topics/manifest/meta-data-element.html#val">android:value</a>="<parent_activity_name>"</code> |
| where <code><parent_activity_name></code> is the value of |
| <code><a href="{@docRoot}guide/topics/manifest/meta-data-element.html#nm">android:name</a></code> |
| for the parent |
| <code><a href="{@docRoot}guide/topics/manifest/activity-element.html"><activity></a></code> |
| element. See the following XML for an example. |
| </p> |
| </li> |
| <li> |
| Also add support for Android 4.1 and later. To do this, add the |
| <code><a href="{@docRoot}guide/topics/manifest/activity-element.html#parent">android:parentActivityName</a></code> |
| attribute to the |
| <code><a href="{@docRoot}guide/topics/manifest/activity-element.html"><activity></a></code> |
| element of the {@link android.app.Activity} you're starting. |
| </li> |
| </ol> |
| <p> |
| The final XML should look like this: |
| </p> |
| <pre> |
| <activity |
| android:name=".MainActivity" |
| android:label="@string/app_name" > |
| <intent-filter> |
| <action android:name="android.intent.action.MAIN" /> |
| <category android:name="android.intent.category.LAUNCHER" /> |
| </intent-filter> |
| </activity> |
| <activity |
| android:name=".ResultActivity" |
| android:parentActivityName=".MainActivity"> |
| <meta-data |
| android:name="android.support.PARENT_ACTIVITY" |
| android:value=".MainActivity"/> |
| </activity> |
| </pre> |
| </li> |
| <li> |
| Create a back stack based on the {@link android.content.Intent} that starts the |
| {@link android.app.Activity}: |
| <ol style="list-style-type: lower-alpha;"> |
| <li> |
| Create the {@link android.content.Intent} to start the {@link android.app.Activity}. |
| </li> |
| <li> |
| Create a stack builder by calling {@link android.app.TaskStackBuilder#create |
| TaskStackBuilder.create()}. |
| </li> |
| <li> |
| Add the back stack to the stack builder by calling |
| {@link android.support.v4.app.TaskStackBuilder#addParentStack addParentStack()}. |
| For each {@link android.app.Activity} in the hierarchy you've defined in the |
| manifest, the back stack contains an {@link android.content.Intent} object that |
| starts the {@link android.app.Activity}. This method also adds flags that start the |
| stack in a fresh task. |
| <p class="note"> |
| <strong>Note:</strong> Although the argument to |
| {@link android.support.v4.app.TaskStackBuilder#addParentStack addParentStack()} |
| is a reference to the started {@link android.app.Activity}, the method call |
| doesn't add the {@link android.content.Intent} that starts the |
| {@link android.app.Activity}. Instead, that's taken care of in the next step. |
| </p> |
| </li> |
| <li> |
| Add the {@link android.content.Intent} that starts the {@link android.app.Activity} |
| from the notification, by calling |
| {@link android.support.v4.app.TaskStackBuilder#addNextIntent addNextIntent()}. |
| Pass the {@link android.content.Intent} you created in the first step as the |
| argument to |
| {@link android.support.v4.app.TaskStackBuilder#addNextIntent addNextIntent()}. |
| </li> |
| <li> |
| If you need to, add arguments to {@link android.content.Intent} objects on the |
| stack by calling {@link android.support.v4.app.TaskStackBuilder#editIntentAt |
| TaskStackBuilder.editIntentAt()}. This is sometimes necessary to ensure that the |
| target {@link android.app.Activity} displays meaningful data when the user navigates |
| to it using <i>Back</i>. |
| </li> |
| <li> |
| Get a {@link android.app.PendingIntent} for this back stack by calling |
| {@link android.support.v4.app.TaskStackBuilder#getPendingIntent getPendingIntent()}. |
| You can then use this {@link android.app.PendingIntent} as the argument to |
| {@link android.support.v4.app.NotificationCompat.Builder#setContentIntent |
| setContentIntent()}. |
| </li> |
| </ol> |
| </li> |
| </ol> |
| <p> |
| The following code snippet demonstrates the process: |
| </p> |
| <pre> |
| ... |
| Intent resultIntent = new Intent(this, ResultActivity.class); |
| TaskStackBuilder stackBuilder = TaskStackBuilder.create(this); |
| // Adds the back stack |
| stackBuilder.addParentStack(ResultActivity.class); |
| // Adds the Intent to the top of the stack |
| stackBuilder.addNextIntent(resultIntent); |
| // Gets a PendingIntent containing the entire back stack |
| PendingIntent resultPendingIntent = |
| stackBuilder.getPendingIntent(0, PendingIntent.FLAG_UPDATE_CURRENT); |
| ... |
| NotificationCompat.Builder builder = new NotificationCompat.Builder(this); |
| builder.setContentIntent(resultPendingIntent); |
| NotificationManager mNotificationManager = |
| (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE); |
| mNotificationManager.notify(id, builder.build()); |
| </pre> |
| <!-- ------------------------------------------------------------------------------------------ --> |
| <h3 id="ExtendedNotification">Setting up a special activity PendingIntent</h3> |
| <p> |
| The following section describes how to set up a special activity |
| {@link android.app.PendingIntent}. |
| </p> |
| <p> |
| A special {@link android.app.Activity} doesn't need a back stack, so you don't have to |
| define its {@link android.app.Activity} hierarchy in the manifest, and you don't have |
| to call |
| {@link android.support.v4.app.TaskStackBuilder#addParentStack addParentStack()} to build a |
| back stack. Instead, use the manifest to set up the {@link android.app.Activity} task options, |
| and create the {@link android.app.PendingIntent} by calling |
| {@link android.app.PendingIntent#getActivity getActivity()}: |
| </p> |
| <ol> |
| <li> |
| In your manifest, add the following attributes to the |
| <code><a href="{@docRoot}guide/topics/manifest/activity-element.html"><activity></a></code> |
| element for the {@link android.app.Activity} |
| <dl> |
| <dt> |
| <code><a href="{@docRoot}guide/topics/manifest/activity-element.html#nm">android:name</a>="<i>activityclass</i>"</code> |
| </dt> |
| <dd> |
| The activity's fully-qualified class name. |
| </dd> |
| <dt> |
| <code><a href="{@docRoot}guide/topics/manifest/activity-element.html#aff">android:taskAffinity</a>=""</code> |
| </dt> |
| <dd> |
| Combined with the |
| {@link android.content.Intent#FLAG_ACTIVITY_NEW_TASK FLAG_ACTIVITY_NEW_TASK} flag |
| that you set in code, this ensures that this {@link android.app.Activity} doesn't |
| go into the application's default task. Any existing tasks that have the |
| application's default affinity are not affected. |
| </dd> |
| <dt> |
| <code><a href="{@docRoot}guide/topics/manifest/activity-element.html#exclude">android:excludeFromRecents</a>="true"</code> |
| </dt> |
| <dd> |
| Excludes the new task from <i>Recents</i>, so that the user can't accidentally |
| navigate back to it. |
| </dd> |
| </dl> |
| <p> |
| This snippet shows the element: |
| </p> |
| <pre> |
| <activity |
| android:name=".ResultActivity" |
| ... |
| android:launchMode="singleTask" |
| android:taskAffinity="" |
| android:excludeFromRecents="true"> |
| </activity> |
| ... |
| </pre> |
| </li> |
| <li> |
| Build and issue the notification: |
| <ol style="list-style-type: lower-alpha;"> |
| <li> |
| Create an {@link android.content.Intent} that starts the |
| {@link android.app.Activity}. |
| </li> |
| <li> |
| Set the {@link android.app.Activity} to start in a new, empty task by calling |
| {@link android.content.Intent#setFlags setFlags()} with the flags |
| {@link android.content.Intent#FLAG_ACTIVITY_NEW_TASK FLAG_ACTIVITY_NEW_TASK} |
| and |
| {@link android.content.Intent#FLAG_ACTIVITY_CLEAR_TASK FLAG_ACTIVITY_CLEAR_TASK}. |
| </li> |
| <li> |
| Set any other options you need for the {@link android.content.Intent}. |
| </li> |
| <li> |
| Create a {@link android.app.PendingIntent} from the {@link android.content.Intent} |
| by calling {@link android.app.PendingIntent#getActivity getActivity()}. |
| You can then use this {@link android.app.PendingIntent} as the argument to |
| {@link android.support.v4.app.NotificationCompat.Builder#setContentIntent |
| setContentIntent()}. |
| </li> |
| </ol> |
| <p> |
| The following code snippet demonstrates the process: |
| </p> |
| <pre> |
| // Instantiate a Builder object. |
| NotificationCompat.Builder builder = new NotificationCompat.Builder(this); |
| // Creates an Intent for the Activity |
| Intent notifyIntent = |
| new Intent(this, ResultActivity.class); |
| // Sets the Activity to start in a new, empty task |
| notifyIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK |
| | Intent.FLAG_ACTIVITY_CLEAR_TASK); |
| // Creates the PendingIntent |
| PendingIntent notifyPendingIntent = |
| PendingIntent.getActivity( |
| this, |
| 0, |
| notifyIntent, |
| PendingIntent.FLAG_UPDATE_CURRENT |
| ); |
| |
| // Puts the PendingIntent into the notification builder |
| builder.setContentIntent(notifyPendingIntent); |
| // Notifications are issued by sending them to the |
| // NotificationManager system service. |
| NotificationManager mNotificationManager = |
| (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE); |
| // Builds an anonymous Notification object from the builder, and |
| // passes it to the NotificationManager |
| mNotificationManager.notify(id, builder.build()); |
| </pre> |
| </li> |
| </ol> |
| <!-- ------------------------------------------------------------------------------------------ --> |
| <!-- ------------------------------------------------------------------------------------------ --> |
| <h2 id="Progress">Displaying Progress in a Notification</h2> |
| <p> |
| Notifications can include an animated progress indicator that shows users the status |
| of an ongoing operation. If you can estimate how long the operation takes and how much of it |
| is complete at any time, use the "determinate" form of the indicator |
| (a progress bar). If you can't estimate the length of the operation, use the |
| "indeterminate" form of the indicator (an activity indicator). |
| </p> |
| <p> |
| Progress indicators are displayed with the platform's implementation of the |
| {@link android.widget.ProgressBar} class. |
| </p> |
| <p> |
| To use a progress indicator on platforms starting with Android 4.0, call |
| {@link android.support.v4.app.NotificationCompat.Builder#setProgress setProgress()}. For |
| previous versions, you must create your own custom notification layout that |
| includes a {@link android.widget.ProgressBar} view. |
| </p> |
| <p> |
| The following sections describe how to display progress in a notification using |
| {@link android.support.v4.app.NotificationCompat.Builder#setProgress setProgress()}. |
| </p> |
| <!-- ------------------------------------------------------------------------------------------ --> |
| <h3 id="FixedProgress">Displaying a fixed-duration progress indicator</h3> |
| <p> |
| To display a determinate progress bar, add the bar to your notification by calling |
| {@link android.support.v4.app.NotificationCompat.Builder#setProgress |
| setProgress(max, progress, false)} and then issue the notification. As your operation proceeds, |
| increment <code>progress</code>, and update the notification. At the end of the operation, |
| <code>progress</code> should equal <code>max</code>. A common way to call |
| {@link android.support.v4.app.NotificationCompat.Builder#setProgress setProgress()} |
| is to set <code>max</code> to 100 and then increment <code>progress</code> as a |
| "percent complete" value for the operation. |
| </p> |
| <p> |
| You can either leave the progress bar showing when the operation is done, or remove it. In |
| either case, remember to update the notification text to show that the operation is complete. |
| To remove the progress bar, call |
| {@link android.support.v4.app.NotificationCompat.Builder#setProgress |
| setProgress(0, 0, false)}. For example: |
| </p> |
| <pre> |
| ... |
| mNotifyManager = |
| (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE); |
| mBuilder = new NotificationCompat.Builder(this); |
| mBuilder.setContentTitle("Picture Download") |
| .setContentText("Download in progress") |
| .setSmallIcon(R.drawable.ic_notification); |
| // Start a lengthy operation in a background thread |
| new Thread( |
| new Runnable() { |
| @Override |
| public void run() { |
| int incr; |
| // Do the "lengthy" operation 20 times |
| for (incr = 0; incr <= 100; incr+=5) { |
| // Sets the progress indicator to a max value, the |
| // current completion percentage, and "determinate" |
| // state |
| mBuilder.setProgress(100, incr, false); |
| // Displays the progress bar for the first time. |
| mNotifyManager.notify(0, mBuilder.build()); |
| // Sleeps the thread, simulating an operation |
| // that takes time |
| try { |
| // Sleep for 5 seconds |
| Thread.sleep(5*1000); |
| } catch (InterruptedException e) { |
| Log.d(TAG, "sleep failure"); |
| } |
| } |
| // When the loop is finished, updates the notification |
| mBuilder.setContentText("Download complete") |
| // Removes the progress bar |
| .setProgress(0,0,false); |
| mNotifyManager.notify(ID, mBuilder.build()); |
| } |
| } |
| // Starts the thread by calling the run() method in its Runnable |
| ).start(); |
| </pre> |
| |
| <!-- ------------------------------------------------------------------------------------------ --> |
| <h3 id="ActivityIndicator">Displaying a continuing activity indicator</h3> |
| <p> |
| To display an indeterminate activity indicator, add it to your notification with |
| {@link android.support.v4.app.NotificationCompat.Builder#setProgress setProgress(0, 0, true)} |
| (the first two arguments are ignored), and issue the notification. The result is an indicator |
| that has the same style as a progress bar, except that its animation is ongoing. |
| </p> |
| <p> |
| Issue the notification at the beginning of the operation. The animation will run until you |
| modify your notification. When the operation is done, call |
| {@link android.support.v4.app.NotificationCompat.Builder#setProgress setProgress(0, 0, false)} |
| and then update the notification to remove the activity indicator. |
| Always do this; otherwise, the animation will run even when the operation is complete. Also |
| remember to change the notification text to indicate that the operation is complete. |
| </p> |
| <p> |
| To see how activity indicators work, refer to the preceding snippet. Locate the following lines: |
| </p> |
| <pre> |
| // Sets the progress indicator to a max value, the current completion |
| // percentage, and "determinate" state |
| mBuilder.setProgress(100, incr, false); |
| // Issues the notification |
| mNotifyManager.notify(0, mBuilder.build()); |
| </pre> |
| <p> |
| Replace the lines you've found with the following lines: |
| </p> |
| <pre> |
| // Sets an activity indicator for an operation of indeterminate length |
| mBuilder.setProgress(0, 0, true); |
| // Issues the notification |
| mNotifyManager.notify(0, mBuilder.build()); |
| </pre> |
| |
| <h2 id="metadata">Notification Metadata</h2> |
| |
| <p>Notifications may be sorted according to metadata that you assign with the |
| following {@link android.support.v4.app.NotificationCompat.Builder} methods:</p> |
| |
| <ul> |
| <li>{@link android.support.v4.app.NotificationCompat.Builder#setCategory(java.lang.String) setCategory()} |
| tells the system how to handle your app notifications when the device is in Priority mode |
| (for example, if your notification represents an incoming call, instant message, or alarm).</li> |
| <li>{@link android.support.v4.app.NotificationCompat.Builder#setPriority(int) setPriority()} causes |
| notifications with the priority field set to {@code PRIORITY_MAX} or {@code PRIORITY_HIGH} to |
| appear in a small floating window if the notification also has sound or vibration.</li> |
| <li>{@link android.support.v4.app.NotificationCompat.Builder#addPerson(java.lang.String) addPerson()} |
| allows you to add a list of people to a notification. Your app can use this to signal to the |
| system that it should group together notifications from the specified people, or rank notifications |
| from these people as being more important.</li> |
| </ul> |
| |
| <div class="figure" style="width:230px"> |
| <img src="{@docRoot}images/ui/notifications/heads-up.png" |
| alt="" width="" height="" id="figure3" /> |
| <p class="img-caption"> |
| <strong>Figure 3.</strong> Fullscreen activity showing a heads-up notification |
| </p> |
| </div> |
| |
| <h2 id="Heads-up">Heads-up Notifications</h2> |
| |
| <p>With Android 5.0 (API level 21), notifications can appear in a small floating window |
| (also called a <em>heads-up notification</em>) when the device is active |
| (that is, the device is unlocked and its screen is on). These notifications |
| appear similar to the compact form of your notification, except that the |
| heads-up notification also shows action buttons. Users can act on, or dismiss, |
| a heads-up notification without leaving the current app.</p> |
| |
| <p>Examples of conditions that may trigger heads-up notifications include:</p> |
| |
| <ul> |
| <li>The user's activity is in fullscreen mode (the app uses |
| {@link android.app.Notification#fullScreenIntent}), or</li> |
| <li>The notification has high priority and uses ringtones or |
| vibrations</li> |
| </ul> |
| |
| <h2 id="lockscreenNotification">Lock Screen Notifications</h2> |
| |
| <p>With the release of Android 5.0 (API level 21), notifications may now appear on the lock |
| screen. Your app can use this functionality to provide media playback controls and other common |
| actions. Users can choose via Settings whether to display notifications on the lock screen, and |
| you can designate whether a notification from your app is visible on the lock screen.</p> |
| |
| <h3 id="visibility">Setting Visibility</h3> |
| |
| <p>Your app can control the level of detail visible in notifications displayed on a secure |
| lock screen. You call {@link android.support.v4.app.NotificationCompat.Builder#setVisibility(int) setVisibility()} |
| and specify one of the following values:</p> |
| |
| <ul> |
| <li>{@link android.support.v4.app.NotificationCompat#VISIBILITY_PUBLIC} shows the notification's |
| full content.</li> |
| <li>{@link android.support.v4.app.NotificationCompat#VISIBILITY_SECRET} doesn't show any part of |
| this notification on the lock screen.</li> |
| <li>{@link android.support.v4.app.NotificationCompat#VISIBILITY_PRIVATE} shows basic information, |
| such as the notification's icon and the content title, but hides the notification's full content.</li> |
| </ul> |
| |
| <p>When {@link android.support.v4.app.NotificationCompat#VISIBILITY_PRIVATE} is set, you can also |
| provide an alternate version of the notification content which hides certain details. For example, |
| an SMS app might display a notification that shows <em>You have 3 new text messages</em>, but hides the |
| message contents and senders. To provide this alternative notification, first create the replacement |
| notification using {@link android.support.v4.app.NotificationCompat.Builder}. When you create the |
| private notification object, attach the replacement notification to it through the |
| {@link android.support.v4.app.NotificationCompat.Builder#setPublicVersion(android.app.Notification) setPublicVersion()} |
| method.</p> |
| |
| <h3 id="controllingMedia">Controlling Media Playback on the Lock Screen</h3> |
| |
| <p> |
| In Android 5.0 (API level 21) the lock screen no longer displays media |
| controls based on the {@link android.media.RemoteControlClient}, which is |
| now deprecated. Instead, use the {@link |
| android.support.v7.app.NotificationCompat.MediaStyle} template with the |
| {@link |
| android.support.v4.app.NotificationCompat.Builder#addAction(android.support.v4.app.NotificationCompat.Action) |
| addAction()} method, which converts actions into clickable icons. |
| </p> |
| |
| <p> |
| To display media playback controls on the lock screen in Android 5.0, set |
| the visibility to {@link |
| android.support.v4.app.NotificationCompat#VISIBILITY_PUBLIC}, as described |
| above. Then add the actions and set the {@link |
| android.support.v7.app.NotificationCompat.MediaStyle} template, as described |
| in the following sample code: |
| </p> |
| |
| <pre> |
| Notification notification = new NotificationCompat.Builder(context) |
| // Show controls on lock screen even when user hides sensitive content. |
| .setVisibility(NotificationCompat.VISIBILITY_PUBLIC) |
| .setSmallIcon(R.drawable.ic_stat_player) |
| // Add media control buttons that invoke intents in your media service |
| .addAction(R.drawable.ic_prev, "Previous", prevPendingIntent) // #0 |
| .addAction(R.drawable.ic_pause, "Pause", pausePendingIntent) // #1 |
| .addAction(R.drawable.ic_next, "Next", nextPendingIntent) // #2 |
| // Apply the media style template |
| .setStyle(new NotificationCompat.MediaStyle() |
| .setShowActionsInCompactView(1 /* #1: pause button */) |
| .setMediaSession(mMediaSession.getSessionToken())) |
| .setContentTitle("Wonderful music") |
| .setContentText("My Awesome Band") |
| .setLargeIcon(albumArtBitmap) |
| .build(); |
| </pre> |
| |
| <p class="note"><strong>Note:</strong> The deprecation of {@link android.media.RemoteControlClient} |
| has further implications for controlling media. See |
| <a href="{@docRoot}about/versions/android-5.0.html#MediaPlaybackControl">Media Playback Control</a> |
| for more information about the new APIs for managing the media session and controlling playback.</p> |
| |
| |
| <!-- ------------------------------------------------------------------------------------------ --> |
| <h2 id="CustomNotification">Custom Notification Layouts</h2> |
| <p> |
| The notifications framework allows you to define a custom notification layout, which |
| defines the notification's appearance in a {@link android.widget.RemoteViews} object. |
| Custom layout notifications are similar to normal notifications, but they're based on a |
| {@link android.widget.RemoteViews} defined in a XML layout file. |
| </p> |
| <p> |
| The height available for a custom notification layout depends on the notification view. Normal |
| view layouts are limited to 64 dp, and expanded view layouts are limited to 256 dp. |
| </p> |
| <p> |
| To define a custom notification layout, start by instantiating a |
| {@link android.widget.RemoteViews} object that inflates an XML layout file. Then, |
| instead of calling methods such as |
| {@link android.support.v4.app.NotificationCompat.Builder#setContentTitle setContentTitle()}, |
| call {@link android.support.v4.app.NotificationCompat.Builder#setContent setContent()}. To set |
| content details in the custom notification, use the methods in |
| {@link android.widget.RemoteViews} to set the values of the view's children: |
| </p> |
| <ol> |
| <li> |
| Create an XML layout for the notification in a separate file. You can use any file name |
| you wish, but you must use the extension <code>.xml</code> |
| </li> |
| <li> |
| In your app, use {@link android.widget.RemoteViews} methods to define your notification's |
| icons and text. Put this {@link android.widget.RemoteViews} object into your |
| {@link android.support.v4.app.NotificationCompat.Builder} by calling |
| {@link android.support.v4.app.NotificationCompat.Builder#setContent setContent()}. Avoid |
| setting a background {@link android.graphics.drawable.Drawable} on your |
| {@link android.widget.RemoteViews} object, because your text color may become unreadable. |
| </li> |
| </ol> |
| <p> |
| The {@link android.widget.RemoteViews} class also includes methods that you can use to easily |
| add a {@link android.widget.Chronometer} or {@link android.widget.ProgressBar} |
| to your notification's layout. For more information about creating custom layouts for your |
| notification, refer to the {@link android.widget.RemoteViews} reference documentation. |
| </p> |
| <p class="caution"> |
| <strong>Caution:</strong> When you use a custom notification layout, take special care to |
| ensure that your custom layout works with different device orientations and resolutions. While |
| this advice applies to all View layouts, it's especially important for notifications because |
| the space in the notification drawer is very restricted. Don't make your custom layout too |
| complex, and be sure to test it in various configurations. |
| </p> |
| <!-- ------------------------------------------------------------------------------------------ --> |
| <h4>Using style resources for custom notification text</h4> |
| <p> |
| Always use style resources for the text of a custom notification. The background color of the |
| notification can vary across different devices and versions, and using style resources |
| helps you account for this. Starting in Android 2.3, the system defined a style for the |
| standard notification layout text. If you use the same style in applications that target Android |
| 2.3 or higher, you'll ensure that your text is visible against the display background. |
| </p> |
| |
| <!-- ------------------------------------------------------------------------ --> |
| <h3 id="custom"> Custom Views</h3> |
| <p> |
| Starting from Android 7.0 (API level 24), |
| you can customize notification views and |
| still obtain system decorations like notification headers, actions, and |
| expandable layouts. |
| </p> |
| |
| <p>To enable this capability, Android provides the following APIs to style your |
| custom view:</p> |
| |
| <dl> |
| <dt> |
| {@code DecoratedCustomViewStyle()}</dt> |
| <dd> Styles notifications other than media |
| notifications.</dd> |
| <dt> |
| {@code DecoratedMediaCustomViewStyle()}</dt> |
| <dd> Styles media notifications.</dd> |
| </dl> |
| |
| <p>To use this API, call the {@code setStyle()} method, passing to it |
| the desired custom view style.</p> |
| |
| <p>This snippet shows how to construct a custom notification object with the |
| {@code DecoratedCustomViewStyle()} method.</p> |
| |
| <pre> |
| Notification notification = new Notification.Builder() |
| .setSmallIcon(R.drawable.ic_stat_player) |
| .setLargeIcon(albumArtBitmap)) |
| .setCustomContentView(contentView); |
| .setStyle(new Notification.DecoratedCustomViewStyle()) |
| .build(); |
| |
| </pre> |
| |
| <!-- ----------------------------------------------------------------------- --> |
| |
| <h3 id="style">Messaging Style</h3> |
| <p> |
| Starting in Android 7.0 (API level 24), |
| Android provides an API for customizing the style of a notification. |
| Using the <code>MessagingStyle</code> class, you can change several of the |
| labels displayed on the notification, including the conversation title, |
| additional messages, and the content view for the notification. |
| </p> |
| |
| <p> |
| The following code snippet demonstrates how to customize a notification's |
| style using the <code>MessagingStyle</code> class. |
| </p> |
| |
| <pre> |
| Notification notification = new Notification.Builder() |
| .setStyle(new Notification.MessagingStyle("Me") |
| .setConversationTitle("Team lunch") |
| .addMessage("Hi", timestamp1, null) // Pass in null for user. |
| .addMessage("What's up?", timestamp2, "Coworker") |
| .addMessage("Not much", timestamp3, null) |
| .addMessage("How about lunch?", timestamp4, "Coworker")) |
| .build(); |
| </pre> |
| |