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