Home | History | Annotate | Download | only in notifiers
      1 page.title=Notifications
      2 page.image=images/android-7.0/notifications-card.png
      3 page.tags="notifications", "alerts"
      4 @jd:body
      5 
      6 <div id="qv-wrapper">
      7 <div id="qv">
      8 <h2>In this document</h2>
      9 <ol>
     10   <li><a href="#Design">Design Considerations</a></li>
     11   <li><a href="#CreateNotification">Creating a Notification</a>
     12     <ol>
     13       <li><a href="#Required">Required notification contents</a></li>
     14       <li><a href="#Optional">Optional notification contents and settings</a></li>
     15       <li><a href="#Actions">Notification actions</a></li>
     16       <li><a href="#Priority">Notification priority</a></li>
     17       <li><a href="#SimpleNotification">Creating a simple notification</a></li>
     18       <li><a href="#ApplyStyle">Applying an expanded layout to a notification</a></li>
     19       <li><a href="#Compatibility">Handling compatibility</a></li>
     20     </ol>
     21   </li>
     22   <li><a href="#Managing">Managing Notifications</a>
     23     <ol>
     24       <li><a href="#Updating">Updating notifications</a></li>
     25       <li><a href="#Removing">Removing notifications</a></li>
     26       <li><a href="#direct">Replying to notifications</a></li>
     27       <li><a href="#bundle">Bundling notifications</a></li>
     28     </ol>
     29   </li>
     30   <li><a href="#NotificationResponse">Preserving Navigation when Starting an Activity</a>
     31     <ol>
     32       <li><a href="#DirectEntry">Setting up a regular activity PendingIntent</a></li>
     33       <li><a href="#ExtendedNotification">Setting up a special activity PendingIntent</a></li>
     34     </ol>
     35   </li>
     36   <li><a href="#Progress">Displaying Progress in a Notification</a>
     37     <ol>
     38       <li><a href="#FixedProgress">Displaying a fixed-duration progress indicator</a></li>
     39       <li><a href="#ActivityIndicator">Displaying a continuing activity indicator</a></li>
     40     </ol>
     41   </li>
     42   <li><a href="#metadata">Notification Metadata</a></li>
     43   <li><a href="#Heads-up">Heads-up Notifications</a></li>
     44   <li><a href="#lockscreenNotification">Lock Screen Notifications</a>
     45     <ol>
     46       <li><a href="#visibility">Setting Visibility</a></li>
     47       <li><a href="#controllingMedia">Controlling Media Playback on the Lock Screen</a></li>
     48     </ol>
     49   </li>
     50   <li><a href="#CustomNotification">Customizing Notifications</a>
     51     <ol>
     52       <li><a href="#custom">Custom Views</a></li>
     53       <li><a href="#style">Messaging Style</a></li>
     54     </ol>
     55   </li>
     56 </ol>
     57 
     58     <h2>Key classes</h2>
     59     <ol>
     60         <li>{@link android.app.NotificationManager}</li>
     61         <li>{@link android.support.v4.app.NotificationCompat}</li>
     62     </ol>
     63     <h2>Videos</h2>
     64     <ol>
     65         <li>
     66             <a href="http://www.youtube.com/watch?v=Yc8YrVc47TI&feature=player_detailpage#t=1672s">
     67             Notifications in 4.1</a>
     68         </li>
     69     </ol>
     70 <h2>See also</h2>
     71 <ol>
     72     <li>
     73         <a href="https://material.google.com/patterns/notifications.html">Material Design: Notifications</a>
     74     </li>
     75 </ol>
     76 </div>
     77 </div>
     78 <p>
     79     A notification is a message you can display to the user outside of your application's
     80     normal UI. When you tell the system to issue a notification, it first appears as an icon in the
     81     <strong>notification area</strong>. To see the details of the notification, the user opens the
     82     <strong>notification drawer</strong>. Both the notification area and the notification drawer
     83     are system-controlled areas that the user can view at any time.
     84 </p>
     85 <img
     86     id="figure1"
     87     src="{@docRoot}images/ui/notifications/notification_area.png"
     88     height="" alt="" />
     89 <p class="img-caption">
     90     <strong>Figure 1.</strong> Notifications in the notification area.
     91 </p>
     92 <img id="figure2" src="{@docRoot}images/ui/notifications/notification_drawer.png"
     93      width="280px" alt="" />
     94 <p class="img-caption">
     95     <strong>Figure 2.</strong> Notifications in the notification drawer.
     96 </p>
     97 
     98 <p class="note"><strong>Note:</strong> Except where noted, this guide refers to the
     99 {@link android.support.v4.app.NotificationCompat.Builder NotificationCompat.Builder} class
    100 in the version 4 <a href="{@docRoot}tools/support-library/index.html">Support Library</a>.
    101 The class {@link android.app.Notification.Builder Notification.Builder} was added in Android
    102 3.0 (API level 11).</p>
    103 
    104 <h2 id="Design">Design Considerations</h2>
    105 
    106 <p>Notifications, as an important part of the Android user interface, have their own design guidelines.
    107 The material design changes introduced in Android 5.0 (API level 21) are of particular
    108 importance, and you should review the <a href="{@docRoot}training/material/index.html">Material
    109 Design</a> training for more information. To learn how to design notifications and their interactions,
    110 read the <a href="https://material.google.com/patterns/notifications.html">Notifications</a> design guide.</p>
    111 
    112 <h2 id="CreateNotification">Creating a Notification</h2>
    113 
    114 <p>You specify the UI information and actions for a notification in a
    115 {@link android.support.v4.app.NotificationCompat.Builder NotificationCompat.Builder} object.
    116 To create the notification itself, you call
    117 {@link android.support.v4.app.NotificationCompat.Builder#build NotificationCompat.Builder.build()},
    118 which returns a {@link android.app.Notification} object containing your specifications. To issue the
    119 notification, you pass the {@link android.app.Notification} object to the system by calling
    120 {@link android.app.NotificationManager#notify(int, android.app.Notification) NotificationManager.notify()}.</p>
    121 
    122 <h3 id="Required">Required notification contents</h3>
    123 <p>
    124     A {@link android.app.Notification} object <em>must</em> contain the following:
    125 </p>
    126 <ul>
    127     <li>
    128         A small icon, set by
    129         {@link android.support.v4.app.NotificationCompat.Builder#setSmallIcon setSmallIcon()}
    130     </li>
    131     <li>
    132         A title, set by
    133         {@link android.support.v4.app.NotificationCompat.Builder#setContentTitle setContentTitle()}
    134     </li>
    135     <li>
    136         Detail text, set by
    137         {@link android.support.v4.app.NotificationCompat.Builder#setContentText setContentText()}
    138     </li>
    139 </ul>
    140 <h3 id="Optional">Optional notification contents and settings</h3>
    141 <p>
    142     All other notification settings and contents are optional. To learn more about them,
    143     see the reference documentation for {@link android.support.v4.app.NotificationCompat.Builder}.
    144 </p>
    145 <!-- ------------------------------------------------------------------------------------------ -->
    146 <h3 id="Actions">Notification actions</h3>
    147 <p>
    148     Although they're optional, you should add at least one action to your notification.
    149     An action allows users to go directly from the notification to an
    150     {@link android.app.Activity} in your application, where they can look at one or more events
    151     or do further work.
    152 </p>
    153 <p>
    154     A notification can provide multiple actions. You should always define the action that's
    155     triggered when the user clicks the notification; usually this action opens an
    156     {@link android.app.Activity} in your application. You can also add buttons to the notification
    157     that perform additional actions such as snoozing an alarm or responding immediately to a text
    158     message; this feature is available as of Android 4.1. If you use additional action buttons, you
    159     must also make their functionality available in an {@link android.app.Activity} in your app; see
    160     the section <a href="#Compatibility">Handling compatibility</a> for more details.
    161 </p>
    162 <p>
    163     Inside a {@link android.app.Notification}, the action itself is defined by a
    164     {@link android.app.PendingIntent} containing an
    165     {@link android.content.Intent} that starts
    166     an {@link android.app.Activity} in your application. To associate the
    167     {@link android.app.PendingIntent} with a gesture, call the appropriate method of
    168     {@link android.support.v4.app.NotificationCompat.Builder}. For example, if you want to start
    169     {@link android.app.Activity} when the user clicks the notification text in
    170     the notification drawer, you add the {@link android.app.PendingIntent} by calling
    171     {@link android.support.v4.app.NotificationCompat.Builder#setContentIntent setContentIntent()}.
    172 </p>
    173 <p>
    174     Starting an {@link android.app.Activity} when the user clicks the notification is the most
    175     common action scenario. You can also start an {@link android.app.Activity} when the user
    176     dismisses a notification. In Android 4.1 and later, you can start an
    177     {@link android.app.Activity} from an action button. To learn more, read the reference guide for
    178     {@link android.support.v4.app.NotificationCompat.Builder}.
    179 </p>
    180 <!-- ------------------------------------------------------------------------------------------ -->
    181 <h3 id="Priority">Notification priority</h3>
    182 <p>
    183     If you wish, you can set the priority of a notification. The priority acts
    184     as a hint to the device UI about how the notification should be displayed.
    185     To set a notification's priority, call {@link
    186     android.support.v4.app.NotificationCompat.Builder#setPriority(int)
    187     NotificationCompat.Builder.setPriority()} and pass in one of the {@link
    188     android.support.v4.app.NotificationCompat} priority constants. There are
    189     five priority levels, ranging from {@link
    190     android.support.v4.app.NotificationCompat#PRIORITY_MIN} (-2) to {@link
    191     android.support.v4.app.NotificationCompat#PRIORITY_MAX} (2); if not set, the
    192     priority defaults to {@link
    193     android.support.v4.app.NotificationCompat#PRIORITY_DEFAULT} (0).
    194 </p>
    195 <p> For information about setting an appropriate priority level, see "Correctly
    196     set and manage notification priority" in the <a
    197     href="https://material.google.com/patterns/notifications.html">Notifications</a> Design
    198     guide.
    199 </p>
    200 <!-- ------------------------------------------------------------------------------------------ -->
    201 <h3 id="SimpleNotification">Creating a simple notification</h3>
    202 <p>
    203     The following snippet illustrates a simple notification that specifies an activity to open when
    204     the user clicks the notification. Notice that the code creates a
    205     {@link android.support.v4.app.TaskStackBuilder} object and uses it to create the
    206     {@link android.app.PendingIntent} for the action. This pattern is explained in more detail
    207     in the section <a href="#NotificationResponse">
    208     Preserving Navigation when Starting an Activity</a>:
    209 </p>
    210 <pre>
    211 NotificationCompat.Builder mBuilder =
    212         new NotificationCompat.Builder(this)
    213         .setSmallIcon(R.drawable.notification_icon)
    214         .setContentTitle("My notification")
    215         .setContentText("Hello World!");
    216 // Creates an explicit intent for an Activity in your app
    217 Intent resultIntent = new Intent(this, ResultActivity.class);
    218 
    219 // The stack builder object will contain an artificial back stack for the
    220 // started Activity.
    221 // This ensures that navigating backward from the Activity leads out of
    222 // your application to the Home screen.
    223 TaskStackBuilder stackBuilder = TaskStackBuilder.create(this);
    224 // Adds the back stack for the Intent (but not the Intent itself)
    225 stackBuilder.addParentStack(ResultActivity.class);
    226 // Adds the Intent that starts the Activity to the top of the stack
    227 stackBuilder.addNextIntent(resultIntent);
    228 PendingIntent resultPendingIntent =
    229         stackBuilder.getPendingIntent(
    230             0,
    231             PendingIntent.FLAG_UPDATE_CURRENT
    232         );
    233 mBuilder.setContentIntent(resultPendingIntent);
    234 NotificationManager mNotificationManager =
    235     (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
    236 // mId allows you to update the notification later on.
    237 mNotificationManager.notify(mId, mBuilder.build());
    238 </pre>
    239 <p>That's it. Your user has now been notified.</p>
    240 <!-- ------------------------------------------------------------------------------------------ -->
    241 <h3 id="ApplyStyle">Applying an expanded layout to a notification</h3>
    242 <p>
    243     To have a notification appear in an expanded view, first create a
    244     {@link android.support.v4.app.NotificationCompat.Builder} object with the normal view options
    245     you want. Next, call {@link android.support.v4.app.NotificationCompat.Builder#setStyle
    246     Builder.setStyle()} with an expanded layout object as its argument.
    247 </p>
    248 <p>
    249     Remember that expanded notifications are not available on platforms prior to Android 4.1. To
    250     learn how to handle notifications for Android 4.1 and for earlier platforms, read the
    251     section <a href="#Compatibility">Handling compatibility</a>.
    252 </p>
    253 <p>
    254     For example, the following code snippet demonstrates how to alter the notification created
    255     in the previous snippet to use the expanded layout:
    256 </p>
    257 <pre>
    258 NotificationCompat.Builder mBuilder = new NotificationCompat.Builder(this)
    259     .setSmallIcon(R.drawable.notification_icon)
    260     .setContentTitle("Event tracker")
    261     .setContentText("Events received")
    262 NotificationCompat.InboxStyle inboxStyle =
    263         new NotificationCompat.InboxStyle();
    264 String[] events = new String[6];
    265 // Sets a title for the Inbox in expanded layout
    266 inboxStyle.setBigContentTitle("Event tracker details:");
    267 ...
    268 // Moves events into the expanded layout
    269 for (int i=0; i &lt; events.length; i++) {
    270 
    271     inboxStyle.addLine(events[i]);
    272 }
    273 // Moves the expanded layout object into the notification object.
    274 mBuilder.setStyle(inBoxStyle);
    275 ...
    276 // Issue the notification here.
    277 </pre>
    278 
    279 <h3 id="Compatibility">Handling compatibility</h3>
    280 
    281 <p>
    282     Not all notification features are available for a particular version, even though
    283     the methods to set them are in the support library class
    284     {@link android.support.v4.app.NotificationCompat.Builder NotificationCompat.Builder}.
    285     For example, action buttons, which depend on expanded notifications, only appear on Android
    286     4.1 and higher, because expanded notifications themselves are only available on
    287     Android 4.1 and higher.
    288 </p>
    289 <p>
    290     To ensure the best compatibility, create notifications with
    291     {@link android.support.v4.app.NotificationCompat NotificationCompat} and its subclasses,
    292     particularly {@link android.support.v4.app.NotificationCompat.Builder
    293     NotificationCompat.Builder}. In addition, follow this process when you implement a notification:
    294 </p>
    295 <ol>
    296     <li>
    297         Provide all of the notification's functionality to all users, regardless of the version
    298         they're using. To do this, verify that all of the functionality is available from an
    299         {@link android.app.Activity} in your app. You may want to add a new
    300         {@link android.app.Activity} to do this.
    301         <p>
    302             For example, if you want to use
    303             {@link android.support.v4.app.NotificationCompat.Builder#addAction addAction()} to
    304             provide a control that stops and starts media playback, first implement this
    305             control in an {@link android.app.Activity} in your app.
    306         </p>
    307     </li>
    308     <li>
    309         Ensure that all users can get to the functionality in the {@link android.app.Activity},
    310         by having it start when users click the notification. To do this,
    311         create a {@link android.app.PendingIntent}
    312         for the {@link android.app.Activity}. Call
    313         {@link android.support.v4.app.NotificationCompat.Builder#setContentIntent
    314         setContentIntent()} to add the {@link android.app.PendingIntent} to the notification.
    315     </li>
    316     <li>
    317         Now add the expanded notification features you want to use to the notification. Remember
    318         that any functionality you add also has to be available in the {@link android.app.Activity}
    319         that starts when users click the notification.
    320     </li>
    321 </ol>
    322 
    323 
    324 <!-- ------------------------------------------------------------------------------------------ -->
    325 <!-- ------------------------------------------------------------------------------------------ -->
    326 <h2 id="Managing">Managing Notifications</h2>
    327 <p>
    328     When you need to issue a notification multiple times for the same type of event, you
    329     should avoid making a completely new notification. Instead, you should consider updating a
    330     previous notification, either by changing some of its values or by adding to it, or both.
    331 </p>
    332 <p>
    333     For example, Gmail notifies the user that new emails have arrived by increasing its count of
    334     unread messages and by adding a summary of each email to the notification. This is called
    335     "stacking" the notification; it's described in more detail in the
    336     <a href="https://material.google.com/patterns/notifications.html">Notifications</a> Design guide.
    337 </p>
    338 <p class="note">
    339     <strong>Note:</strong> This Gmail feature requires the "inbox" expanded layout, which is part
    340     of the expanded notification feature.
    341 </p>
    342 <p>
    343     The following section describes how to update notifications and also how to remove them.
    344 </p>
    345 <h3 id="Updating">Updating notifications</h3>
    346 <p>
    347     To set up a notification so it can be updated, issue it with a notification ID by
    348     calling {@link android.app.NotificationManager#notify(int, android.app.Notification) NotificationManager.notify()}.
    349     To update this notification once you've issued
    350     it, update or create a {@link android.support.v4.app.NotificationCompat.Builder} object,
    351     build a {@link android.app.Notification} object from it, and issue the
    352     {@link android.app.Notification} with the same ID you used previously. If
    353     the previous notification is still visible, the system updates it from the contents of
    354     the {@link android.app.Notification} object. If the previous notification has been dismissed, a
    355     new notification is created instead.
    356 </p>
    357 <p>
    358     The following snippet demonstrates a notification that is updated to reflect the
    359     number of events that have occurred. It stacks the notification, showing a summary:
    360 </p>
    361 <pre>
    362 mNotificationManager =
    363         (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
    364 // Sets an ID for the notification, so it can be updated
    365 int notifyID = 1;
    366 mNotifyBuilder = new NotificationCompat.Builder(this)
    367     .setContentTitle("New Message")
    368     .setContentText("You've received new messages.")
    369     .setSmallIcon(R.drawable.ic_notify_status)
    370 numMessages = 0;
    371 // Start of a loop that processes data and then notifies the user
    372 ...
    373     mNotifyBuilder.setContentText(currentText)
    374         .setNumber(++numMessages);
    375     // Because the ID remains unchanged, the existing notification is
    376     // updated.
    377     mNotificationManager.notify(
    378             notifyID,
    379             mNotifyBuilder.build());
    380 ...
    381 </pre>
    382 
    383 <!-- ------------------------------------------------------------------------------------------ -->
    384 <h3 id="Removing">Removing notifications</h3>
    385 <p>
    386     Notifications remain visible until one of the following happens:
    387 </p>
    388 <ul>
    389     <li>
    390         The user dismisses the notification either individually or by using "Clear All" (if
    391         the notification can be cleared).
    392     </li>
    393     <li>
    394         The user clicks the notification, and you called
    395         {@link android.support.v4.app.NotificationCompat.Builder#setAutoCancel setAutoCancel()} when
    396         you created the notification.
    397     </li>
    398     <li>
    399         You call {@link android.app.NotificationManager#cancel(int) cancel()} for a specific
    400         notification ID. This method also deletes ongoing notifications.
    401     </li>
    402     <li>
    403         You call {@link android.app.NotificationManager#cancelAll() cancelAll()}, which removes
    404         all of the notifications you previously issued.
    405     </li>
    406 </ul>
    407 
    408 <!--------------------------------------------------------------- -->
    409 <h2 id="direct">Replying to notifications</h2>
    410 
    411 <p>
    412   Starting in Android 7.0 (API level 24),
    413   users can respond directly to text messages or update task lists
    414   from within the notification
    415   dialog. On a handheld, the inline reply action appears as an additional
    416   button
    417   displayed in the notification. When a user replies via keyboard, the system
    418   attaches the text response to the intent
    419   you had specified for the notification action and sends the intent to your
    420   handheld app.
    421 </p>
    422 
    423 <img id="fig-reply-button" src="{@docRoot}images/android-7.0/inline-reply.png"
    424   srcset="{@docRoot}images/android-7.0/inline-reply.png 1x,
    425   {@docRoot}images/android-7.0/inline-reply_2x.png 2x"
    426   width="400">
    427 <p class="img-caption">
    428   <strong>Figure 1.</strong> The <strong>Reply</strong> action button.
    429 </p>
    430 
    431 <h3>Adding inline reply actions</h3>
    432 
    433 <p>To create a notification action that supports direct reply:
    434 </p>
    435 
    436 <ol>
    437 <li>Create an instance of {@link android.support.v4.app.RemoteInput.Builder}
    438   that you can add to your notification
    439 action. This class's constructor accepts a string that the system uses as the key
    440  for the text input. Later, your handheld app uses that key to retrieve the text
    441   of the input.
    442 
    443 <pre>
    444 // Key for the string that's delivered in the action's intent.
    445 private static final String KEY_TEXT_REPLY = "key_text_reply";
    446 String replyLabel = getResources().getString(R.string.reply_label);
    447 RemoteInput remoteInput = new RemoteInput.Builder(KEY_TEXT_REPLY)
    448         .setLabel(replyLabel)
    449         .build();
    450 </pre>
    451 </li>
    452 <li>Attach the {@link android.support.v4.app.RemoteInput}
    453  object to an action using <code>addRemoteInput()</code>.
    454 
    455 <pre>
    456 // Create the reply action and add the remote input.
    457 Notification.Action action =
    458         new Notification.Action.Builder(R.drawable.ic_reply_icon,
    459                 getString(R.string.label), replyPendingIntent)
    460                 .addRemoteInput(remoteInput)
    461                 .build();
    462 </pre>
    463 </li>
    464 
    465 <li>Apply the action to a notification and issue the notification.
    466 
    467 <pre>
    468 // Build the notification and add the action.
    469 Notification newMessageNotification =
    470         new Notification.Builder(mContext)
    471                 .setSmallIcon(R.drawable.ic_message)
    472                 .setContentTitle(getString(R.string.title))
    473                 .setContentText(getString(R.string.content))
    474                 .addAction(action))
    475                 .build();
    476 
    477 // Issue the notification.
    478 NotificationManager notificationManager =
    479         NotificationManager.from(mContext);
    480 notificationManager.notify(notificationId, newMessageNotification);
    481 
    482 </pre>
    483 </li>
    484 
    485 </ol>
    486 
    487 
    488 <p> The system prompts the user to input a response when they trigger the
    489 notification action. </p>
    490 
    491 <img id="fig-user-input" src="{@docRoot}images/android-7.0/inline-type-reply.png"
    492     srcset="{@docRoot}images/android-7.0/inline-type-reply.png 1x,
    493     {@docRoot}images/android-7.0/inline-type-reply_2x.png 2x"
    494     width="300">
    495 <p class="img-caption">
    496   <strong>Figure 2.</strong> The user inputs text from the notification shade.
    497 </p>
    498 
    499 <h3>
    500   Retrieving user input from the inline reply
    501 </h3>
    502 
    503 <p>
    504   To receive user input from the notification interface to the activity you
    505   declared in the reply action's intent:
    506 </p>
    507 
    508 <ol>
    509   <li>Call {@link android.support.v4.app.RemoteInput#getResultsFromIntent
    510   getResultsFromIntent()} by passing the notification actions intent as the
    511   input parameter. This method returns a {@link android.os.Bundle} that
    512   contains the text response.
    513 
    514     <pre>
    515 Bundle remoteInput = RemoteInput.getResultsFromIntent(intent);
    516 </pre>
    517   </li>
    518 
    519   <li>Query the bundle using the result key (provided to the {@link
    520   android.support.v4.app.RemoteInput.Builder} constructor). You can complete
    521   this process and retrieve the input text by creating a method, as in the
    522   following code snippet:
    523 
    524     <pre>
    525 // Obtain the intent that started this activity by calling
    526 // Activity.getIntent() and pass it into this method to
    527 // get the associated string.
    528 
    529 private CharSequence getMessageText(Intent intent) {
    530     Bundle remoteInput = RemoteInput.getResultsFromIntent(intent);
    531     if (remoteInput != null) {
    532         return remoteInput.getCharSequence(KEY_TEXT_REPLY);
    533     }
    534     return null;
    535  }
    536 </pre>
    537   </li>
    538 
    539   <li>Build and issue another notification, using the same notification ID that
    540     you provided for the previous notification. The progress indicator
    541     disappears from the notification interface to inform users of a successful
    542     reply. When working with this new notification, use the context that gets
    543     passed to the receiver's {@code onReceive()} method.
    544 
    545     <pre>
    546 // Build a new notification, which informs the user that the system
    547 // handled their interaction with the previous notification.
    548 Notification repliedNotification =
    549         new Notification.Builder(context)
    550                 .setSmallIcon(R.drawable.ic_message)
    551                 .setContentText(getString(R.string.replied))
    552                 .build();
    553 
    554 // Issue the new notification.
    555 NotificationManager notificationManager =
    556         NotificationManager.from(context);
    557 notificationManager.notify(notificationId, repliedNotification);
    558 </pre>
    559   </li>
    560 </ol>
    561 
    562 <p>
    563   For interactive apps, such as chats, you can include additional
    564   context when handling retrieved text. For example, these apps could show
    565   multiple lines of chat history. When the user responds via {@link
    566   android.support.v4.app.RemoteInput}, you can update the reply history
    567   using the {@code setRemoteInputHistory()} method.
    568 </p>
    569 
    570 <p>
    571   The notification must be either updated or cancelled after the app has
    572   received remote input. When the user replies to a remote update
    573   using Direct Reply,
    574   do not cancel the notification. Instead, update the notification
    575   to display the user's reply.
    576   For notifications using {@code MessagingStyle}, you should add
    577   the reply as the latest message. When using other templates, you can
    578   append the user's reply to the remote-input history.
    579 </p>
    580 
    581 <!-------------------------------------------------------------------------- -->
    582 
    583 <h2 id="bundle">Bundling notifications</h2>
    584 
    585 <p>
    586   Starting in Android 7.0 (API level 24),
    587   Android provides developers with a new way to represent
    588   a queue of notifications: <i>bundled notifications</i>. This is similar to the
    589   <a href="{@docRoot}training/wearables/notifications/stacks.html">Notification
    590   Stacks</a> feature in Android Wear. For example, if your app
    591   creates notifications
    592   for received messages, when more than one message is received, bundle the
    593   notifications together as a single group. You can
    594   use the {@link android.support.v4.app.NotificationCompat.Builder#setGroup
    595   Builder.setGroup()} method to bundle similar notifications.</p>
    596 
    597 <p>
    598   A notification group imposes a hierarchy on the notifications comprising it.
    599   At the top of that hierarchy is a parent notification that displays summary
    600   information for the group. The user can progressively
    601   expand the notification group, and the system shows more information as the
    602   user drills deeper. When the user expands the bundle, the system reveals more
    603   information for all its child notifications; when the user
    604   expands one of those notifications, the system reveals its entire content.
    605 </p>
    606 
    607 <img id="fig-bundles" src="{@docRoot}images/android-7.0/bundles.png"
    608   srcset="{@docRoot}images/android-7.0/bundles.png 1x,
    609           {@docRoot}images/android-7.0/bundles_2x.png 2x"
    610   width="300">
    611 <p class="img-caption">
    612   <strong>Figure 3.</strong> The user can progressively expand the notification
    613   group.
    614 </p>
    615 
    616 <p class="note">
    617   <strong>Note:</strong> If the same app sends four or more notifications
    618   and does not specify a grouping, the
    619   system automatically groups them together.
    620 </p>
    621 
    622 <p>To learn how to add notifications to a group, see
    623 <a href="{@docRoot}training/wearables/notifications/stacks.html#AddGroup">Add
    624 Each Notification to a Group</a>.</p>
    625 
    626 
    627 <h3 id="best-practices">Best practices for bundled notifications</h3>
    628 <p>This section provides guidelines about when to use notification groups instead
    629 of the {@link android.app.Notification.InboxStyle InboxStyle}
    630 notifications available in Android 6.0 and previous versions.</p>
    631 
    632 <h3>When to use bundled notifications</h3>
    633 
    634 <p>You should use notification groups only if all of the following conditions are
    635 true for your use case:</p>
    636 
    637 <ul>
    638   <li>The child notifications are complete notifications and can be displayed
    639    individually without the need for a group summary.</li>
    640   <li>There is a benefit to surfacing the child notifications individually. For
    641   example:
    642   </li>
    643   <ul>
    644     <li>They are actionable, with actions specific to each child.</li>
    645     <li>There is more information to the child that the user wants to read.</li>
    646   </ul>
    647 </ul>
    648 
    649 <p>Examples of good use cases for notification groups include: a messaging app
    650 displaying a list of incoming messages, or an email app displaying a list of
    651 received emails.</p>
    652 
    653 <p>
    654 Examples of cases where a single notification is preferable
    655  include individual messages from a single person, or a list representation of
    656  single-line text items. You can use
    657 ({@link android.app.Notification.InboxStyle InboxStyle} or
    658 {@link android.app.Notification.BigTextStyle BigTextStyle}) to accomplish
    659 this.
    660 </p>
    661 
    662 <h3 id ="post">Displaying bundled notifications</h3>
    663 
    664 <p>
    665   The app should always post a group summary, even if the group contains just a
    666   single child. The system will suppress the summary and directly display the
    667   child notification if it only contains a single notification. This ensures
    668   that the system can provide a consistent experience when the user swipes away
    669   children of a group.
    670 </p>
    671 
    672 <h3>Peeking notifications</h3>
    673 
    674 <p>While the system usually displays child notifications as a group, you can set
    675  them to temporarily appear as
    676  <a href="{@docRoot}guide/topics/ui/notifiers/notifications.html#Heads-up">
    677  heads-up notifications</a>. This feature is especially useful because it allows
    678   immediate access to the most recent child and the actions associated with it.
    679 </p>
    680 
    681 
    682 <h3>Backwards compatibility</h3>
    683 
    684 <p>
    685   Both notification groups and remote input have been a part of the {@link
    686   android.app.Notification} API since Android 5.0 (API level 21) to support
    687   Android Wear devices. If you've already built notifications with these APIs,
    688   the only action you must take is to verify that the app behavior corresponds
    689   to the guidelines described above, and to consider implementing {@code
    690   setRemoteInputHistory()}.
    691 </p>
    692 
    693 <p>
    694   In order to support backward compatibility, the same APIs are available with
    695   the support library's {@link android.support.v4.app.NotificationCompat}
    696   class, allowing you to build notifications that works on versions of Android
    697   less than 5.0 (API level 21).
    698   On handhelds and tablets, users only see the summary notification,
    699   so an app should still have an inbox style or an equivalent notification
    700   representative for the whole information content of the group. As Android
    701   Wear devices allow users to see all child notifications even on older
    702   platform levels, you should build child notifications regardless of API
    703   level.
    704 </p>
    705 
    706 <!-- ------------------------------------------------------------------------------------------ -->
    707 <!-- ------------------------------------------------------------------------------------------ -->
    708 <h2 id="NotificationResponse">Preserving Navigation when Starting an Activity</h2>
    709 <p>
    710     When you start an {@link android.app.Activity} from a notification, you must preserve the
    711     user's expected navigation experience. Clicking <i>Back</i> should take the user back through
    712     the application's normal work flow to the Home screen, and clicking <i>Recents</i> should show
    713     the {@link android.app.Activity} as a separate task. To preserve the navigation experience, you
    714     should start the {@link android.app.Activity} in a fresh task. How you set up the
    715     {@link android.app.PendingIntent} to give you a fresh task depends on the nature of the
    716     {@link android.app.Activity} you're starting. There are two general situations:
    717 </p>
    718 <dl>
    719     <dt>
    720         Regular activity
    721     </dt>
    722     <dd>
    723         You're starting an {@link android.app.Activity} that's part of the application's normal
    724         workflow. In this situation, set up the {@link android.app.PendingIntent} to
    725         start a fresh task, and provide the {@link android.app.PendingIntent} with a back stack
    726         that reproduces the application's normal <i>Back</i> behavior.
    727         <p>
    728             Notifications from the Gmail app demonstrate this. When you click a notification for
    729             a single email message, you see the message itself. Touching <b>Back</b> takes you
    730             backwards through Gmail to the Home screen, just as if you had entered Gmail from the
    731             Home screen rather than entering it from a notification.
    732         </p>
    733         <p>
    734             This happens regardless of the application you were in when you touched the
    735             notification. For example, if you're in Gmail composing a message, and you click a
    736             notification for a single email, you go immediately to that email. Touching <i>Back</i>
    737             takes you to the inbox and then the Home screen, rather than taking you to the
    738             message you were composing.
    739         </p>
    740     </dd>
    741     <dt>
    742         Special activity
    743     </dt>
    744     <dd>
    745         The user only sees this {@link android.app.Activity} if it's started from a notification.
    746         In a sense, the {@link android.app.Activity} extends the notification by providing
    747         information that would be hard to display in the notification itself. For this situation,
    748         set up the {@link android.app.PendingIntent} to start in a fresh task. There's no need to
    749         create a back stack, though, because the started {@link android.app.Activity} isn't part of
    750         the application's activity flow. Clicking <i>Back</i> will still take the user to the
    751         Home screen.
    752     </dd>
    753 </dl>
    754 <!-- ------------------------------------------------------------------------------------------ -->
    755 <h3 id="DirectEntry">Setting up a regular activity PendingIntent</h3>
    756 <p>
    757     To set up a {@link android.app.PendingIntent} that starts a direct entry
    758     {@link android.app.Activity}, follow these steps:
    759 </p>
    760 <ol>
    761     <li>
    762         Define your application's {@link android.app.Activity} hierarchy in the manifest.
    763         <ol style="list-style-type: lower-alpha;">
    764             <li>
    765                 Add support for Android 4.0.3 and earlier. To do this, specify the parent of the
    766                 {@link android.app.Activity} you're starting by adding a
    767 <code><a href="{@docRoot}guide/topics/manifest/meta-data-element.html">&lt;meta-data&gt;</a></code>
    768                 element as the child of the
    769 <code><a href="{@docRoot}guide/topics/manifest/activity-element.html">&lt;activity&gt;</a></code>.
    770                 <p>
    771                     For this element, set
    772 <code><a href="{@docRoot}guide/topics/manifest/meta-data-element.html#nm">android:name</a>="android.support.PARENT_ACTIVITY"</code>.
    773                     Set
    774 <code><a href="{@docRoot}guide/topics/manifest/meta-data-element.html#val">android:value</a>="&lt;parent_activity_name&gt;"</code>
    775                     where <code>&lt;parent_activity_name&gt;</code> is the value of
    776 <code><a href="{@docRoot}guide/topics/manifest/meta-data-element.html#nm">android:name</a></code>
    777                     for the parent
    778 <code><a href="{@docRoot}guide/topics/manifest/activity-element.html">&lt;activity&gt;</a></code>
    779                     element. See the following XML for an example.
    780                 </p>
    781             </li>
    782             <li>
    783                 Also add support for Android 4.1 and later. To do this, add the
    784 <code><a href="{@docRoot}guide/topics/manifest/activity-element.html#parent">android:parentActivityName</a></code>
    785                 attribute to the
    786 <code><a href="{@docRoot}guide/topics/manifest/activity-element.html">&lt;activity&gt;</a></code>
    787                 element of the {@link android.app.Activity} you're starting.
    788             </li>
    789         </ol>
    790         <p>
    791             The final XML should look like this:
    792         </p>
    793 <pre>
    794 &lt;activity
    795     android:name=".MainActivity"
    796     android:label="&#64;string/app_name" &gt;
    797     &lt;intent-filter&gt;
    798         &lt;action android:name="android.intent.action.MAIN" /&gt;
    799         &lt;category android:name="android.intent.category.LAUNCHER" /&gt;
    800     &lt;/intent-filter&gt;
    801 &lt;/activity&gt;
    802 &lt;activity
    803     android:name=".ResultActivity"
    804     android:parentActivityName=".MainActivity"&gt;
    805     &lt;meta-data
    806         android:name="android.support.PARENT_ACTIVITY"
    807         android:value=".MainActivity"/&gt;
    808 &lt;/activity&gt;
    809 </pre>
    810     </li>
    811     <li>
    812         Create a back stack based on the {@link android.content.Intent} that starts the
    813         {@link android.app.Activity}:
    814         <ol style="list-style-type: lower-alpha;">
    815             <li>
    816                 Create the {@link android.content.Intent} to start the {@link android.app.Activity}.
    817             </li>
    818             <li>
    819                 Create a stack builder by calling {@link android.app.TaskStackBuilder#create
    820                 TaskStackBuilder.create()}.
    821             </li>
    822             <li>
    823                 Add the back stack to the stack builder by calling
    824                 {@link android.support.v4.app.TaskStackBuilder#addParentStack addParentStack()}.
    825                 For each {@link android.app.Activity} in the hierarchy you've defined in the
    826                 manifest, the back stack contains an {@link android.content.Intent} object that
    827                 starts the {@link android.app.Activity}. This method also adds flags that start the
    828                 stack in a fresh task.
    829                 <p class="note">
    830                     <strong>Note:</strong> Although the argument to
    831                     {@link android.support.v4.app.TaskStackBuilder#addParentStack addParentStack()}
    832                     is a reference to the started {@link android.app.Activity}, the method call
    833                     doesn't add the {@link android.content.Intent} that starts the
    834                     {@link android.app.Activity}. Instead, that's taken care of in the next step.
    835                 </p>
    836             </li>
    837             <li>
    838                 Add the {@link android.content.Intent} that starts the {@link android.app.Activity}
    839                 from the notification, by calling
    840                 {@link android.support.v4.app.TaskStackBuilder#addNextIntent addNextIntent()}.
    841                 Pass the {@link android.content.Intent} you created in the first step as the
    842                 argument to
    843                 {@link android.support.v4.app.TaskStackBuilder#addNextIntent addNextIntent()}.
    844             </li>
    845             <li>
    846                 If you need to, add arguments to {@link android.content.Intent} objects on the
    847                 stack by calling {@link android.support.v4.app.TaskStackBuilder#editIntentAt
    848                 TaskStackBuilder.editIntentAt()}. This is sometimes necessary to ensure that the
    849                 target {@link android.app.Activity} displays meaningful data when the user navigates
    850                 to it using <i>Back</i>.
    851             </li>
    852             <li>
    853                 Get a {@link android.app.PendingIntent} for this back stack by calling
    854                 {@link android.support.v4.app.TaskStackBuilder#getPendingIntent getPendingIntent()}.
    855                 You can then use this {@link android.app.PendingIntent} as the argument to
    856                 {@link android.support.v4.app.NotificationCompat.Builder#setContentIntent
    857                 setContentIntent()}.
    858             </li>
    859         </ol>
    860      </li>
    861 </ol>
    862 <p>
    863     The following code snippet demonstrates the process:
    864 </p>
    865 <pre>
    866 ...
    867 Intent resultIntent = new Intent(this, ResultActivity.class);
    868 TaskStackBuilder stackBuilder = TaskStackBuilder.create(this);
    869 // Adds the back stack
    870 stackBuilder.addParentStack(ResultActivity.class);
    871 // Adds the Intent to the top of the stack
    872 stackBuilder.addNextIntent(resultIntent);
    873 // Gets a PendingIntent containing the entire back stack
    874 PendingIntent resultPendingIntent =
    875         stackBuilder.getPendingIntent(0, PendingIntent.FLAG_UPDATE_CURRENT);
    876 ...
    877 NotificationCompat.Builder builder = new NotificationCompat.Builder(this);
    878 builder.setContentIntent(resultPendingIntent);
    879 NotificationManager mNotificationManager =
    880     (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
    881 mNotificationManager.notify(id, builder.build());
    882 </pre>
    883 <!-- ------------------------------------------------------------------------------------------ -->
    884 <h3 id="ExtendedNotification">Setting up a special activity PendingIntent</h3>
    885 <p>
    886     The following section describes how to set up a special activity
    887     {@link android.app.PendingIntent}.
    888 </p>
    889 <p>
    890     A special {@link android.app.Activity} doesn't need a back stack, so you don't have to
    891     define its {@link android.app.Activity} hierarchy in the manifest, and you don't have
    892     to call
    893     {@link android.support.v4.app.TaskStackBuilder#addParentStack  addParentStack()} to build a
    894     back stack. Instead, use the manifest to set up the {@link android.app.Activity} task options,
    895     and create the {@link android.app.PendingIntent} by calling
    896     {@link android.app.PendingIntent#getActivity getActivity()}:
    897 </p>
    898 <ol>
    899     <li>
    900         In your manifest, add the following attributes to the
    901 <code><a href="{@docRoot}guide/topics/manifest/activity-element.html">&lt;activity&gt;</a></code>
    902         element for the {@link android.app.Activity}
    903         <dl>
    904             <dt>
    905 <code><a href="{@docRoot}guide/topics/manifest/activity-element.html#nm">android:name</a>="<i>activityclass</i>"</code>
    906             </dt>
    907             <dd>
    908                 The activity's fully-qualified class name.
    909             </dd>
    910             <dt>
    911 <code><a href="{@docRoot}guide/topics/manifest/activity-element.html#aff">android:taskAffinity</a>=""</code>
    912             </dt>
    913             <dd>
    914                 Combined with the
    915                 {@link android.content.Intent#FLAG_ACTIVITY_NEW_TASK FLAG_ACTIVITY_NEW_TASK} flag
    916                 that you set in code, this ensures that this {@link android.app.Activity} doesn't
    917                 go into the application's default task. Any existing tasks that have the
    918                 application's default affinity are not affected.
    919             </dd>
    920             <dt>
    921 <code><a href="{@docRoot}guide/topics/manifest/activity-element.html#exclude">android:excludeFromRecents</a>="true"</code>
    922             </dt>
    923             <dd>
    924                 Excludes the new task from <i>Recents</i>, so that the user can't accidentally
    925                 navigate back to it.
    926             </dd>
    927         </dl>
    928         <p>
    929             This snippet shows the element:
    930         </p>
    931 <pre>
    932 &lt;activity
    933     android:name=".ResultActivity"
    934 ...
    935     android:launchMode="singleTask"
    936     android:taskAffinity=""
    937     android:excludeFromRecents="true"&gt;
    938 &lt;/activity&gt;
    939 ...
    940 </pre>
    941     </li>
    942     <li>
    943         Build and issue the notification:
    944         <ol style="list-style-type: lower-alpha;">
    945             <li>
    946                 Create an {@link android.content.Intent} that starts the
    947                 {@link android.app.Activity}.
    948             </li>
    949             <li>
    950                 Set the {@link android.app.Activity} to start in a new, empty task by calling
    951                 {@link android.content.Intent#setFlags setFlags()} with the flags
    952                 {@link android.content.Intent#FLAG_ACTIVITY_NEW_TASK FLAG_ACTIVITY_NEW_TASK}
    953                 and
    954                 {@link android.content.Intent#FLAG_ACTIVITY_CLEAR_TASK FLAG_ACTIVITY_CLEAR_TASK}.
    955             </li>
    956             <li>
    957                 Set any other options you need for the {@link android.content.Intent}.
    958             </li>
    959             <li>
    960                 Create a {@link android.app.PendingIntent} from the {@link android.content.Intent}
    961                 by calling {@link android.app.PendingIntent#getActivity getActivity()}.
    962                 You can then use this {@link android.app.PendingIntent} as the argument to
    963                 {@link android.support.v4.app.NotificationCompat.Builder#setContentIntent
    964                 setContentIntent()}.
    965             </li>
    966         </ol>
    967     <p>
    968         The following code snippet demonstrates the process:
    969     </p>
    970 <pre>
    971 // Instantiate a Builder object.
    972 NotificationCompat.Builder builder = new NotificationCompat.Builder(this);
    973 // Creates an Intent for the Activity
    974 Intent notifyIntent =
    975         new Intent(this, ResultActivity.class);
    976 // Sets the Activity to start in a new, empty task
    977 notifyIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK
    978                         | Intent.FLAG_ACTIVITY_CLEAR_TASK);
    979 // Creates the PendingIntent
    980 PendingIntent notifyPendingIntent =
    981         PendingIntent.getActivity(
    982         this,
    983         0,
    984         notifyIntent,
    985         PendingIntent.FLAG_UPDATE_CURRENT
    986 );
    987 
    988 // Puts the PendingIntent into the notification builder
    989 builder.setContentIntent(notifyPendingIntent);
    990 // Notifications are issued by sending them to the
    991 // NotificationManager system service.
    992 NotificationManager mNotificationManager =
    993     (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
    994 // Builds an anonymous Notification object from the builder, and
    995 // passes it to the NotificationManager
    996 mNotificationManager.notify(id, builder.build());
    997 </pre>
    998     </li>
    999 </ol>
   1000 <!-- ------------------------------------------------------------------------------------------ -->
   1001 <!-- ------------------------------------------------------------------------------------------ -->
   1002 <h2 id="Progress">Displaying Progress in a Notification</h2>
   1003 <p>
   1004     Notifications can include an animated progress indicator that shows users the status
   1005     of an ongoing operation. If you can estimate how long the operation takes and how much of it
   1006     is complete at any time, use the "determinate" form of the indicator
   1007     (a progress bar). If you can't estimate the length of the operation, use the
   1008     "indeterminate" form of the indicator (an activity indicator).
   1009 </p>
   1010 <p>
   1011     Progress indicators are displayed with the platform's implementation of the
   1012     {@link android.widget.ProgressBar} class.
   1013 </p>
   1014 <p>
   1015     To use a progress indicator on platforms starting with Android 4.0, call
   1016     {@link android.support.v4.app.NotificationCompat.Builder#setProgress setProgress()}. For
   1017     previous versions, you must create your own custom notification layout that
   1018     includes a {@link android.widget.ProgressBar} view.
   1019 </p>
   1020 <p>
   1021     The following sections describe how to display progress in a notification using
   1022     {@link android.support.v4.app.NotificationCompat.Builder#setProgress setProgress()}.
   1023 </p>
   1024 <!-- ------------------------------------------------------------------------------------------ -->
   1025 <h3 id="FixedProgress">Displaying a fixed-duration progress indicator</h3>
   1026 <p>
   1027     To display a determinate progress bar, add the bar to your notification by calling
   1028     {@link android.support.v4.app.NotificationCompat.Builder#setProgress
   1029     setProgress(max, progress, false)} and then issue the notification. As your operation proceeds,
   1030     increment <code>progress</code>, and update the notification. At the end of the operation,
   1031     <code>progress</code> should equal <code>max</code>. A common way to call
   1032     {@link android.support.v4.app.NotificationCompat.Builder#setProgress setProgress()}
   1033     is to set <code>max</code> to 100 and then increment <code>progress</code> as a
   1034     "percent complete" value for the operation.
   1035 </p>
   1036 <p>
   1037     You can either leave the progress bar showing when the operation is done, or remove it. In
   1038     either case, remember to update the notification text to show that the operation is complete.
   1039     To remove the progress bar, call
   1040     {@link android.support.v4.app.NotificationCompat.Builder#setProgress
   1041     setProgress(0, 0, false)}. For example:
   1042 </p>
   1043 <pre>
   1044 ...
   1045 mNotifyManager =
   1046         (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
   1047 mBuilder = new NotificationCompat.Builder(this);
   1048 mBuilder.setContentTitle("Picture Download")
   1049     .setContentText("Download in progress")
   1050     .setSmallIcon(R.drawable.ic_notification);
   1051 // Start a lengthy operation in a background thread
   1052 new Thread(
   1053     new Runnable() {
   1054         &#64;Override
   1055         public void run() {
   1056             int incr;
   1057             // Do the "lengthy" operation 20 times
   1058             for (incr = 0; incr &lt;= 100; incr+=5) {
   1059                     // Sets the progress indicator to a max value, the
   1060                     // current completion percentage, and "determinate"
   1061                     // state
   1062                     mBuilder.setProgress(100, incr, false);
   1063                     // Displays the progress bar for the first time.
   1064                     mNotifyManager.notify(0, mBuilder.build());
   1065                         // Sleeps the thread, simulating an operation
   1066                         // that takes time
   1067                         try {
   1068                             // Sleep for 5 seconds
   1069                             Thread.sleep(5*1000);
   1070                         } catch (InterruptedException e) {
   1071                             Log.d(TAG, "sleep failure");
   1072                         }
   1073             }
   1074             // When the loop is finished, updates the notification
   1075             mBuilder.setContentText("Download complete")
   1076             // Removes the progress bar
   1077                     .setProgress(0,0,false);
   1078             mNotifyManager.notify(ID, mBuilder.build());
   1079         }
   1080     }
   1081 // Starts the thread by calling the run() method in its Runnable
   1082 ).start();
   1083 </pre>
   1084 
   1085 <!-- ------------------------------------------------------------------------------------------ -->
   1086 <h3 id="ActivityIndicator">Displaying a continuing activity indicator</h3>
   1087 <p>
   1088     To display an indeterminate activity indicator, add it to your notification with
   1089     {@link android.support.v4.app.NotificationCompat.Builder#setProgress setProgress(0, 0, true)}
   1090     (the first two arguments are ignored), and issue the notification. The result is an indicator
   1091     that has the same style as a progress bar, except that its animation is ongoing.
   1092 </p>
   1093 <p>
   1094     Issue the notification at the beginning of the operation. The animation will run until you
   1095     modify your notification. When the operation is done, call
   1096     {@link android.support.v4.app.NotificationCompat.Builder#setProgress setProgress(0, 0, false)}
   1097     and then update the notification to remove the activity indicator.
   1098     Always do this; otherwise, the animation will run even when the operation is complete. Also
   1099     remember to change the notification text to indicate that the operation is complete.
   1100 </p>
   1101 <p>
   1102     To see how activity indicators work, refer to the preceding snippet. Locate the following lines:
   1103 </p>
   1104 <pre>
   1105 // Sets the progress indicator to a max value, the current completion
   1106 // percentage, and "determinate" state
   1107 mBuilder.setProgress(100, incr, false);
   1108 // Issues the notification
   1109 mNotifyManager.notify(0, mBuilder.build());
   1110 </pre>
   1111 <p>
   1112     Replace the lines you've found with the following lines:
   1113 </p>
   1114 <pre>
   1115  // Sets an activity indicator for an operation of indeterminate length
   1116 mBuilder.setProgress(0, 0, true);
   1117 // Issues the notification
   1118 mNotifyManager.notify(0, mBuilder.build());
   1119 </pre>
   1120 
   1121 <h2 id="metadata">Notification Metadata</h2>
   1122 
   1123 <p>Notifications may be sorted according to metadata that you assign with the
   1124 following {@link android.support.v4.app.NotificationCompat.Builder} methods:</p>
   1125 
   1126 <ul>
   1127     <li>{@link android.support.v4.app.NotificationCompat.Builder#setCategory(java.lang.String) setCategory()}
   1128     tells the system how to handle your app notifications when the device is in Priority mode
   1129     (for example, if your notification represents an incoming call, instant message, or alarm).</li>
   1130     <li>{@link android.support.v4.app.NotificationCompat.Builder#setPriority(int) setPriority()} causes
   1131     notifications with the priority field set to {@code PRIORITY_MAX} or {@code PRIORITY_HIGH} to
   1132     appear in a small floating window if the notification also has sound or vibration.</li>
   1133     <li>{@link android.support.v4.app.NotificationCompat.Builder#addPerson(java.lang.String) addPerson()}
   1134     allows you to add a list of people to a notification. Your app can use this to signal to the
   1135     system that it should group together notifications from the specified people, or rank notifications
   1136     from these people as being more important.</li>
   1137 </ul>
   1138 
   1139 <div class="figure" style="width:230px">
   1140   <img src="{@docRoot}images/ui/notifications/heads-up.png"
   1141     alt="" width="" height="" id="figure3" />
   1142   <p class="img-caption">
   1143     <strong>Figure 3.</strong> Fullscreen activity showing a heads-up notification
   1144   </p>
   1145 </div>
   1146 
   1147 <h2 id="Heads-up">Heads-up Notifications</h2>
   1148 
   1149 <p>With Android 5.0 (API level 21), notifications can appear in a small floating window
   1150 (also called a <em>heads-up notification</em>) when the device is active
   1151 (that is, the device is unlocked and its screen is on). These notifications
   1152 appear similar to the compact form of your notification, except that the
   1153 heads-up notification also shows action buttons. Users can act on, or dismiss,
   1154 a heads-up notification without leaving the current app.</p>
   1155 
   1156 <p>Examples of conditions that may trigger heads-up notifications include:</p>
   1157 
   1158 <ul>
   1159   <li>The user's activity is in fullscreen mode (the app uses
   1160 {@link android.app.Notification#fullScreenIntent}), or</li>
   1161   <li>The notification has high priority and uses ringtones or
   1162     vibrations</li>
   1163 </ul>
   1164 
   1165 <h2 id="lockscreenNotification">Lock Screen Notifications</h2>
   1166 
   1167 <p>With the release of Android 5.0 (API level 21), notifications may now appear on the lock
   1168 screen. Your app can use this functionality to provide media playback controls and other common
   1169 actions. Users can choose via Settings whether to display notifications on the lock screen, and
   1170 you can designate whether a notification from your app is visible on the lock screen.</p>
   1171 
   1172 <h3 id="visibility">Setting Visibility</h3>
   1173 
   1174 <p>Your app can control the level of detail visible in notifications displayed on a secure
   1175 lock screen. You call {@link android.support.v4.app.NotificationCompat.Builder#setVisibility(int) setVisibility()}
   1176 and specify one of the following values:</p>
   1177 
   1178 <ul>
   1179     <li>{@link android.support.v4.app.NotificationCompat#VISIBILITY_PUBLIC} shows the notification's
   1180     full content.</li>
   1181     <li>{@link android.support.v4.app.NotificationCompat#VISIBILITY_SECRET} doesn't show any part of
   1182     this notification on the lock screen.</li>
   1183     <li>{@link android.support.v4.app.NotificationCompat#VISIBILITY_PRIVATE} shows basic information,
   1184     such as the notification's icon and the content title, but hides the notification's full content.</li>
   1185 </ul>
   1186 
   1187 <p>When {@link android.support.v4.app.NotificationCompat#VISIBILITY_PRIVATE} is set, you can also
   1188 provide an alternate version of the notification content which hides certain details. For example,
   1189 an SMS app might display a notification that shows <em>You have 3 new text messages</em>, but hides the
   1190 message contents and senders. To provide this alternative notification, first create the replacement
   1191 notification using {@link android.support.v4.app.NotificationCompat.Builder}. When you create the
   1192 private notification object, attach the replacement notification to it through the
   1193 {@link android.support.v4.app.NotificationCompat.Builder#setPublicVersion(android.app.Notification) setPublicVersion()}
   1194 method.</p>
   1195 
   1196 <h3 id="controllingMedia">Controlling Media Playback on the Lock Screen</h3>
   1197 
   1198 <p>
   1199   In Android 5.0 (API level 21) the lock screen no longer displays media
   1200   controls based on the {@link android.media.RemoteControlClient}, which is
   1201   now deprecated. Instead, use the {@link
   1202   android.support.v7.app.NotificationCompat.MediaStyle} template with the
   1203   {@link
   1204   android.support.v4.app.NotificationCompat.Builder#addAction(android.support.v4.app.NotificationCompat.Action)
   1205   addAction()} method, which converts actions into clickable icons.
   1206 </p>
   1207 
   1208 <p>
   1209   To display media playback controls on the lock screen in Android 5.0, set
   1210   the visibility to {@link
   1211   android.support.v4.app.NotificationCompat#VISIBILITY_PUBLIC}, as described
   1212   above. Then add the actions and set the {@link
   1213   android.support.v7.app.NotificationCompat.MediaStyle} template, as described
   1214   in the following sample code:
   1215 </p>
   1216 
   1217 <pre>
   1218 Notification notification = new NotificationCompat.Builder(context)
   1219     // Show controls on lock screen even when user hides sensitive content.
   1220     .setVisibility(NotificationCompat.VISIBILITY_PUBLIC)
   1221     .setSmallIcon(R.drawable.ic_stat_player)
   1222     // Add media control buttons that invoke intents in your media service
   1223     .addAction(R.drawable.ic_prev, "Previous", prevPendingIntent) // #0
   1224     .addAction(R.drawable.ic_pause, "Pause", pausePendingIntent)  // #1
   1225     .addAction(R.drawable.ic_next, "Next", nextPendingIntent)     // #2
   1226     // Apply the media style template
   1227     .setStyle(new NotificationCompat.MediaStyle()
   1228         .setShowActionsInCompactView(1 /* #1: pause button */)
   1229         .setMediaSession(mMediaSession.getSessionToken()))
   1230     .setContentTitle("Wonderful music")
   1231     .setContentText("My Awesome Band")
   1232     .setLargeIcon(albumArtBitmap)
   1233     .build();
   1234 </pre>
   1235 
   1236 <p class="note"><strong>Note:</strong> The deprecation of {@link android.media.RemoteControlClient}
   1237 has further implications for controlling media. See
   1238 <a href="{@docRoot}about/versions/android-5.0.html#MediaPlaybackControl">Media Playback Control</a>
   1239 for more information about the new APIs for managing the media session and controlling playback.</p>
   1240 
   1241 
   1242 <!-- ------------------------------------------------------------------------------------------ -->
   1243 <h2 id="CustomNotification">Custom Notification Layouts</h2>
   1244 <p>
   1245     The notifications framework allows you to define a custom notification layout, which
   1246     defines the notification's appearance in a {@link android.widget.RemoteViews} object.
   1247     Custom layout notifications are similar to normal notifications, but they're based on a
   1248     {@link android.widget.RemoteViews} defined in a XML layout file.
   1249 </p>
   1250 <p>
   1251     The height available for a custom notification layout depends on the notification view. Normal
   1252     view layouts are limited to 64 dp, and expanded view layouts are limited to 256 dp.
   1253 </p>
   1254 <p>
   1255     To define a custom notification layout, start by instantiating a
   1256     {@link android.widget.RemoteViews} object that inflates an XML layout file. Then,
   1257     instead of calling methods such as
   1258     {@link android.support.v4.app.NotificationCompat.Builder#setContentTitle setContentTitle()},
   1259     call {@link android.support.v4.app.NotificationCompat.Builder#setContent setContent()}. To set
   1260     content details in the custom notification, use the methods in
   1261     {@link android.widget.RemoteViews} to set the values of the view's children:
   1262 </p>
   1263 <ol>
   1264     <li>
   1265         Create an XML layout for the notification in a separate file. You can use any file name
   1266         you wish, but you must use the extension <code>.xml</code>
   1267     </li>
   1268     <li>
   1269         In your app, use {@link android.widget.RemoteViews} methods to define your notification's
   1270         icons and text. Put this {@link android.widget.RemoteViews} object into your
   1271         {@link android.support.v4.app.NotificationCompat.Builder} by calling
   1272         {@link android.support.v4.app.NotificationCompat.Builder#setContent setContent()}. Avoid
   1273         setting a background {@link android.graphics.drawable.Drawable} on your
   1274         {@link android.widget.RemoteViews} object, because your text color may become unreadable.
   1275     </li>
   1276 </ol>
   1277 <p>
   1278     The {@link android.widget.RemoteViews} class also includes methods that you can use to easily
   1279     add a {@link android.widget.Chronometer} or {@link android.widget.ProgressBar}
   1280     to your notification's layout. For more information about creating custom layouts for your
   1281     notification, refer to the {@link android.widget.RemoteViews} reference documentation.
   1282 </p>
   1283 <p class="caution">
   1284     <strong>Caution:</strong> When you use a custom notification layout, take special care to
   1285     ensure that your custom layout works with different device orientations and resolutions. While
   1286     this advice applies to all View layouts, it's especially important for notifications because
   1287     the space in the notification drawer is very restricted. Don't make your custom layout too
   1288     complex, and be sure to test it in various configurations.
   1289 </p>
   1290 <!-- ------------------------------------------------------------------------------------------ -->
   1291 <h4>Using style resources for custom notification text</h4>
   1292 <p>
   1293     Always use style resources for the text of a custom notification. The background color of the
   1294     notification can vary across different devices and versions, and using style resources
   1295     helps you account for this. Starting in Android 2.3, the system defined a style for the
   1296     standard notification layout text. If you use the same style in applications that target Android
   1297     2.3 or higher, you'll ensure that your text is visible against the display background.
   1298 </p>
   1299 
   1300 <!-- ------------------------------------------------------------------------ -->
   1301 <h3 id="custom"> Custom Views</h3>
   1302 <p>
   1303   Starting from Android 7.0 (API level 24),
   1304   you can customize notification views and
   1305   still obtain system decorations like notification headers, actions, and
   1306   expandable layouts.
   1307 </p>
   1308 
   1309 <p>To enable this capability, Android provides the following APIs to style your
   1310   custom view:</p>
   1311 
   1312 <dl>
   1313 <dt>
   1314 {@code DecoratedCustomViewStyle()}</dt>
   1315 <dd> Styles notifications other than media
   1316 notifications.</dd>
   1317 <dt>
   1318 {@code DecoratedMediaCustomViewStyle()}</dt>
   1319 <dd> Styles media notifications.</dd>
   1320 </dl>
   1321 
   1322 <p>To use this API, call the {@code setStyle()} method, passing to it
   1323 the desired custom view style.</p>
   1324 
   1325 <p>This snippet shows how to construct a custom notification object with the
   1326 {@code DecoratedCustomViewStyle()} method.</p>
   1327 
   1328 <pre>
   1329 Notification notification = new Notification.Builder()
   1330            .setSmallIcon(R.drawable.ic_stat_player)
   1331            .setLargeIcon(albumArtBitmap))
   1332            .setCustomContentView(contentView);
   1333            .setStyle(new Notification.DecoratedCustomViewStyle())
   1334            .build();
   1335 
   1336 </pre>
   1337 
   1338 <!-- ----------------------------------------------------------------------- -->
   1339 
   1340 <h3 id="style">Messaging Style</h3>
   1341 <p>
   1342   Starting in Android 7.0 (API level 24),
   1343   Android provides an API for customizing the style of a notification.
   1344   Using the <code>MessagingStyle</code> class, you can change several of the
   1345   labels displayed on the notification, including the conversation title,
   1346   additional messages, and the content view for the notification.
   1347 </p>
   1348 
   1349 <p>
   1350   The following code snippet demonstrates how to customize a notification's
   1351   style using the <code>MessagingStyle</code> class.
   1352 </p>
   1353 
   1354 <pre>
   1355   Notification notification = new Notification.Builder()
   1356              .setStyle(new Notification.MessagingStyle("Me")
   1357                  .setConversationTitle("Team lunch")
   1358                  .addMessage("Hi", timestamp1, null) // Pass in null for user.
   1359                  .addMessage("What's up?", timestamp2, "Coworker")
   1360                  .addMessage("Not much", timestamp3, null)
   1361                  .addMessage("How about lunch?", timestamp4, "Coworker"))
   1362              .build();
   1363 </pre>
   1364 
   1365