notifications.jd revision fa9b5cae646ab1461c9f0f4b170c941e3da7c740
1page.title=Status Bar Notifications
2parent.title=Notifications
3parent.link=index.html
4@jd:body
5
6<div id="qv-wrapper">
7  <div id="qv">
8    <h2>Quickview</h2>
9    <ul>
10      <li>A status bar notification allows your application to notify the user of an event
11without interupting their current activity</li>
12      <li>You can attach an intent to your notification that the system will initiate when the
13user clicks it</li>
14    </ul>
15
16    <h2>In this document</h2>
17    <ol>
18      <li><a href="#Basics">The Basics</a></li>
19      <li><a href="#HandlingNotifications">Responding to Notifications</a></li>
20      <li><a href="#ManageYourNotifications">Managing your Notifications</a></li>
21      <li><a href="#CreateANotification">Creating a Notification</a>
22        <ol>
23          <li><a href="#Updating">Updating the notification</a></li>
24          <li><a href="#Sound">Adding a sound</a></li>
25          <li><a href="#Vibration">Adding vibration</a></li>
26          <li><a href="#Lights">Adding flashing lights</a></li>
27          <li><a href="#More">More features</a></li>
28        </ol>
29      </li>
30      <li><a href="#CustomExpandedView">Creating a Custom Notification Layout</a></li>
31    </ol>
32    <h2>Key classes</h2>
33    <ol>
34      <li>{@link android.app.Notification}</li>
35      <li>{@link android.app.NotificationManager}</li>
36    </ol>
37    
38    <h2>See also</h2>
39    <ol>
40      <li><a href="{@docRoot}design/patterns/notifications.html">Android
41Design: Notifications</a></li>
42    </ol>
43  </div>
44</div>
45
46<p>A status bar notification adds an icon to the system's status bar
47(with an optional ticker-text message) and a notification message in the notifications window.
48When the user selects the notification, Android fires an
49{@link android.content.Intent} that is defined by the {@link android.app.Notification} (usually to
50launch an {@link android.app.Activity}).
51You can also configure the notification to alert the user with a sound, a vibration, and flashing
52lights on the device.</p>
53
54<p>A status bar notification should be used for any case in
55which a background service needs to alert the user about an event that requires a response. A
56background service
57<strong>should never</strong> launch an activity on its own in order to receive user interaction.
58The service should instead create a status bar notification that will launch the activity
59when selected by the user.</p>
60
61<p>Figure 1 shows the status bar with a notification icon on the left side.</p>
62<img src="{@docRoot}images/status_bar.png" alt="" />
63<p class="img-caption"><strong>Figure 1.</strong> Status bar with a notification.</p>
64
65<p>Figure 2 shows the notification's message in the notifications window.</p>
66
67<img src="{@docRoot}images/notifications_window.png" alt="" />
68<p class="img-caption"><strong>Figure 2.</strong> The notifications window.</p>
69
70
71<div class="design-announce">
72<p><strong>Notification Design</strong></p>
73  <p>For design guidelines, read Android Design's <a
74href="{@docRoot}design/patterns/notifications.html">Notifications</a> guide.</p>
75</div>
76
77
78
79<h2 id="Basics">The Basics</h2>
80
81<p>An {@link android.app.Activity} or {@link android.app.Service} can initiate a status bar
82notification. Because an activity can perform actions only while it is
83running in the foreground and its window has focus, you will usually create status bar notifications
84from a
85service. This way, the notification can be created from the background,
86while the user is using another application or
87while the device is asleep. To create a notification, you must use two
88classes: {@link android.app.Notification} and {@link android.app.NotificationManager}.</p>
89
90<p>Use an instance of the {@link android.app.Notification} class to define the properties of your
91status bar notification, such as the status bar icon, the notification message, and extra settings
92such as a sound to play. The {@link android.app.NotificationManager} is an Android system service
93that executes and manages all status bar notifications. You do not instantiate the
94{@link android.app.NotificationManager} directly. In order
95to give it your {@link android.app.Notification}, you must retrieve a reference to the
96{@link android.app.NotificationManager} with
97{@link android.app.Activity#getSystemService(String) getSystemService()} and
98then, when you want to notify the user, pass it your {@link android.app.Notification} with
99{@link android.app.NotificationManager#notify(int,Notification) notify()}. </p>
100
101<p>To create a status bar notification:</p>
102<ol>
103  <li>Get a reference to the {@link android.app.NotificationManager}:
104<pre>
105String ns = Context.NOTIFICATION_SERVICE;
106NotificationManager mNotificationManager = (NotificationManager) getSystemService(ns);
107</pre>
108  </li>
109  <!-- use Notification.Builder in 3.0 -->
110  <li>Instantiate the {@link android.app.Notification}:
111<pre>
112int icon = R.drawable.notification_icon;
113CharSequence tickerText = "Hello";
114long when = System.currentTimeMillis();
115
116Notification notification = new Notification(icon, tickerText, when);
117</pre>
118  </li>
119  <li>Define the notification's message and {@link android.app.PendingIntent}:
120<pre>
121Context context = getApplicationContext();
122CharSequence contentTitle = "My notification";
123CharSequence contentText = "Hello World!";
124Intent notificationIntent = new Intent(this, MyClass.class);
125PendingIntent contentIntent = PendingIntent.getActivity(this, 0, notificationIntent, 0);
126
127notification.setLatestEventInfo(context, contentTitle, contentText, contentIntent);
128</pre>
129  </li>
130  <li>Pass the {@link android.app.Notification} to the {@link android.app.NotificationManager}:
131<pre>
132private static final int HELLO_ID = 1;
133
134mNotificationManager.notify(HELLO_ID, notification);
135</pre>
136  <p>That's it. Your user has now been notified.</p>
137  </li>
138</ol>
139
140
141<h2 id="HandlingNotifications">Responding to Notifications</h2>
142
143<p>A central part of the user's experience with a notification revolves around
144how it interacts with the application's UI flow.  You must implement
145this correctly to provide a consistent user experience within your app.</p>
146
147<p>Two typical examples of notifications are provided by Calendar, which can send out
148notifications of upcoming events, and Email, which can send out notifications
149when new messages arrive.  These represent the two recommended patterns for handling
150notifications: either launching into an activity that is separate from the
151main application, or launching an entirely new instance of the application
152showing the appropriate point for the notification.</p>
153
154<p>The following scenario shows how the activity stack should work
155in these two typical notification flows, first handling a Calendar notification:
156</p>
157
158<ol>
159  <li>User is creating a new event in Calendar. They realize they
160    need to copy part of an email message into this event.
161  </li>
162  <li>
163    The user chooses Home &gt; Email.
164  </li>
165  <li>
166    While in Email, they receive a notification from Calendar for an upcoming
167    meeting.
168  </li>
169  <li>
170    So they choose that notification, which takes them to a
171    dedicated Calendar activity that displays brief details of the
172    upcoming meeting.
173  </li>
174  <li>
175    The user has seen enough to know they have a meeting coming up,
176    so they press the BACK button.  They are now returned to Email, which
177    is where they were when they took the notification.
178  </li>
179</ol>
180
181<p>Handling an Email notification:</p>
182
183<ol>
184  <li>
185    The user is currently in Email composing a message, and needs to
186    check a date in their calendar.
187  </li>
188  <li>
189    The user chooses Home &gt; Calendar.
190  </li>
191  <li>
192    While in Calendar, they receive a notification from Email about a new
193    message.
194  </li>
195  <li>
196    They select the notification, which brings them to Email with the message
197    details displayed.  This has replaced what they were previously doing
198    (writing an e-mail), but that message is still saved in their drafts.
199  </li>
200  <li>
201    The user presses BACK once to go to the message list (the typical flow in the
202    Email app), and press BACK again to return to Calendar as they left it.
203  </li>
204</ol>
205
206<p>In an Email style of notification, the UI launched by the notification
207shows the main application in a state representing that notification.
208For example, when the Email application comes to the foreground from its
209notification, it displays either the conversion list or a specific
210conversation depending on whether there are multiple or only one new
211email.  To achieve this, we want to completely replace whatever current
212state the application is in with a new activity stack representing the
213new notification state.</p>
214
215<p>The following code illustrates how to show this kind of notification.  Of
216most interest is the <code>makeMessageIntentStack()</code> method, which constructs
217an array of intents representing the app's new activity stack for this state.
218(If you are using fragments, you may need to initialize your fragment and
219app state so that pressing BACK will switch the UI back to its parent state.)
220The core of this is the {@link android.content.Intent#makeRestartActivityTask
221Intent.makeRestartActivityTask()} method, which constructs the root activity
222of the stack with the appropriate flags, such as
223{@link android.content.Intent#FLAG_ACTIVITY_CLEAR_TASK Intent.FLAG_ACTIVITY_CLEAR_TASK}.</p>
224
225{@sample development/samples/ApiDemos/src/com/example/android/apis/app/IncomingMessage.java
226  app_notification}
227
228<p>In a Calendar style of notification, the UI launched by the notification
229is a dedicated activity that is not part of the normal application flow.
230For example, when the user receives a Calendar notification, choosing that
231notification starts a special activity that displays a list
232of upcoming calendar events &mdash; this view is available only
233from the notification, not through the Calendar's normal user
234interface.</p>
235
236<p>The code for posting this type of notification is very straight-forward; it
237is like the above, but the {@link android.app.PendingIntent} is for just a single
238activity, our dedicated notification activity.</p>
239
240{@sample development/samples/ApiDemos/src/com/example/android/apis/app/IncomingMessage.java
241  interstitial_notification}
242
243<p>This is not enough, however.  Normally Android considers all activities within
244an application to be part of that application's UI flow, so simply launching the
245activity like this can cause it to be mixed with your normal application back stack
246in undesired ways.  To make it behave correctly, in the manifest declaration
247for the activity the attributes 
248<code>android:launchMode="singleTask"</code>,
249<code>android:taskAffinity=""</code> and
250<code>android:excludeFromRecents="true"</code>
251must be set.  The full activity declaration for this sample is:</p>
252
253{@sample development/samples/ApiDemos/AndroidManifest.xml interstitial_affinity}
254
255<p>You must be careful when launching other activities from this initial activity,
256because this is not a top-level part of the application, does not appear in
257recents, and needs to be relaunched at any point from the notification with new data
258to show.  This best approach is to make sure any activity launched from it is
259launched in its own task.  When doing this care must be taken to make sure this
260new task interacts well with the current state of your exiting application's
261task.  This is essentially
262the same as switching to the main application as described for the Email style
263notification shown before.  Given the <code>makeMessageIntentStack()</code>
264method previously shown, handling a click then would look something like this:</p>
265
266{@sample development/samples/ApiDemos/src/com/example/android/apis/app/IncomingMessageInterstitial.java
267  app_launch}
268
269<h2 id="ManageYourNotifications">Managing your Notifications</h2>
270
271<p>The {@link android.app.NotificationManager} is a system service that manages all
272notifications. You must retrieve a reference to it with the
273{@link android.app.Activity#getSystemService(String) getSystemService()} method.
274For example:</p>
275<pre>
276String ns = Context.NOTIFICATION_SERVICE;
277NotificationManager mNotificationManager = (NotificationManager) getSystemService(ns);
278</pre>
279
280<p>When you want to deliver your status bar notification, pass the {@link android.app.Notification}
281to the {@link android.app.NotificationManager} with {@link
282android.app.NotificationManager#notify(int,Notification)}.
283The first parameter is the unique ID for the notification and the second is the {@link
284android.app.Notification} object.
285The ID uniquely identifies the notification from within your
286application. The ID is necessary if you need to update the notification or (if
287your application manages different kinds of notifications) select the appropriate action
288when the user returns to your application via the intent defined in the notification.</p>
289
290<p>To clear the status bar notification when the user selects it from the notifications
291window, add the "FLAG_AUTO_CANCEL" flag to your {@link android.app.Notification}. You can
292also clear it manually with {@link android.app.NotificationManager#cancel(int)}, passing it the
293notification ID, or clear all your notifications with {@link
294android.app.NotificationManager#cancelAll()}.</p>
295
296
297<h2 id="CreateANotification">Creating a Notification</h2>
298
299<p>A {@link android.app.Notification} object defines the details of the notification
300message that is displayed in the status bar and notifications window, and any other
301alert settings, such as sounds and blinking lights.</p>
302
303<p>A status bar notification <em>requires</em> all of the following:</p>
304<ul>
305  <li>An icon for the status bar</li>
306  <li>A title and message, unless you define a
307    <a href="#CustomExpandedView">custom notification layout</a></li>
308  <li>A {@link android.app.PendingIntent}, to be fired when the notification is selected</li>
309</ul>
310<p>Optional settings for the status bar notification include:</p>
311<ul>
312  <li>A ticker-text message for the status bar</li>
313  <li>An alert sound</li>
314  <li>A vibrate setting</li>
315  <li>A flashing LED setting</li>
316</ul>
317
318<p>The starter-kit for a new notification includes the
319{@link android.app.Notification#Notification(int,CharSequence,long)} constructor and the
320{@link android.app.Notification#setLatestEventInfo(Context,CharSequence,CharSequence,PendingIntent)}
321method. These define all the required settings for a notification.
322The following snippet demonstrates a basic notification setup:</p>
323<pre>
324int icon = R.drawable.notification_icon;        // icon from resources
325CharSequence tickerText = "Hello";              // ticker-text
326long when = System.currentTimeMillis();         // notification time
327Context context = getApplicationContext();      // application Context
328CharSequence contentTitle = "My notification";  // message title
329CharSequence contentText = "Hello World!";      // message text
330
331Intent notificationIntent = new Intent(this, MyClass.class);
332PendingIntent contentIntent = PendingIntent.getActivity(this, 0, notificationIntent, 0);
333
334// the next two lines initialize the Notification, using the configurations above
335Notification notification = new Notification(icon, tickerText, when);
336notification.setLatestEventInfo(context, contentTitle, contentText, contentIntent);
337</pre>
338
339
340<h3 id="Updating">Updating the notification</h3>
341
342<p>You can update the information in your status bar notification as events
343continue to occur in your application. For example, when a new SMS text message arrives
344before previous messages have been read, the Messaging application updates the existing
345notification to display the total number of new messages received.
346This practice of updating an existing notification is much better than adding new
347notifications, because it avoids clutter in the notifications window.</p>
348
349<p>Because each notification is uniquely identified
350by the {@link android.app.NotificationManager} with an integer ID, you can revise the notification
351by calling {@link
352android.app.Notification#setLatestEventInfo(Context,CharSequence,CharSequence,PendingIntent)
353setLatestEventInfo()} with new values, change some field values of the notification, and then call
354{@link android.app.NotificationManager#notify(int,Notification) notify()} again.</p>
355
356<p>You can revise each property with the object member fields
357(except for the {@link android.content.Context} and the notification title and text). You
358should always revise the text message when you update the notification by calling
359{@link android.app.Notification#setLatestEventInfo(Context,CharSequence,CharSequence,PendingIntent)
360setLatestEventInfo()} with new values for <var>contentTitle</var> and <var>contentText</var>.
361Then call {@link android.app.NotificationManager#notify(int,Notification) notify()} to update the
362notification. (Of course, if you've created a <a href="#CustomExpandedView">custom notification
363layout</a>, then updating these title and text values has no effect.)</p>
364
365
366<h3 id="Sound">Adding a sound</h3>
367
368<p>You can alert the user with the default notification sound
369(which is defined by the user) or with a sound specified by your application.</p>
370
371<p>To use the user's default sound, add "DEFAULT_SOUND" to the <var>defaults</var> field:</p>
372<pre>
373notification.defaults |= Notification.DEFAULT_SOUND;
374</pre>
375
376<p>To use a different sound with your notifications, pass a Uri reference to the
377<var>sound</var> field.
378The following example uses a known audio file saved to the device SD card:</p>
379<pre>
380notification.sound = Uri.parse("file:///sdcard/notification/ringer.mp3");
381</pre>
382
383<p>In the next example, the audio file is chosen from the internal
384{@link android.provider.MediaStore.Audio.Media MediaStore}'s {@link android.content.ContentProvider}:</p>
385<pre>
386notification.sound = Uri.withAppendedPath(Audio.Media.INTERNAL_CONTENT_URI, "6");
387</pre>
388
389<p>In this case, the exact ID of the media file ("6") is known and appended to the content
390{@link android.net.Uri}. If you don't know the exact ID, you must query all the
391media available in the {@link android.provider.MediaStore} with a {@link
392android.content.ContentResolver}.
393See the <a href="{@docRoot}guide/topics/providers/content-providers.html">Content Providers</a>
394documentation for more information on using a ContentResolver.</p>
395
396<p>If you want the sound to continuously repeat until the user responds to the notification
397or the notification is cancelled, add {@link android.app.Notification#FLAG_INSISTENT} to the
398<var>flags</var> field.</p>
399
400<p class="note"><strong>Note:</strong> If the <var>defaults</var> field includes
401{@link android.app.Notification#DEFAULT_SOUND}, then the default sound overrides any sound defined
402by the <var>sound</var> field.</p>
403
404
405<h3 id="Vibration">Adding vibration</h3>
406
407<p>You can alert the user with the the default
408vibration pattern or with a vibration pattern defined by your application.</p>
409
410<p>To use the default pattern, add {@link android.app.Notification#DEFAULT_VIBRATE} to the
411<var>defaults</var> field:</p>
412<pre>
413notification.defaults |= Notification.DEFAULT_VIBRATE;
414</pre>
415
416<p>To define your own vibration pattern, pass an array of <em>long</em> values to the
417<var>vibrate</var> field:</p>
418<pre>
419long[] vibrate = {0,100,200,300};
420notification.vibrate = vibrate;
421</pre>
422
423<p>The long array defines the alternating pattern for the length of vibration off and on
424(in milliseconds). The first value is how long to wait (off) before beginning, the second
425value is the length of the first vibration, the third is the next length off, and so on.
426The pattern can be as long as you like, but it can't be set to repeat.
427</p>
428
429<p class="note"><strong>Note:</strong> If the <var>defaults</var> field includes
430{@link android.app.Notification#DEFAULT_VIBRATE}, then the default vibration overrides any vibration
431defined by the
432<var>vibrate</var> field.</p>
433
434
435<h3 id="Lights">Adding flashing lights</h3>
436
437<p>To alert the user by flashing LED lights, you can implement the default
438light pattern (if available), or define your own color and pattern for the lights.</p>
439
440<p>To use the default light setting, add {@link android.app.Notification#DEFAULT_LIGHTS} to the
441<var>defaults</var> field:</p>
442<pre>
443notification.defaults |= Notification.DEFAULT_LIGHTS;
444</pre>
445
446<p>To define your own color and pattern, define a value for the <var>ledARGB</var> field
447(for the color), the <var>ledOffMS</var> field (length of time, in milliseconds, to
448keep the light off), the <var>ledOnMS</var> (length of time, in milliseconds, to keep the light on),
449and also add {@link android.app.Notification#FLAG_SHOW_LIGHTS} to the <var>flags</var> field:</p>
450<pre>
451notification.ledARGB = 0xff00ff00;
452notification.ledOnMS = 300;
453notification.ledOffMS = 1000;
454notification.flags |= Notification.FLAG_SHOW_LIGHTS;
455</pre>
456
457<p>In this example, the green light repeatedly flashes on for 300 milliseconds and
458turns off for one second. Not every color in the spectrum is supported by the
459device LEDs, and not every device supports the same colors, so the hardware
460estimates to the best of its ability. Green is the most common notification color.</p>
461
462
463<h3 id="More">More features</h3>
464
465<p>You can add several more features to your notifications
466using {@link android.app.Notification} fields and flags. Some useful features include the
467following:</p>
468
469<dl>
470  <dt>{@link android.app.Notification#FLAG_AUTO_CANCEL} flag</dt>
471  <dd>Add this to the <var>flags</var> field to automatically cancel the notification
472  after it is selected from the notifications window.</dd>
473  <dt>{@link android.app.Notification#FLAG_INSISTENT} flag</dt>
474  <dd>Add this to the <var>flags</var> field to repeat the audio until the
475  user responds.</dd>
476  <dt>{@link android.app.Notification#FLAG_ONGOING_EVENT} flag</dt>
477  <dd>Add this to the <var>flags</var> field to group the notification under the "Ongoing"
478  title in the notifications window. This indicates that the application is on-going &mdash;
479  its processes are still running in the background, even when the application is not
480  visible (such as with music or a phone call).</dd>
481  <dt>{@link android.app.Notification#FLAG_NO_CLEAR} flag</dt>
482  <dd>Add this to the <var>flags</var> field to indicate that the notification should
483  <em>not</em> be cleared by the "Clear notifications" button. This is particularly useful if
484  your notification is on-going.</dd>
485  <dt>{@link android.app.Notification#number} field</dt>
486  <dd>This value indicates the current number of events represented by the notification.
487  The appropriate number is overlaid on top of the status bar icon.
488  If you intend to use this field, then you must start with "1" when the Notification is first
489  created. (If you change the value from zero to anything greater during an update, the number
490  is not shown.)</dd>
491  <dt>{@link android.app.Notification#iconLevel} field</dt>
492  <dd>This value indicates the current level of a
493  {@link android.graphics.drawable.LevelListDrawable} that is used for the notification icon.
494  You can animate the icon in the status bar by changing this value to correlate with the
495  drawable's defined in a LevelListDrawable. See the {@link android.graphics.drawable.LevelListDrawable}
496  reference for more information.</dd>
497</dl>
498
499<p>See the {@link android.app.Notification} class reference for more information about additional
500features that you can customize for your application.</p>
501
502
503<h2 id="CustomExpandedView">Creating a Custom Notification Layout</h2>
504
505<div class="figure" style="width:200px;margin-top:0">
506<img src="{@docRoot}images/custom_message.png" alt="" />
507<p class="img-caption"><strong>Figure 3.</strong> Notification with a custom layout.</p>
508</div>
509
510<p>By default, the notification that appears in the notifications window includes a title
511and the message text.
512These are defined by the <var>contentTitle</var> and <var>contentText</var>
513parameters of the {@link android.app.Notification#setLatestEventInfo(Context,CharSequence,CharSequence,PendingIntent)
514setLatestEventInfo()} method. However, you can also define a custom layout for the
515notification using
516{@link android.widget.RemoteViews}. Figure 3 shows an example of a
517custom notification layout. It looks similar to the default notification, but is
518actually created with a custom XML layout.</p>
519
520<p>To define your own layout for the notification,
521instantiate a {@link android.widget.RemoteViews} object that inflates a custom layout file, then
522pass the {@link android.widget.RemoteViews} to the <var>contentView</var> field of your
523Notification.</p>
524
525<p>Creating a custom notification layout is best understood with an example:</p>
526
527<ol>
528  <li>Create the XML layout for the notification.
529    For example, the following layout is called <code>custom_notification.xml</code>:
530<pre>
531&lt;RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
532    android:id="@+id/layout"
533    android:layout_width="fill_parent"
534    android:layout_height="fill_parent"
535    android:padding="10dp" >
536    &lt;ImageView android:id="@+id/image"
537        android:layout_width="wrap_content"
538        android:layout_height="fill_parent"
539        android:layout_alignParentLeft="true"
540        android:layout_marginRight="10dp" />
541    &lt;TextView android:id="@+id/title"
542        android:layout_width="wrap_content"
543        android:layout_height="wrap_content"
544        android:layout_toRightOf="@id/image"
545        style="@style/NotificationTitle" />
546    &lt;TextView android:id="@+id/text"
547        android:layout_width="wrap_content"
548        android:layout_height="wrap_content"
549        android:layout_toRightOf="@id/image"
550        android:layout_below="@id/title"
551        style="@style/NotificationText" />
552&lt;/RelativeLayout>
553</pre>
554
555    <p>Notice that the two {@link android.widget.TextView} elements include the {@code style}
556attribute. It's important that you use style resources for the text in your custom
557notifications, because the background color of the notification can vary across different
558devices and platform versions. Beginning with Android 2.3 (API level 9), the system defines a
559style for the text it uses for the default notification layouts. Thus, you should apply
560that style when running on Android 2.3 or higher to ensure that your text is visible against
561the background.</p>
562
563    <p>For example, to use the standard text colors on versions of Android lower than 2.3, you
564should use the following styles for {@code res/values/styles.xml}:</p>
565<pre>
566&lt;?xml version="1.0" encoding="utf-8"?>
567&lt;resources>
568    &lt;style name="NotificationText">
569      &lt;item name="android:textColor">?android:attr/textColorPrimary&lt;/item>
570    &lt;/style>
571    &lt;style name="NotificationTitle">
572      &lt;item name="android:textColor">?android:attr/textColorPrimary&lt;/item>
573      &lt;item name="android:textStyle">bold&lt;/item>
574    &lt;/style>
575    &lt;!-- If you want a slightly different color for some text,
576         consider using ?android:attr/textColorSecondary -->
577&lt;/resources>
578</pre>
579    <p>Then, to apply the system's default colors for notifications on Android
5802.3 and higher, use the following styles for {@code res/values-v9/styles.xml}:</p>
581<pre>
582&lt;?xml version="1.0" encoding="utf-8"?>
583&lt;resources>
584    &lt;style name="NotificationText" parent="android:TextAppearance.StatusBar.EventContent" />
585    &lt;style name="NotificationTitle" parent="android:TextAppearance.StatusBar.EventContent.Title" />
586&lt;/resources>
587</pre>
588    <p>Now, when running on Android 2.3 (API level 9) or higher, the text in your custom view will
589use the same colors that the system does for default notifications. This is important because later
590versions of Android actually change the background color of the notifications to be dark. Inheriting
591the system's styles ensures that your text will be light in such cases, but also if the background
592is some other unexpected color, your text will also change as appropriate.</p>
593  </li>
594
595  <li>Now, in the application code, use the RemoveViews
596    methods to define the image and text. Then pass the RemoteViews object to the <var>contentView</var>
597    field of the Notification, as shown in this example:
598<pre>
599RemoteViews contentView = new RemoteViews(getPackageName(), R.layout.custom_notification_layout);
600contentView.setImageViewResource(R.id.image, R.drawable.notification_image);
601contentView.setTextViewText(R.id.title, "Custom notification");
602contentView.setTextViewText(R.id.text, "This is a custom layout");
603notification.contentView = contentView;
604</pre>
605
606    <p>As shown here, pass the application's package name and the layout
607    resource ID to the RemoteViews constructor. Then, define the content for the ImageView and TextView,
608    using the {@link android.widget.RemoteViews#setImageViewResource(int, int) setImageViewResource()}
609    and {@link android.widget.RemoteViews#setTextViewText(int, CharSequence) setTextViewText()}.
610    In each case, pass the reference ID of the appropriate View object that you want to set, along with
611    the value for that View. Finally, the RemoteViews object is passed to the Notification in the
612    <var>contentView</var> field.</p>
613  </li>
614
615  <li>Because you don't need the
616    {@link android.app.Notification#setLatestEventInfo(Context,CharSequence,CharSequence,PendingIntent)
617    setLatestEventInfo()} method when using a custom view, you must define the Intent for the Notification
618    with the <var>contentIntent</var> field, as in this example:
619<pre>
620Intent notificationIntent = new Intent(this, MyClass.class);
621PendingIntent contentIntent = PendingIntent.getActivity(this, 0, notificationIntent, 0);
622notification.contentIntent = contentIntent;
623</pre>
624  </li>
625
626  <li>The notification can now be sent as usual:
627    <pre>mNotificationManager.notify(CUSTOM_VIEW_ID, notification);</pre>
628  </li>
629</ol>
630
631
632<p>The {@link android.widget.RemoteViews} class also includes methods that you can use to easily add
633a {@link android.widget.Chronometer} or {@link android.widget.ProgressBar}
634in your notification's layout. For more information about creating custom layouts for your
635notification, refer to the {@link android.widget.RemoteViews} class reference.</p>
636
637<p class="caution"><strong>Caution:</strong>
638When creating a custom notification layout, you must take special care to ensure that your
639custom layout functions properly in different device orientations and resolutions. While this
640advice applies to all View layouts created on Android, it is especially important in this case
641because your layout real estate is very restricted. So don't make your custom layout too
642complex and be sure to test it in various configurations.</p>
643
644
645
646
647