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