| page.title=Notifications |
| @jd:body |
| |
| <div id="qv-wrapper"> |
| <div id="qv"> |
| <h2>In this document</h2> |
| <ol> |
| <li><a href="#NotificationUI">Notification Display Elements</a> |
| <ol> |
| <li><a href="#NormalNotify">Normal view</a></li> |
| <li><a href="#BigNotify">Big view</a></li> |
| </ol> |
| </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="#SimpleNotification">Creating a simple notification</a></li> |
| <li><a href="#ApplyStyle">Applying a big view style 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> |
| </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="#CustomNotification">Custom Notification Layouts</a></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="{@docRoot}design/patterns/notifications.html">Android 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/iconic_notification.png" |
| height="120" alt="" /> |
| <p class="img-caption"> |
| <strong>Figure 1.</strong> Notifications in the notification area. |
| </p> |
| <img id="figure2" src="{@docRoot}images/ui/notifications/normal_notification.png" |
| height="293" alt="" /> |
| <p class="img-caption"> |
| <strong>Figure 2.</strong> Notifications in the notification drawer. |
| </p> |
| <div class="note design"> |
| <p> |
| <strong>Notification Design</strong> |
| </p> |
| <p> |
| Notifications, as an important part of the Android UI, have their own design guidelines. To |
| learn how to design notifications and their interactions, read the Android Design Guide |
| <a href="{@docRoot}design/patterns/notifications.html">Notifications</a> topic. |
| </p> |
| </div> |
| <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/extras/support-library.html">Support Library</a>. |
| The class {@link android.app.Notification.Builder Notification.Builder} was added in Android |
| 3.0. |
| </p> |
| <!-- ------------------------------------------------------------------------------------------ --> |
| <!-- ------------------------------------------------------------------------------------------ --> |
| <h2 id="NotificationUI">Notification Display Elements</h2> |
| <p> |
| Notifications in the notification drawer can appear in one of two visual styles, depending on |
| the version and the state of the drawer: |
| </p> |
| <dl> |
| <dt> |
| Normal view |
| </dt> |
| <dd> |
| The standard view of the notifications in the notification drawer. |
| </dd> |
| <dt> |
| Big view |
| </dt> |
| <dd> |
| A large view that's visible when the notification is expanded. Big view is part of the |
| expanded notification feature available as of Android 4.1. |
| </dd> |
| </dl> |
| <p> |
| These styles are described in the following sections. |
| </p> |
| <!-- ------------------------------------------------------------------------------------------ --> |
| <h3 id="NormalNotify">Normal view</h3> |
| <p> |
| A notification in normal view appears in an area that's up to 64 dp tall. Even if you create a |
| notification with a big view style, it will appear in normal view until it's expanded. This |
| is an example of a normal view: |
| </p> |
| <img |
| src="{@docRoot}images/ui/notifications/normal_notification_callouts.png" |
| alt="" |
| height="153" |
| id="figure3" /> |
| <p class="img-caption"> |
| <strong>Figure 3.</strong> Notification in normal view. |
| </p> |
| <p> |
| The callouts in the illustration refer to the following: |
| </p> |
| <ol> |
| <li>Content title</li> |
| <li>Large icon</li> |
| <li>Content text</li> |
| <li>Content info</li> |
| <li>Small icon</li> |
| <li> |
| Time that the notification was issued. You can set an explicit value with |
| {@link android.support.v4.app.NotificationCompat.Builder#setWhen setWhen()}; if you don't |
| it defaults to the time that the system received the notification. |
| </li> |
| </ol> |
| <!-- ------------------------------------------------------------------------------------------ --> |
| <h3 id="BigNotify">Big view</h3> |
| <p> |
| A notification's big view appears only when the notification is expanded, which happens when the |
| notification is at the top of the notification drawer, or when the user expands the |
| notification with a gesture. Expanded notifications are available starting with Android 4.1. |
| </p> |
| <p> |
| The following screenshot shows an inbox-style notification: |
| </p> |
| <img src="{@docRoot}images/ui/notifications/bigpicture_notification_callouts.png" |
| alt="" |
| height="240" |
| id="figure4" /> |
| <p class="img-caption"> |
| <strong>Figure 4.</strong> Big view notification. |
| </p> |
| <p> |
| Notice that the big view shares most of its visual elements with the normal view. The |
| only difference is callout number 7, the details area. Each big view style sets this area in |
| a different way. The available styles are: |
| </p> |
| <dl> |
| <dt> |
| Big picture style |
| </dt> |
| <dd> |
| The details area contains a bitmap up to 256 dp tall in its detail section. |
| </dd> |
| <dt> |
| Big text style |
| </dt> |
| <dd> |
| Displays a large text block in the details section. |
| </dd> |
| <dt> |
| Inbox style |
| </dt> |
| <dd> |
| Displays lines of text in the details section. |
| </dd> |
| </dl> |
| <p> |
| All of the big view styles also have the following content options that aren't |
| available in normal view: |
| </p> |
| <dl> |
| <dt> |
| Big content title |
| </dt> |
| <dd> |
| Allows you to override the normal view's content title with a title that appears only in |
| the expanded view. |
| </dd> |
| <dt> |
| Summary text |
| </dt> |
| <dd> |
| Allows you to add a line of text below the details area. |
| </dd> |
| </dl> |
| <p> |
| Applying a big view style to a notification is described in the section |
| <a href="#ApplyStyle">Applying a big view style to a notification</a>. |
| </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 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 an {@link android.app.Activity}. 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="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 a big view style to a notification</h3> |
| <p> |
| To have a notification appear in a big view when it's expanded, 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 a big view style 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 Inbox big view style: |
| </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 style big view |
| inboxStyle.SetBigContentTitle("Event tracker details:"); |
| ... |
| // Moves events into the big view |
| for (int i=0; i < events.length; i++) { |
| |
| inboxStyle.addLine(events[i]); |
| } |
| // Moves the big view style 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="{@docRoot}design/patterns/notifications.html">Notifications</a> Design guide. |
| </p> |
| <p class="note"> |
| <strong>Note:</strong> This Gmail feature requires the "inbox" big view style, which is |
| part of the expanded notification feature available starting in Android 4.1. |
| </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, Notification) |
| NotificationManager.notify(ID, notification)}. 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> |
| <p> |
| This produces a notification that looks like this: |
| </p> |
| <img |
| id="figure5" |
| src="{@docRoot}images/ui/notifications/updated_notification.png" |
| alt="" |
| height="118"/> |
| <p class="img-caption"> |
| <strong>Figure 5.</strong> Updated notification displayed in the notification drawer. |
| </p> |
| <!-- ------------------------------------------------------------------------------------------ --> |
| <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="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(new ComponentName(this, ResultActivity.class)); |
| // Sets the Activity to start in a new, empty task |
| notifyIntent.setFlags(FLAG_ACTIVITY_NEW_TASK | FLAG_ACTIVITY_CLEAR_TASK); |
| // Creates the PendingIntent |
| PendingIntent notifyIntent = |
| PendingIntent.getActivity( |
| this, |
| 0, |
| notifyIntent |
| PendingIntent.FLAG_UPDATE_CURRENT |
| ); |
| |
| // Puts the PendingIntent into the notification builder |
| builder.setContentIntent(notifyIntent); |
| // 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() |
| 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() |
| 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> |
| <p> |
| The resulting notifications are shown in figure 6. On the left side is a snapshot of the |
| notification during the operation; on the right side is a snapshot of it after the operation |
| has finished. |
| </p> |
| <img |
| id="figure6" |
| src="{@docRoot}images/ui/notifications/progress_bar_summary.png" |
| height="84" |
| alt="" /> |
| <p class="img-caption"> |
| <strong>Figure 6.</strong> The progress bar during and after the operation.</p> |
| <!-- ------------------------------------------------------------------------------------------ --> |
| <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() |
| 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> |
| <p> |
| The resulting indicator is shown in figure 7: |
| </p> |
| <img |
| id="figure7" |
| src="{@docRoot}images/ui/notifications/activity_indicator.png" |
| height="99" |
| alt="" /> |
| <p class="img-caption"><strong>Figure 7.</strong> An ongoing activity indicator.</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> |