notifications.jd revision 3701cbef0f76144d66924b1724abb856e938e340
1page.title=Notifications
2@jd:body
3
4<div id="qv-wrapper">
5<div id="qv">
6<h2>In this document</h2>
7<ol>
8  <li><a href="#NotificationUI">Notification Display Elements</a>
9    <ol>
10      <li><a href="#NormalNotify">Normal view</a></li>
11      <li><a href="#BigNotify">Big view</a></li>
12    </ol>
13  </li>
14  <li><a href="#CreateNotification">Creating a Notification</a>
15    <ol>
16      <li><a href="#Required">Required notification contents</a></li>
17      <li><a href="#Optional">Optional notification contents and settings</a></li>
18      <li><a href="#Actions">Notification actions</a></li>
19      <li><a href="#Priority">Notification priority</a></li>
20      <li><a href="#SimpleNotification">Creating a simple notification</a></li>
21      <li><a href="#ApplyStyle">Applying a big view style to a notification</a></li>
22      <li><a href="#Compatibility">Handling compatibility</a></li>
23    </ol>
24  </li>
25  <li><a href="#Managing">Managing Notifications</a>
26    <ol>
27      <li><a href="#Updating">Updating notifications</a></li>
28      <li><a href="#Removing">Removing notifications</a></li>
29    </ol>
30  </li>
31  <li><a href="#NotificationResponse">Preserving Navigation when Starting an Activity</a>
32    <ol>
33      <li><a href="#DirectEntry">Setting up a regular activity PendingIntent</a></li>
34      <li><a href="#ExtendedNotification">Setting up a special activity PendingIntent</a></li>
35    </ol>
36  </li>
37  <li><a href="#Progress">Displaying Progress in a Notification</a>
38    <ol>
39      <li><a href="#FixedProgress">Displaying a fixed-duration progress indicator</a></li>
40      <li><a href="#ActivityIndicator">Displaying a continuing activity indicator</a></li>
41    </ol>
42  </li>
43  <li><a href="#CustomNotification">Custom Notification Layouts</a></li>
44</ol>
45
46    <h2>Key classes</h2>
47    <ol>
48        <li>{@link android.app.NotificationManager}</li>
49        <li>{@link android.support.v4.app.NotificationCompat}</li>
50    </ol>
51    <h2>Videos</h2>
52    <ol>
53        <li>
54            <a href="http://www.youtube.com/watch?v=Yc8YrVc47TI&feature=player_detailpage#t=1672s">
55            Notifications in 4.1</a>
56        </li>
57    </ol>
58<h2>See also</h2>
59<ol>
60    <li>
61        <a href="{@docRoot}design/patterns/notifications.html">Android Design: Notifications</a>
62    </li>
63</ol>
64</div>
65</div>
66<p>
67    A notification is a message you can display to the user outside of your application's
68    normal UI. When you tell the system to issue a notification, it first appears as an icon in the
69    <strong>notification area</strong>. To see the details of the notification, the user opens the
70    <strong>notification drawer</strong>. Both the notification area and the notification drawer
71    are system-controlled areas that the user can view at any time.
72</p>
73<img
74    id="figure1"
75    src="{@docRoot}images/ui/notifications/iconic_notification.png"
76    height="120" alt="" />
77<p class="img-caption">
78    <strong>Figure 1.</strong> Notifications in the notification area.
79</p>
80<img id="figure2" src="{@docRoot}images/ui/notifications/normal_notification.png"
81     height="293" alt="" />
82<p class="img-caption">
83    <strong>Figure 2.</strong> Notifications in the notification drawer.
84</p>
85<div class="note design">
86    <p>
87        <strong>Notification Design</strong>
88    </p>
89    <p>
90        Notifications, as an important part of the Android UI, have their own design guidelines. To
91        learn how to design notifications and their interactions, read the Android Design Guide
92        <a href="{@docRoot}design/patterns/notifications.html">Notifications</a> topic.
93    </p>
94</div>
95<p class="note">
96    <strong>Note:</strong> Except where noted, this guide refers to the
97    {@link android.support.v4.app.NotificationCompat.Builder NotificationCompat.Builder} class
98    in the version 4 <a href="{@docRoot}tools/support-library/index.html">Support Library</a>.
99    The class {@link android.app.Notification.Builder Notification.Builder} was added in Android
100    3.0.
101</p>
102<!-- ------------------------------------------------------------------------------------------ -->
103<!-- ------------------------------------------------------------------------------------------ -->
104<h2 id="NotificationUI">Notification Display Elements</h2>
105<p>
106    Notifications in the notification drawer can appear in one of two visual styles, depending on
107    the version and the state of the drawer:
108</p>
109<dl>
110    <dt>
111        Normal view
112    </dt>
113    <dd>
114        The standard view of the notifications in the notification drawer.
115    </dd>
116    <dt>
117        Big view
118    </dt>
119    <dd>
120        A large view that's visible when the notification is expanded. Big view is part of the
121        expanded notification feature available as of Android 4.1.
122    </dd>
123</dl>
124<p>
125    These styles are described in the following sections.
126</p>
127<!-- ------------------------------------------------------------------------------------------ -->
128<h3 id="NormalNotify">Normal view</h3>
129<p>
130    A notification in normal view appears in an area that's up to 64 dp tall. Even if you create a
131    notification with a big view style, it will appear in normal view until it's expanded. This
132    is an example of a normal view:
133</p>
134<img
135    src="{@docRoot}images/ui/notifications/normal_notification_callouts.png"
136    alt=""
137    height="153"
138    id="figure3" />
139<p class="img-caption">
140  <strong>Figure 3.</strong> Notification in normal view.
141</p>
142<p>
143    The callouts in the illustration refer to the following:
144</p>
145<ol>
146    <li>Content title</li>
147    <li>Large icon</li>
148    <li>Content text</li>
149    <li>Content info</li>
150    <li>Small icon</li>
151    <li>
152        Time that the notification was issued. You can set an explicit value with
153        {@link android.support.v4.app.NotificationCompat.Builder#setWhen setWhen()}; if you don't
154        it defaults to the time that the system received the notification.
155    </li>
156</ol>
157<!-- ------------------------------------------------------------------------------------------ -->
158<h3 id="BigNotify">Big view</h3>
159<p>
160    A notification's big view appears only when the notification is expanded, which happens when the
161    notification is at the top of the notification drawer, or when the user expands the
162    notification with a gesture. Expanded notifications are available starting with Android 4.1.
163</p>
164<p>
165    The following screenshot shows an inbox-style notification:
166</p>
167<img src="{@docRoot}images/ui/notifications/bigpicture_notification_callouts.png"
168    alt=""
169    height="240"
170    id="figure4" />
171<p class="img-caption">
172  <strong>Figure 4.</strong> Big view notification.
173</p>
174<p>
175    Notice that the big view shares most of its visual elements with the normal view. The
176    only difference is callout number 7, the details area. Each big view style sets this area in
177    a different way. The available styles are:
178</p>
179<dl>
180    <dt>
181        Big picture style
182    </dt>
183    <dd>
184        The details area contains a bitmap up to 256 dp tall in its detail section.
185    </dd>
186    <dt>
187        Big text style
188    </dt>
189    <dd>
190        Displays a large text block in the details section.
191    </dd>
192    <dt>
193        Inbox style
194    </dt>
195    <dd>
196        Displays lines of text in the details section.
197    </dd>
198</dl>
199<p>
200    All of the big view styles also have the following content options that aren't
201    available in normal view:
202</p>
203<dl>
204    <dt>
205        Big content title
206    </dt>
207    <dd>
208        Allows you to override the normal view's content title with a title that appears only in
209        the expanded view.
210    </dd>
211    <dt>
212        Summary text
213    </dt>
214    <dd>
215        Allows you to add a line of text below the details area.
216    </dd>
217</dl>
218<p>
219    Applying a big view style to a notification is described in the section
220    <a href="#ApplyStyle">Applying a big view style to a notification</a>.
221</p>
222<!-- ------------------------------------------------------------------------------------------ -->
223<!-- ------------------------------------------------------------------------------------------ -->
224<h2 id="CreateNotification">Creating a Notification</h2>
225<p>
226    You specify the UI information and actions for a notification in a
227    {@link android.support.v4.app.NotificationCompat.Builder NotificationCompat.Builder} object.
228    To create the notification itself, you call
229    {@link android.support.v4.app.NotificationCompat.Builder#build
230    NotificationCompat.Builder.build()}, which returns a {@link android.app.Notification} object
231    containing your specifications.
232    To issue the notification, you pass the {@link android.app.Notification} object to the system
233    by calling {@link android.app.NotificationManager#notify NotificationManager.notify()}.
234</p>
235<!-- ------------------------------------------------------------------------------------------ -->
236<h3 id="Required">Required notification contents</h3>
237<p>
238    A {@link android.app.Notification} object <em>must</em> contain the following:
239</p>
240<ul>
241    <li>
242        A small icon, set by
243        {@link android.support.v4.app.NotificationCompat.Builder#setSmallIcon setSmallIcon()}
244    </li>
245    <li>
246        A title, set by
247        {@link android.support.v4.app.NotificationCompat.Builder#setContentTitle setContentTitle()}
248    </li>
249    <li>
250        Detail text, set by
251        {@link android.support.v4.app.NotificationCompat.Builder#setContentText setContentText()}
252    </li>
253</ul>
254<h3 id="Optional">Optional notification contents and settings</h3>
255<p>
256    All other notification settings and contents are optional. To learn more about them,
257    see the reference documentation for {@link android.support.v4.app.NotificationCompat.Builder}.
258</p>
259<!-- ------------------------------------------------------------------------------------------ -->
260<h3 id="Actions">Notification actions</h3>
261<p>
262    Although they're optional, you should add at least one action to your notification.
263    An action allows users to go directly from the notification to an
264    {@link android.app.Activity} in your application, where they can look at one or more events
265    or do further work.
266</p>
267<p>
268    A notification can provide multiple actions. You should always define the action that's
269    triggered when the user clicks the notification; usually this action opens an
270    {@link android.app.Activity} in your application. You can also add buttons to the notification
271    that perform additional actions such as snoozing an alarm or responding immediately to a text
272    message; this feature is available as of Android 4.1. If you use additional action buttons, you
273    must also make their functionality available in an {@link android.app.Activity} in your app; see
274    the section <a href="#Compatibility">Handling compatibility</a> for more details.
275</p>
276<p>
277    Inside a {@link android.app.Notification}, the action itself is defined by a
278    {@link android.app.PendingIntent} containing an {@link android.content.Intent} that starts
279    an {@link android.app.Activity} in your application. To associate the
280    {@link android.app.PendingIntent} with a gesture, call the appropriate method of
281    {@link android.support.v4.app.NotificationCompat.Builder}. For example, if you want to start
282    {@link android.app.Activity} when the user clicks the notification text in
283    the notification drawer, you add the {@link android.app.PendingIntent} by calling
284    {@link android.support.v4.app.NotificationCompat.Builder#setContentIntent setContentIntent()}.
285</p>
286<p>
287    Starting an {@link android.app.Activity} when the user clicks the notification is the most
288    common action scenario. You can also start an {@link android.app.Activity} when the user
289    dismisses a notification. In Android 4.1 and later, you can start an
290    {@link android.app.Activity} from an action button. To learn more, read the reference guide for
291    {@link android.support.v4.app.NotificationCompat.Builder}.
292</p>
293<!-- ------------------------------------------------------------------------------------------ -->
294<h3 id="Priority">Notification priority</h3>
295<p>
296    If you wish, you can set the priority of a notification. The priority acts
297    as a hint to the device UI about how the notification should be displayed.
298    To set a notification's priority, call {@link
299    android.support.v4.app.NotificationCompat.Builder#setPriority(int)
300    NotificationCompat.Builder.setPriority()} and pass in one of the {@link
301    android.support.v4.app.NotificationCompat} priority constants. There are
302    five priority levels, ranging from {@link
303    android.support.v4.app.NotificationCompat#PRIORITY_MIN} (-2) to {@link
304    android.support.v4.app.NotificationCompat#PRIORITY_MAX} (2); if not set, the
305    priority defaults to {@link
306    android.support.v4.app.NotificationCompat#PRIORITY_DEFAULT} (0).
307</p>
308<p> For information about setting an appropriate priority level, see "Correctly
309    set and manage notification priority" in the <a
310    href="{@docRoot}design/patterns/notifications.html">Notifications</a> Design
311    guide.
312</p>
313<!-- ------------------------------------------------------------------------------------------ -->
314<h3 id="SimpleNotification">Creating a simple notification</h3>
315<p>
316    The following snippet illustrates a simple notification that specifies an activity to open when
317    the user clicks the notification. Notice that the code creates a
318    {@link android.support.v4.app.TaskStackBuilder} object and uses it to create the
319    {@link android.app.PendingIntent} for the action. This pattern is explained in more detail
320    in the section <a href="#NotificationResponse">
321    Preserving Navigation when Starting an Activity</a>:
322</p>
323<pre>
324NotificationCompat.Builder mBuilder =
325        new NotificationCompat.Builder(this)
326        .setSmallIcon(R.drawable.notification_icon)
327        .setContentTitle("My notification")
328        .setContentText("Hello World!");
329// Creates an explicit intent for an Activity in your app
330Intent resultIntent = new Intent(this, ResultActivity.class);
331
332// The stack builder object will contain an artificial back stack for the
333// started Activity.
334// This ensures that navigating backward from the Activity leads out of
335// your application to the Home screen.
336TaskStackBuilder stackBuilder = TaskStackBuilder.create(this);
337// Adds the back stack for the Intent (but not the Intent itself)
338stackBuilder.addParentStack(ResultActivity.class);
339// Adds the Intent that starts the Activity to the top of the stack
340stackBuilder.addNextIntent(resultIntent);
341PendingIntent resultPendingIntent =
342        stackBuilder.getPendingIntent(
343            0,
344            PendingIntent.FLAG_UPDATE_CURRENT
345        );
346mBuilder.setContentIntent(resultPendingIntent);
347NotificationManager mNotificationManager =
348    (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
349// mId allows you to update the notification later on.
350mNotificationManager.notify(mId, mBuilder.build());
351</pre>
352<p>That's it. Your user has now been notified.</p>
353<!-- ------------------------------------------------------------------------------------------ -->
354<h3 id="ApplyStyle">Applying a big view style to a notification</h3>
355<p>
356    To have a notification appear in a big view when it's expanded, first create a
357    {@link android.support.v4.app.NotificationCompat.Builder} object with the normal view options
358    you want. Next, call {@link android.support.v4.app.NotificationCompat.Builder#setStyle
359    Builder.setStyle()} with a big view style object as its argument.
360</p>
361<p>
362    Remember that expanded notifications are not available on platforms prior to Android 4.1. To
363    learn how to handle notifications for Android 4.1 and for earlier platforms, read the
364    section <a href="#Compatibility">Handling compatibility</a>.
365</p>
366<p>
367    For example, the following code snippet demonstrates how to alter the notification created
368    in the previous snippet to use the Inbox big view style:
369</p>
370<pre>
371NotificationCompat.Builder mBuilder = new NotificationCompat.Builder(this)
372    .setSmallIcon(R.drawable.notification_icon)
373    .setContentTitle("Event tracker")
374    .setContentText("Events received")
375NotificationCompat.InboxStyle inboxStyle =
376        new NotificationCompat.InboxStyle();
377String[] events = new String[6];
378// Sets a title for the Inbox style big view
379inboxStyle.setBigContentTitle("Event tracker details:");
380...
381// Moves events into the big view
382for (int i=0; i &lt; events.length; i++) {
383
384    inboxStyle.addLine(events[i]);
385}
386// Moves the big view style object into the notification object.
387mBuilder.setStyle(inBoxStyle);
388...
389// Issue the notification here.
390</pre>
391<h3 id="Compatibility">Handling compatibility</h3>
392<p>
393    Not all notification features are available for a particular version, even though
394    the methods to set them are in the support library class
395    {@link android.support.v4.app.NotificationCompat.Builder NotificationCompat.Builder}.
396    For example, action buttons, which depend on expanded notifications, only appear on Android
397    4.1 and higher, because expanded notifications themselves are only available on
398    Android 4.1 and higher.
399</p>
400<p>
401    To ensure the best compatibility, create notifications with
402    {@link android.support.v4.app.NotificationCompat NotificationCompat} and its subclasses,
403    particularly {@link android.support.v4.app.NotificationCompat.Builder
404    NotificationCompat.Builder}. In addition, follow this process when you implement a notification:
405</p>
406<ol>
407    <li>
408        Provide all of the notification's functionality to all users, regardless of the version
409        they're using. To do this, verify that all of the functionality is available from an
410        {@link android.app.Activity} in your app. You may want to add a new
411        {@link android.app.Activity} to do this.
412        <p>
413            For example, if you want to use
414            {@link android.support.v4.app.NotificationCompat.Builder#addAction addAction()} to
415            provide a control that stops and starts media playback, first implement this
416            control in an {@link android.app.Activity} in your app.
417        </p>
418    </li>
419    <li>
420        Ensure that all users can get to the functionality in the {@link android.app.Activity},
421        by having it start when users click the notification. To do this,
422        create a {@link android.app.PendingIntent} for the {@link android.app.Activity}. Call
423        {@link android.support.v4.app.NotificationCompat.Builder#setContentIntent
424        setContentIntent()} to add the {@link android.app.PendingIntent} to the notification.
425    </li>
426    <li>
427        Now add the expanded notification features you want to use to the notification. Remember
428        that any functionality you add also has to be available in the {@link android.app.Activity}
429        that starts when users click the notification.
430    </li>
431</ol>
432<!-- ------------------------------------------------------------------------------------------ -->
433<!-- ------------------------------------------------------------------------------------------ -->
434<h2 id="Managing">Managing Notifications</h2>
435<p>
436    When you need to issue a notification multiple times for the same type of event, you
437    should avoid making a completely new notification. Instead, you should consider updating a
438    previous notification, either by changing some of its values or by adding to it, or both.
439</p>
440<p>
441    For example, Gmail notifies the user that new emails have arrived by increasing its count of
442    unread messages and by adding a summary of each email to the notification. This is called
443    "stacking" the notification; it's described in more detail in the
444    <a href="{@docRoot}design/patterns/notifications.html">Notifications</a> Design guide.
445</p>
446<p class="note">
447    <strong>Note:</strong> This Gmail feature requires the "inbox" big view style, which is
448    part of the expanded notification feature available starting in Android 4.1.
449</p>
450<p>
451    The following section describes how to update notifications and also how to remove them.
452</p>
453<h3 id="Updating">Updating notifications</h3>
454<p>
455    To set up a notification so it can be updated, issue it with a notification ID by
456    calling {@link android.app.NotificationManager#notify(int, Notification)
457    NotificationManager.notify(ID, notification)}. To update this notification once you've issued
458    it, update or create a {@link android.support.v4.app.NotificationCompat.Builder} object,
459    build a {@link android.app.Notification} object from it, and issue the
460    {@link android.app.Notification} with the same ID you used previously. If
461    the previous notification is still visible, the system updates it from the contents of
462    the {@link android.app.Notification} object. If the previous notification has been dismissed, a
463    new notification is created instead.
464</p>
465<p>
466    The following snippet demonstrates a notification that is updated to reflect the
467    number of events that have occurred. It stacks the notification, showing a summary:
468</p>
469<pre>
470mNotificationManager =
471        (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
472// Sets an ID for the notification, so it can be updated
473int notifyID = 1;
474mNotifyBuilder = new NotificationCompat.Builder(this)
475    .setContentTitle("New Message")
476    .setContentText("You've received new messages.")
477    .setSmallIcon(R.drawable.ic_notify_status)
478numMessages = 0;
479// Start of a loop that processes data and then notifies the user
480...
481    mNotifyBuilder.setContentText(currentText)
482        .setNumber(++numMessages);
483    // Because the ID remains unchanged, the existing notification is
484    // updated.
485    mNotificationManager.notify(
486            notifyID,
487            mNotifyBuilder.build());
488...
489</pre>
490<p>
491    This produces a notification that looks like this:
492</p>
493<img
494    id="figure5"
495    src="{@docRoot}images/ui/notifications/updated_notification.png"
496    alt=""
497    height="118"/>
498<p class="img-caption">
499  <strong>Figure 5.</strong> Updated notification displayed in the notification drawer.
500</p>
501<!-- ------------------------------------------------------------------------------------------ -->
502<h3 id="Removing">Removing notifications</h3>
503<p>
504    Notifications remain visible until one of the following happens:
505</p>
506<ul>
507    <li>
508        The user dismisses the notification either individually or by using "Clear All" (if
509        the notification can be cleared).
510    </li>
511    <li>
512        The user clicks the notification, and you called
513        {@link android.support.v4.app.NotificationCompat.Builder#setAutoCancel setAutoCancel()} when
514        you created the notification.
515    </li>
516    <li>
517        You call {@link android.app.NotificationManager#cancel(int) cancel()} for a specific
518        notification ID. This method also deletes ongoing notifications.
519    </li>
520    <li>
521        You call {@link android.app.NotificationManager#cancelAll() cancelAll()}, which removes
522        all of the notifications you previously issued.
523    </li>
524</ul>
525<!-- ------------------------------------------------------------------------------------------ -->
526<!-- ------------------------------------------------------------------------------------------ -->
527<h2 id="NotificationResponse">Preserving Navigation when Starting an Activity</h2>
528<p>
529    When you start an {@link android.app.Activity} from a notification, you must preserve the
530    user's expected navigation experience. Clicking <i>Back</i> should take the user back through
531    the application's normal work flow to the Home screen, and clicking <i>Recents</i> should show
532    the {@link android.app.Activity} as a separate task. To preserve the navigation experience, you
533    should start the {@link android.app.Activity} in a fresh task. How you set up the
534    {@link android.app.PendingIntent} to give you a fresh task depends on the nature of the
535    {@link android.app.Activity} you're starting. There are two general situations:
536</p>
537<dl>
538    <dt>
539        Regular activity
540    </dt>
541    <dd>
542        You're starting an {@link android.app.Activity} that's part of the application's normal
543        workflow. In this situation, set up the {@link android.app.PendingIntent} to
544        start a fresh task, and provide the {@link android.app.PendingIntent} with a back stack
545        that reproduces the application's normal <i>Back</i> behavior.
546        <p>
547            Notifications from the Gmail app demonstrate this. When you click a notification for
548            a single email message, you see the message itself. Touching <b>Back</b> takes you
549            backwards through Gmail to the Home screen, just as if you had entered Gmail from the
550            Home screen rather than entering it from a notification.
551        </p>
552        <p>
553            This happens regardless of the application you were in when you touched the
554            notification. For example, if you're in Gmail composing a message, and you click a
555            notification for a single email, you go immediately to that email. Touching <i>Back</i>
556            takes you to the inbox and then the Home screen, rather than taking you to the
557            message you were composing.
558        </p>
559    </dd>
560    <dt>
561        Special activity
562    </dt>
563    <dd>
564        The user only sees this {@link android.app.Activity} if it's started from a notification.
565        In a sense, the {@link android.app.Activity} extends the notification by providing
566        information that would be hard to display in the notification itself. For this situation,
567        set up the {@link android.app.PendingIntent} to start in a fresh task. There's no need to
568        create a back stack, though, because the started {@link android.app.Activity} isn't part of
569        the application's activity flow. Clicking <i>Back</i> will still take the user to the
570        Home screen.
571    </dd>
572</dl>
573<!-- ------------------------------------------------------------------------------------------ -->
574<h3 id="DirectEntry">Setting up a regular activity PendingIntent</h3>
575<p>
576    To set up a {@link android.app.PendingIntent} that starts a direct entry
577    {@link android.app.Activity}, follow these steps:
578</p>
579<ol>
580    <li>
581        Define your application's {@link android.app.Activity} hierarchy in the manifest.
582        <ol style="list-style-type: lower-alpha;">
583            <li>
584                Add support for Android 4.0.3 and earlier. To do this, specify the parent of the
585                {@link android.app.Activity} you're starting by adding a
586<code><a href="{@docRoot}guide/topics/manifest/meta-data-element.html">&lt;meta-data&gt;</a></code>
587                element as the child of the
588<code><a href="{@docRoot}guide/topics/manifest/activity-element.html">&lt;activity&gt;</a></code>.
589                <p>
590                    For this element, set
591<code><a href="{@docRoot}guide/topics/manifest/meta-data-element.html#nm">android:name</a>="android.support.PARENT_ACTIVITY"</code>.
592                    Set
593<code><a href="{@docRoot}guide/topics/manifest/meta-data-element.html#val">android:value</a>="&lt;parent_activity_name&gt;"</code>
594                    where <code>&lt;parent_activity_name&gt;</code> is the value of
595<code><a href="{@docRoot}guide/topics/manifest/meta-data-element.html#nm">android:name</a></code>
596                    for the parent
597<code><a href="{@docRoot}guide/topics/manifest/activity-element.html">&lt;activity&gt;</a></code>
598                    element. See the following XML for an example.
599                </p>
600            </li>
601            <li>
602                Also add support for Android 4.1 and later. To do this, add the
603<code><a href="{@docRoot}guide/topics/manifest/activity-element.html#parent">android:parentActivityName</a></code>
604                attribute to the
605<code><a href="{@docRoot}guide/topics/manifest/activity-element.html">&lt;activity&gt;</a></code>
606                element of the {@link android.app.Activity} you're starting.
607            </li>
608        </ol>
609        <p>
610            The final XML should look like this:
611        </p>
612<pre>
613&lt;activity
614    android:name=".MainActivity"
615    android:label="&#64;string/app_name" &gt;
616    &lt;intent-filter&gt;
617        &lt;action android:name="android.intent.action.MAIN" /&gt;
618        &lt;category android:name="android.intent.category.LAUNCHER" /&gt;
619    &lt;/intent-filter&gt;
620&lt;/activity&gt;
621&lt;activity
622    android:name=".ResultActivity"
623    android:parentActivityName=".MainActivity"&gt;
624    &lt;meta-data
625        android:name="android.support.PARENT_ACTIVITY"
626        android:value=".MainActivity"/&gt;
627&lt;/activity&gt;
628</pre>
629    </li>
630    <li>
631        Create a back stack based on the {@link android.content.Intent} that starts the
632        {@link android.app.Activity}:
633        <ol style="list-style-type: lower-alpha;">
634            <li>
635                Create the {@link android.content.Intent} to start the {@link android.app.Activity}.
636            </li>
637            <li>
638                Create a stack builder by calling {@link android.app.TaskStackBuilder#create
639                TaskStackBuilder.create()}.
640            </li>
641            <li>
642                Add the back stack to the stack builder by calling
643                {@link android.support.v4.app.TaskStackBuilder#addParentStack addParentStack()}.
644                For each {@link android.app.Activity} in the hierarchy you've defined in the
645                manifest, the back stack contains an {@link android.content.Intent} object that
646                starts the {@link android.app.Activity}. This method also adds flags that start the
647                stack in a fresh task.
648                <p class="note">
649                    <strong>Note:</strong> Although the argument to
650                    {@link android.support.v4.app.TaskStackBuilder#addParentStack addParentStack()}
651                    is a reference to the started {@link android.app.Activity}, the method call
652                    doesn't add the {@link android.content.Intent} that starts the
653                    {@link android.app.Activity}. Instead, that's taken care of in the next step.
654                </p>
655            </li>
656            <li>
657                Add the {@link android.content.Intent} that starts the {@link android.app.Activity}
658                from the notification, by calling
659                {@link android.support.v4.app.TaskStackBuilder#addNextIntent addNextIntent()}.
660                Pass the {@link android.content.Intent} you created in the first step as the
661                argument to
662                {@link android.support.v4.app.TaskStackBuilder#addNextIntent addNextIntent()}.
663            </li>
664            <li>
665                If you need to, add arguments to {@link android.content.Intent} objects on the
666                stack by calling {@link android.support.v4.app.TaskStackBuilder#editIntentAt
667                TaskStackBuilder.editIntentAt()}. This is sometimes necessary to ensure that the
668                target {@link android.app.Activity} displays meaningful data when the user navigates
669                to it using <i>Back</i>.
670            </li>
671            <li>
672                Get a {@link android.app.PendingIntent} for this back stack by calling
673                {@link android.support.v4.app.TaskStackBuilder#getPendingIntent getPendingIntent()}.
674                You can then use this {@link android.app.PendingIntent} as the argument to
675                {@link android.support.v4.app.NotificationCompat.Builder#setContentIntent
676                setContentIntent()}.
677            </li>
678        </ol>
679     </li>
680</ol>
681<p>
682    The following code snippet demonstrates the process:
683</p>
684<pre>
685...
686Intent resultIntent = new Intent(this, ResultActivity.class);
687TaskStackBuilder stackBuilder = TaskStackBuilder.create(this);
688// Adds the back stack
689stackBuilder.addParentStack(ResultActivity.class);
690// Adds the Intent to the top of the stack
691stackBuilder.addNextIntent(resultIntent);
692// Gets a PendingIntent containing the entire back stack
693PendingIntent resultPendingIntent =
694        stackBuilder.getPendingIntent(0, PendingIntent.FLAG_UPDATE_CURRENT);
695...
696NotificationCompat.Builder builder = new NotificationCompat.Builder(this);
697builder.setContentIntent(resultPendingIntent);
698NotificationManager mNotificationManager =
699    (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
700mNotificationManager.notify(id, builder.build());
701</pre>
702<!-- ------------------------------------------------------------------------------------------ -->
703<h3 id="ExtendedNotification">Setting up a special activity PendingIntent</h3>
704<p>
705    The following section describes how to set up a special activity
706    {@link android.app.PendingIntent}.
707</p>
708<p>
709    A special {@link android.app.Activity} doesn't need a back stack, so you don't have to
710    define its {@link android.app.Activity} hierarchy in the manifest, and you don't have
711    to call
712    {@link android.support.v4.app.TaskStackBuilder#addParentStack  addParentStack()} to build a
713    back stack. Instead, use the manifest to set up the {@link android.app.Activity} task options,
714    and create the {@link android.app.PendingIntent} by calling
715    {@link android.app.PendingIntent#getActivity getActivity()}:
716</p>
717<ol>
718    <li>
719        In your manifest, add the following attributes to the
720<code><a href="{@docRoot}guide/topics/manifest/activity-element.html">&lt;activity&gt;</a></code>
721        element for the {@link android.app.Activity}
722        <dl>
723            <dt>
724<code><a href="{@docRoot}guide/topics/manifest/activity-element.html#nm">android:name</a>="<i>activityclass</i>"</code>
725            </dt>
726            <dd>
727                The activity's fully-qualified class name.
728            </dd>
729            <dt>
730<code><a href="{@docRoot}guide/topics/manifest/activity-element.html#aff">android:taskAffinity</a>=""</code>
731            </dt>
732            <dd>
733                Combined with the
734                {@link android.content.Intent#FLAG_ACTIVITY_NEW_TASK FLAG_ACTIVITY_NEW_TASK} flag
735                that you set in code, this ensures that this {@link android.app.Activity} doesn't
736                go into the application's default task. Any existing tasks that have the
737                application's default affinity are not affected.
738            </dd>
739            <dt>
740<code><a href="{@docRoot}guide/topics/manifest/activity-element.html#exclude">android:excludeFromRecents</a>="true"</code>
741            </dt>
742            <dd>
743                Excludes the new task from <i>Recents</i>, so that the user can't accidentally
744                navigate back to it.
745            </dd>
746        </dl>
747        <p>
748            This snippet shows the element:
749        </p>
750<pre>
751&lt;activity
752    android:name=".ResultActivity"
753...
754    android:launchMode="singleTask"
755    android:taskAffinity=""
756    android:excludeFromRecents="true"&gt;
757&lt;/activity&gt;
758...
759</pre>
760    </li>
761    <li>
762        Build and issue the notification:
763        <ol style="list-style-type: lower-alpha;">
764            <li>
765                Create an {@link android.content.Intent} that starts the
766                {@link android.app.Activity}.
767            </li>
768            <li>
769                Set the {@link android.app.Activity} to start in a new, empty task by calling
770                {@link android.content.Intent#setFlags setFlags()} with the flags
771                {@link android.content.Intent#FLAG_ACTIVITY_NEW_TASK FLAG_ACTIVITY_NEW_TASK}
772                and
773                {@link android.content.Intent#FLAG_ACTIVITY_CLEAR_TASK FLAG_ACTIVITY_CLEAR_TASK}.
774            </li>
775            <li>
776                Set any other options you need for the {@link android.content.Intent}.
777            </li>
778            <li>
779                Create a {@link android.app.PendingIntent} from the {@link android.content.Intent}
780                by calling {@link android.app.PendingIntent#getActivity getActivity()}.
781                You can then use this {@link android.app.PendingIntent} as the argument to
782                {@link android.support.v4.app.NotificationCompat.Builder#setContentIntent
783                setContentIntent()}.
784            </li>
785        </ol>
786    <p>
787        The following code snippet demonstrates the process:
788    </p>
789<pre>
790// Instantiate a Builder object.
791NotificationCompat.Builder builder = new NotificationCompat.Builder(this);
792// Creates an Intent for the Activity
793Intent notifyIntent =
794        new Intent(new ComponentName(this, ResultActivity.class));
795// Sets the Activity to start in a new, empty task
796notifyIntent.setFlags(FLAG_ACTIVITY_NEW_TASK | FLAG_ACTIVITY_CLEAR_TASK);
797// Creates the PendingIntent
798PendingIntent notifyIntent =
799        PendingIntent.getActivity(
800        this,
801        0,
802        notifyIntent
803        PendingIntent.FLAG_UPDATE_CURRENT
804);
805
806// Puts the PendingIntent into the notification builder
807builder.setContentIntent(notifyIntent);
808// Notifications are issued by sending them to the
809// NotificationManager system service.
810NotificationManager mNotificationManager =
811    (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
812// Builds an anonymous Notification object from the builder, and
813// passes it to the NotificationManager
814mNotificationManager.notify(id, builder.build());
815</pre>
816    </li>
817</ol>
818<!-- ------------------------------------------------------------------------------------------ -->
819<!-- ------------------------------------------------------------------------------------------ -->
820<h2 id="Progress">Displaying Progress in a Notification</h2>
821<p>
822    Notifications can include an animated progress indicator that shows users the status
823    of an ongoing operation. If you can estimate how long the operation takes and how much of it
824    is complete at any time, use the "determinate" form of the indicator
825    (a progress bar). If you can't estimate the length of the operation, use the
826    "indeterminate" form of the indicator (an activity indicator).
827</p>
828<p>
829    Progress indicators are displayed with the platform's implementation of the
830    {@link android.widget.ProgressBar} class.
831</p>
832<p>
833    To use a progress indicator on platforms starting with Android 4.0, call
834    {@link android.support.v4.app.NotificationCompat.Builder#setProgress setProgress()}. For
835    previous versions, you must create your own custom notification layout that
836    includes a {@link android.widget.ProgressBar} view.
837</p>
838<p>
839    The following sections describe how to display progress in a notification using
840    {@link android.support.v4.app.NotificationCompat.Builder#setProgress setProgress()}.
841</p>
842<!-- ------------------------------------------------------------------------------------------ -->
843<h3 id="FixedProgress">Displaying a fixed-duration progress indicator</h3>
844<p>
845    To display a determinate progress bar, add the bar to your notification by calling
846    {@link android.support.v4.app.NotificationCompat.Builder#setProgress setProgress()
847    setProgress(max, progress, false)} and then issue the notification. As your operation proceeds,
848    increment <code>progress</code>, and update the notification. At the end of the operation,
849    <code>progress</code> should equal <code>max</code>. A common way to call
850    {@link android.support.v4.app.NotificationCompat.Builder#setProgress setProgress()}
851    is to set <code>max</code> to 100 and then increment <code>progress</code> as a
852    "percent complete" value for the operation.
853</p>
854<p>
855    You can either leave the progress bar showing when the operation is done, or remove it. In
856    either case, remember to update the notification text to show that the operation is complete.
857    To remove the progress bar, call
858    {@link android.support.v4.app.NotificationCompat.Builder#setProgress setProgress()
859    setProgress(0, 0, false)}. For example:
860</p>
861<pre>
862...
863mNotifyManager =
864        (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
865mBuilder = new NotificationCompat.Builder(this);
866mBuilder.setContentTitle("Picture Download")
867    .setContentText("Download in progress")
868    .setSmallIcon(R.drawable.ic_notification);
869// Start a lengthy operation in a background thread
870new Thread(
871    new Runnable() {
872        &#64;Override
873        public void run() {
874            int incr;
875            // Do the "lengthy" operation 20 times
876            for (incr = 0; incr &lt;= 100; incr+=5) {
877                    // Sets the progress indicator to a max value, the
878                    // current completion percentage, and "determinate"
879                    // state
880                    mBuilder.setProgress(100, incr, false);
881                    // Displays the progress bar for the first time.
882                    mNotifyManager.notify(0, mBuilder.build());
883                        // Sleeps the thread, simulating an operation
884                        // that takes time
885                        try {
886                            // Sleep for 5 seconds
887                            Thread.sleep(5*1000);
888                        } catch (InterruptedException e) {
889                            Log.d(TAG, "sleep failure");
890                        }
891            }
892            // When the loop is finished, updates the notification
893            mBuilder.setContentText("Download complete")
894            // Removes the progress bar
895                    .setProgress(0,0,false);
896            mNotifyManager.notify(ID, mBuilder.build());
897        }
898    }
899// Starts the thread by calling the run() method in its Runnable
900).start();
901</pre>
902<p>
903    The resulting notifications are shown in figure 6. On the left side is a snapshot of the
904    notification during the operation; on the right side is a snapshot of it after the operation
905    has finished.
906</p>
907<img
908    id="figure6"
909    src="{@docRoot}images/ui/notifications/progress_bar_summary.png"
910    height="84"
911    alt="" />
912<p class="img-caption">
913<strong>Figure 6.</strong> The progress bar during and after the operation.</p>
914<!-- ------------------------------------------------------------------------------------------ -->
915<h3 id="ActivityIndicator">Displaying a continuing activity indicator</h3>
916<p>
917    To display an indeterminate activity indicator, add it to your notification with
918    {@link android.support.v4.app.NotificationCompat.Builder#setProgress setProgress(0, 0, true)}
919    (the first two arguments are ignored), and issue the notification. The result is an indicator
920    that has the same style as a progress bar, except that its animation is ongoing.
921</p>
922<p>
923    Issue the notification at the beginning of the operation. The animation will run until you
924    modify your notification. When the operation is done, call
925    {@link android.support.v4.app.NotificationCompat.Builder#setProgress setProgress()
926    setProgress(0, 0, false)} and then update the notification to remove the activity indicator.
927    Always do this; otherwise, the animation will run even when the operation is complete. Also
928    remember to change the notification text to indicate that the operation is complete.
929</p>
930<p>
931    To see how activity indicators work, refer to the preceding snippet. Locate the following lines:
932</p>
933<pre>
934// Sets the progress indicator to a max value, the current completion
935// percentage, and "determinate" state
936mBuilder.setProgress(100, incr, false);
937// Issues the notification
938mNotifyManager.notify(0, mBuilder.build());
939</pre>
940<p>
941    Replace the lines you've found with the following lines:
942</p>
943<pre>
944 // Sets an activity indicator for an operation of indeterminate length
945mBuilder.setProgress(0, 0, true);
946// Issues the notification
947mNotifyManager.notify(0, mBuilder.build());
948</pre>
949<p>
950    The resulting indicator is shown in figure 7:
951</p>
952<img
953    id="figure7"
954    src="{@docRoot}images/ui/notifications/activity_indicator.png"
955    height="99"
956    alt="" />
957<p class="img-caption"><strong>Figure 7.</strong> An ongoing activity indicator.</p>
958
959<!-- ------------------------------------------------------------------------------------------ -->
960<!-- ------------------------------------------------------------------------------------------ -->
961<!-- ------------------------------------------------------------------------------------------ -->
962
963<!-- ------------------------------------------------------------------------------------------ -->
964<h2 id="CustomNotification">Custom Notification Layouts</h2>
965<p>
966    The notifications framework allows you to define a custom notification layout, which
967    defines the notification's appearance in a {@link android.widget.RemoteViews} object.
968    Custom layout notifications are similar to normal notifications, but they're based on a
969    {@link android.widget.RemoteViews} defined in a XML layout file.
970</p>
971<p>
972    The height available for a custom notification layout depends on the notification view. Normal
973    view layouts are limited to 64 dp, and expanded view layouts are limited to 256 dp.
974</p>
975<p>
976    To define a custom notification layout, start by instantiating a
977    {@link android.widget.RemoteViews} object that inflates an XML layout file. Then,
978    instead of calling methods such as
979    {@link android.support.v4.app.NotificationCompat.Builder#setContentTitle setContentTitle()},
980    call {@link android.support.v4.app.NotificationCompat.Builder#setContent setContent()}. To set
981    content details in the custom notification, use the methods in
982    {@link android.widget.RemoteViews} to set the values of the view's children:
983</p>
984<ol>
985    <li>
986        Create an XML layout for the notification in a separate file. You can use any file name
987        you wish, but you must use the extension <code>.xml</code>
988    </li>
989    <li>
990        In your app, use {@link android.widget.RemoteViews} methods to define your notification's
991        icons and text. Put this {@link android.widget.RemoteViews} object into your
992        {@link android.support.v4.app.NotificationCompat.Builder} by calling
993        {@link android.support.v4.app.NotificationCompat.Builder#setContent setContent()}. Avoid
994        setting a background {@link android.graphics.drawable.Drawable} on your
995        {@link android.widget.RemoteViews} object, because your text color may become unreadable.
996    </li>
997</ol>
998<p>
999    The {@link android.widget.RemoteViews} class also includes methods that you can use to easily
1000    add a {@link android.widget.Chronometer} or {@link android.widget.ProgressBar}
1001    to your notification's layout. For more information about creating custom layouts for your
1002    notification, refer to the {@link android.widget.RemoteViews} reference documentation.
1003</p>
1004<p class="caution">
1005    <strong>Caution:</strong> When you use a custom notification layout, take special care to
1006    ensure that your custom layout works with different device orientations and resolutions. While
1007    this advice applies to all View layouts, it's especially important for notifications because
1008    the space in the notification drawer is very restricted. Don't make your custom layout too
1009    complex, and be sure to test it in various configurations.
1010</p>
1011<!-- ------------------------------------------------------------------------------------------ -->
1012<h4>Using style resources for custom notification text</h4>
1013<p>
1014    Always use style resources for the text of a custom notification. The background color of the
1015    notification can vary across different devices and versions, and using style resources
1016    helps you account for this. Starting in Android 2.3, the system defined a style for the
1017    standard notification layout text. If you use the same style in applications that target Android
1018    2.3 or higher, you'll ensure that your text is visible against the display background.
1019</p>
1020