| page.title=Creating Status Bar Notifications |
| parent.title=Notifying the User |
| parent.link=index.html |
| @jd:body |
| |
| <div id="qv-wrapper"> |
| <div id="qv"> |
| <h2>Quickview</h2> |
| <ul> |
| <li>A status bar notification allows your application to notify the user of an event |
| without interupting their current activity</li> |
| <li>You can attach an intent to your notification that the system will initiate when the |
| user clicks it</li> |
| </ul> |
| |
| <h2>In this document</h2> |
| <ol> |
| <li><a href="#Basics">The Basics</a></li> |
| <li><a href="#ManageYourNotifications">Managing your Notifications</a></li> |
| <li><a href="#CreateANotification">Creating a Notification</a> |
| <ol> |
| <li><a href="#Updating">Updating the notification</a></li> |
| <li><a href="#Sound">Adding a sound</a></li> |
| <li><a href="#Vibration">Adding vibration</a></li> |
| <li><a href="#Lights">Adding flashing lights</a></li> |
| <li><a href="#More">More features</a></li> |
| </ol> |
| </li> |
| <li><a href="#CustomExpandedView">Creating a Custom Expanded View</a></li> |
| </ol> |
| <h2>Key classes</h2> |
| <ol> |
| <li>{@link android.app.Notification}</li> |
| <li>{@link android.app.NotificationManager}</li> |
| </ol> |
| </div> |
| </div> |
| |
| <p>A status bar notification adds an icon to the system's status bar |
| (with an optional ticker-text message) and an expanded message in the "Notifications" window. |
| When the user selects the expanded message, Android fires an |
| {@link android.content.Intent} that is defined by the notification (usually to launch an |
| {@link android.app.Activity}). |
| You can also configure the notification to alert the user with a sound, a vibration, and flashing |
| lights on the device.</p> |
| |
| <p>A status bar notification should be used for any case in |
| which a background Service needs to alert the user about an event that requires a response. A background Service |
| <strong>should never</strong> launch an Activity on its own in order to receive user interaction. |
| The Service should instead create a status bar notification that will launch the Activity |
| when selected by the user.</p> |
| |
| <p>The screenshot below shows the status bar with a notification icon on the left side.</p> |
| <img src="{@docRoot}images/status_bar.png" alt="" /> |
| |
| <p>The next screenshot shows the notification's expanded message in the "Notifications" window. |
| The user can reveal the Notifications window by pulling down the status bar |
| (or selecting <em>Notifications</em> from the Home options menu).</p> |
| <img src="{@docRoot}images/notifications_window.png" alt="" /> |
| |
| |
| <h2 id="Basics">The Basics</h2> |
| |
| <p>An {@link android.app.Activity} or {@link android.app.Service} can initiate a status bar |
| notification. Because an Activity can perform actions only while it is |
| active and in focus, you should create your status bar notifications from a |
| Service. This way, the notification can be created from the background, |
| while the user is using another application or |
| while the device is asleep. To create a notification, you must use two |
| classes: {@link android.app.Notification} and {@link android.app.NotificationManager}.</p> |
| |
| <p>Use an instance of the {@link android.app.Notification} class to define the properties of your |
| status bar notification, such as the status bar icon, the expanded message, and extra settings such |
| as a sound to play. The {@link android.app.NotificationManager} is an Android system service that |
| executes and manages all Notifications. You do not instantiate the NotificationManager. In order |
| to give it your Notification, you must retrieve a reference to the NotificationManager with |
| {@link android.app.Activity#getSystemService(String) getSystemService()} and |
| then, when you want to notify the user, pass it your Notification object with |
| {@link android.app.NotificationManager#notify(int,Notification) notify()}. </p> |
| |
| <p>To create a status bar notification:</p> |
| <ol> |
| <li>Get a reference to the NotificationManager: |
| <pre> |
| String ns = Context.NOTIFICATION_SERVICE; |
| NotificationManager mNotificationManager = (NotificationManager) getSystemService(ns); |
| </pre> |
| </li> |
| <li>Instantiate the Notification: |
| <pre> |
| int icon = R.drawable.notification_icon; |
| CharSequence tickerText = "Hello"; |
| long when = System.currentTimeMillis(); |
| |
| Notification notification = new Notification(icon, tickerText, when); |
| </pre> |
| </li> |
| <li>Define the Notification's expanded message and Intent: |
| <pre> |
| Context context = getApplicationContext(); |
| CharSequence contentTitle = "My notification"; |
| CharSequence contentText = "Hello World!"; |
| Intent notificationIntent = new Intent(this, MyClass.class); |
| PendingIntent contentIntent = PendingIntent.getActivity(this, 0, notificationIntent, 0); |
| |
| notification.setLatestEventInfo(context, contentTitle, contentText, contentIntent); |
| </pre> |
| </li> |
| <li>Pass the Notification to the NotificationManager: |
| <pre> |
| private static final int HELLO_ID = 1; |
| |
| mNotificationManager.notify(HELLO_ID, notification); |
| </pre> |
| <p>That's it. Your user has now been notified.</p> |
| </li> |
| </ol> |
| |
| |
| <h2 id="ManageYourNotifications">Managing your Notifications</h2> |
| |
| <p>The {@link android.app.NotificationManager} is a system service that manages all |
| notifications. You must retrieve a reference to it with the |
| {@link android.app.Activity#getSystemService(String) getSystemService()} method. |
| For example:</p> |
| <pre> |
| String ns = Context.NOTIFICATION_SERVICE; |
| NotificationManager mNotificationManager = (NotificationManager) getSystemService(ns); |
| </pre> |
| |
| <p>When you want to send your status bar notification, pass the Notification object |
| to the NotificationManager with {@link android.app.NotificationManager#notify(int,Notification)}. |
| The first parameter is the unique ID for the Notification and the second is the Notification object. |
| The ID uniquely identifies the Notification from within your |
| application. This is necessary if you need to update the Notification or (if |
| your application manages different kinds of Notifications) select the appropriate action |
| when the user returns to your application via the Intent defined in the Notification.</p> |
| |
| <p>To clear the status bar notification when the user selects it from the Notifications |
| window, add the "FLAG_AUTO_CANCEL" flag to your Notification object. You can also clear it |
| manually with {@link android.app.NotificationManager#cancel(int)}, passing it the notification ID, |
| or clear all your Notifications with {@link android.app.NotificationManager#cancelAll()}.</p> |
| |
| |
| <h2 id="CreateANotification">Creating a Notification</h2> |
| |
| <p>A {@link android.app.Notification} object defines the details of the notification |
| message that is displayed in the status bar and "Notifications" window, and any other |
| alert settings, such as sounds and blinking lights.</p> |
| |
| <p>A status bar notification <em>requires</em> all of the following:</p> |
| <ul> |
| <li>An icon for the status bar</li> |
| <li>A title and expanded message for the expanded view (unless you define a |
| <a href="#CustomExpandedView">custom expanded view</a>)</li> |
| <li>A {@link android.app.PendingIntent}, to be fired when the notification is selected</li> |
| </ul> |
| <p>Optional settings for the status bar notification include:</p> |
| <ul> |
| <li>A ticker-text message for the status bar</li> |
| <li>An alert sound</li> |
| <li>A vibrate setting</li> |
| <li>A flashing LED setting</li> |
| </ul> |
| |
| <p>The starter-kit for a new Notification includes the |
| {@link android.app.Notification#Notification(int,CharSequence,long)} constructor and the |
| {@link android.app.Notification#setLatestEventInfo(Context,CharSequence,CharSequence,PendingIntent)} |
| method. These define all the required settings for a Notification. |
| The following snippet demonstrates a basic Notification setup:</p> |
| <pre> |
| int icon = R.drawable.notification_icon; // icon from resources |
| CharSequence tickerText = "Hello"; // ticker-text |
| long when = System.currentTimeMillis(); // notification time |
| Context context = getApplicationContext(); // application Context |
| CharSequence contentTitle = "My notification"; // expanded message title |
| CharSequence contentText = "Hello World!"; // expanded message text |
| |
| Intent notificationIntent = new Intent(this, MyClass.class); |
| PendingIntent contentIntent = PendingIntent.getActivity(this, 0, notificationIntent, 0); |
| |
| // the next two lines initialize the Notification, using the configurations above |
| Notification notification = new Notification(icon, tickerText, when); |
| notification.setLatestEventInfo(context, contentTitle, contentText, contentIntent); |
| </pre> |
| |
| |
| <h3 id="Updating">Updating the notification</h3> |
| |
| <p>You can update the information in your status bar notification as events |
| continue to occur in your application. For example, when a new SMS text message arrives |
| before previous messages have been read, the Messaging application updates the existing |
| notification to display the total number of new messages received. |
| This practice of updating an existing Notification is much better than adding new Notifications |
| to the NotificationManager because it avoids clutter in the Notifications window.</p> |
| |
| <p>Because each notification is uniquely identified |
| by the NotificationManager with an integer ID, you can revise the notification by calling |
| {@link android.app.Notification#setLatestEventInfo(Context,CharSequence,CharSequence,PendingIntent) |
| setLatestEventInfo()} with new values, change some field values of the Notification, and then call |
| {@link android.app.NotificationManager#notify(int,Notification) notify()} again.</p> |
| |
| <p>You can revise each property with the object member fields |
| (except for the Context and the expanded message title and text). You should always |
| revise the text message when you update the notification by calling |
| {@link android.app.Notification#setLatestEventInfo(Context,CharSequence,CharSequence,PendingIntent) |
| setLatestEventInfo()} with new values for <var>contentTitle</var> and <var>contentText</var>. |
| Then call {@link android.app.NotificationManager#notify(int,Notification) notify()} to update the |
| notification. (Of course, if you've created a <a href="#CustomExpandedView">custom expanded |
| view</a>, then updating these title and text values has no effect.)</p> |
| |
| |
| <h3 id="Sound">Adding a sound</h3> |
| |
| <p>You can alert the user with the default notification sound |
| (which is defined by the user) or with a sound specified by your application.</p> |
| |
| <p>To use the user's default sound, add "DEFAULT_SOUND" to the <var>defaults</var> field:</p> |
| <pre> |
| notification.defaults |= Notification.DEFAULT_SOUND; |
| </pre> |
| |
| <p>To use a different sound with your notifications, pass a Uri reference to the |
| <var>sound</var> field. |
| The following example uses a known audio file saved to the device SD card:</p> |
| <pre> |
| notification.sound = Uri.parse("file:///sdcard/notification/ringer.mp3"); |
| </pre> |
| |
| <p>In the next example, the audio file is chosen from the internal |
| {@link android.provider.MediaStore.Audio.Media MediaStore}'s {@link android.content.ContentProvider}:</p> |
| <pre> |
| notification.sound = Uri.withAppendedPath(Audio.Media.INTERNAL_CONTENT_URI, "6"); |
| </pre> |
| |
| <p>In this case, the exact ID of the media file ("6") is known and appended to the content |
| {@link android.net.Uri}. If you don't know the exact ID, you must query all the |
| media available in the MediaStore with a {@link android.content.ContentResolver}. |
| See the <a href="{@docRoot}guide/topics/providers/content-providers.html">Content Providers</a> |
| documentation for more information on using a ContentResolver.</p> |
| |
| <p>If you want the sound to continuously repeat until the user responds to the notification |
| or the notification is cancelled, add "FLAG_INSISTENT" to the <var>flags</var> field.</p> |
| |
| <p class="note"><strong>Note:</strong> If the <var>defaults</var> field includes |
| "DEFAULT_SOUND", then the default sound overrides any sound defined by the <var>sound</var> field.</p> |
| |
| |
| <h3 id="Vibration">Adding vibration</h3> |
| |
| <p>You can alert the user with the the default |
| vibration pattern or with a vibration pattern defined by your application.</p> |
| |
| <p>To use the default pattern, add "DEFAULT_VIBRATE" to the <var>defaults</var> field:</p> |
| <pre> |
| notification.defaults |= Notification.DEFAULT_VIBRATE; |
| </pre> |
| |
| <p>To define your own vibration pattern, pass an array of <em>long</em> values to the |
| <var>vibrate</var> field:</p> |
| <pre> |
| long[] vibrate = {0,100,200,300}; |
| notification.vibrate = vibrate; |
| </pre> |
| |
| <p>The long array defines the alternating pattern for the length of vibration off and on |
| (in milliseconds). The first value is how long to wait (off) before beginning, the second |
| value is the length of the first vibration, the third is the next length off, and so on. |
| The pattern can be as long as you like, but it can't be set to repeat. |
| </p> |
| |
| <p class="note"><strong>Note:</strong> If the <var>defaults</var> field includes |
| "DEFAULT_VIBRATE", then the default vibration overrides any vibration defined by the |
| <var>vibrate</var> field.</p> |
| |
| |
| <h3 id="Lights">Adding flashing lights</h3> |
| |
| <p>To alert the user by flashing LED lights, you can implement the default |
| light pattern (if available), or define your own color and pattern for the lights.</p> |
| |
| <p>To use the default light setting, add "DEFAULT_LIGHTS" to the <var>defaults</var> field:</p> |
| <pre> |
| notification.defaults |= Notification.DEFAULT_LIGHTS; |
| </pre> |
| |
| <p>To define your own color and pattern, define a value for the <var>ledARGB</var> field |
| (for the color), the <var>ledOffMS</var> field (length of time, in milliseconds, to |
| keep the light off), the <var>ledOnMS</var> (length of time, in milliseconds, to keep the light on), |
| and also add "FLAG_SHOW_LIGHTS" to the <var>flags</var> field:</p> |
| <pre> |
| notification.ledARGB = 0xff00ff00; |
| notification.ledOnMS = 300; |
| notification.ledOffMS = 1000; |
| notification.flags |= Notification.FLAG_SHOW_LIGHTS; |
| </pre> |
| |
| <p>In this example, the green light repeatedly flashes on for 300 milliseconds and |
| turns off for one second. Not every color in the spectrum is supported by the |
| device LEDs, and not every device supports the same colors, so the hardware |
| estimates to the best of its ability. Green is the most common notification color.</p> |
| |
| |
| <h3 id="More">More features</h3> |
| |
| <p>You can add several more features to your notifications |
| using Notification fields and flags. Some useful features include the following:</p> |
| |
| <dl> |
| <dt>"FLAG_AUTO_CANCEL" flag</dt> |
| <dd>Add this to the <var>flags</var> field to automatically cancel the notification |
| after it is selected from the Notifications window.</dd> |
| <dt>"FLAG_INSISTENT" flag</dt> |
| <dd>Add this to the <var>flags</var> field to repeat the audio until the |
| user responds.</dd> |
| <dt>"FLAG_ONGOING_EVENT" flag</dt> |
| <dd>Add this to the <var>flags</var> field to group the notification under the "Ongoing" |
| title in the Notifications window. This indicates that the application is on-going — |
| its processes is still running in the background, even when the application is not |
| visible (such as with music or a phone call).</dd> |
| <dt>"FLAG_NO_CLEAR" flag</dt> |
| <dd>Add this to the <var>flags</var> field to indicate that the notification should |
| <em>not</em> be cleared by the "Clear notifications" button. This is particularly useful if |
| your notification is on-going.</dd> |
| <dt><var>number</var> field</dt> |
| <dd>This value indicates the current number of events represented by the notification. |
| The appropriate number is overlaid on top of the status bar icon. |
| If you intend to use this field, then you must start with "1" when the Notification is first |
| created. (If you change the value from zero to anything greater during an update, the number |
| is not shown.)</dd> |
| <dt><var>iconLevel</var> field</dt> |
| <dd>This value indicates the current level of a |
| {@link android.graphics.drawable.LevelListDrawable} that is used for the notification icon. |
| You can animate the icon in the status bar by changing this value to correlate with the |
| drawable's defined in a LevelListDrawable. See the {@link android.graphics.drawable.LevelListDrawable} |
| reference for more information.</dd> |
| </dl> |
| |
| <p>See the {@link android.app.Notification} class reference for more information about additional |
| features that you can customize for your application.</p> |
| |
| |
| <h2 id="CustomExpandedView">Creating a Custom Expanded View</h2> |
| |
| <img src="{@docRoot}images/custom_message.png" alt="" style="float:right;" /> |
| |
| <p>By default, the expanded view used in the "Notifications" window includes a basic title and text |
| message. These are defined by the <var>contentTitle</var> and <var>contentText</var> |
| parameters of the {@link android.app.Notification#setLatestEventInfo(Context,CharSequence,CharSequence,PendingIntent) |
| setLatestEventInfo()} method. However, you can also define a custom layout for the expanded view using |
| {@link android.widget.RemoteViews}. The screenshot to the right shows an example of a |
| custom expanded view that uses an ImageView and TextView in a LinearLayout.</p> |
| |
| <p>To define your own layout for the expanded message, |
| instantiate a {@link android.widget.RemoteViews} object and |
| pass it to the <var>contentView</var> field of your Notification. Pass the |
| {@link android.app.PendingIntent} to the <var>contentIntent</var> field.</p> |
| |
| <p>Creating a custom expanded view is best understood with an example:</p> |
| |
| <ol> |
| <li>Create the XML layout for the expanded view. |
| For example, create a layout file called <code>custom_notification_layout.xml</code> and |
| build it like so: |
| <pre> |
| <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" |
| android:orientation="horizontal" |
| android:layout_width="fill_parent" |
| android:layout_height="fill_parent" |
| android:padding="3dp" |
| > |
| <ImageView android:id="@+id/image" |
| android:layout_width="wrap_content" |
| android:layout_height="fill_parent" |
| android:layout_marginRight="10dp" |
| /> |
| <TextView android:id="@+id/text" |
| android:layout_width="wrap_content" |
| android:layout_height="fill_parent" |
| android:textColor="#000" |
| /> |
| </LinearLayout> |
| </pre> |
| |
| <p>This layout is used for the expanded view, |
| but the content of the ImageView and TextView still needs to be defined by the application. |
| RemoteViews offers some convenient methods that allow you to define this content...</p> |
| </li> |
| |
| <li>In the application code, use the RemoveViews |
| methods to define the image and text. Then pass the RemoteViews object to the <var>contentView</var> |
| field of the Notification, as shown in this example: |
| <pre> |
| RemoteViews contentView = new RemoteViews(getPackageName(), R.layout.custom_notification_layout); |
| contentView.setImageViewResource(R.id.image, R.drawable.notification_image); |
| contentView.setTextViewText(R.id.text, "Hello, this message is in a custom expanded view"); |
| notification.contentView = contentView; |
| </pre> |
| |
| <p>As shown here, pass the application's package name and the layout |
| resource ID to the RemoteViews constructor. Then, define the content for the ImageView and TextView, |
| using the {@link android.widget.RemoteViews#setImageViewResource(int, int) setImageViewResource()} |
| and {@link android.widget.RemoteViews#setTextViewText(int, CharSequence) setTextViewText()}. |
| In each case, pass the reference ID of the appropriate View object that you want to set, along with |
| the value for that View. Finally, the RemoteViews object is passed to the Notification in the |
| <var>contentView</var> field.</p> |
| </li> |
| |
| <li>Because you don't need the |
| {@link android.app.Notification#setLatestEventInfo(Context,CharSequence,CharSequence,PendingIntent) |
| setLatestEventInfo()} method when using a custom view, you must define the Intent for the Notification |
| with the <var>contentIntent</var> field, as in this example: |
| <pre> |
| Intent notificationIntent = new Intent(this, MyClass.class); |
| PendingIntent contentIntent = PendingIntent.getActivity(this, 0, notificationIntent, 0); |
| notification.contentIntent = contentIntent; |
| </pre> |
| </li> |
| |
| <li>The notification can now be sent as usual: |
| <pre>mNotificationManager.notify(CUSTOM_VIEW_ID, notification);</pre> |
| </li> |
| </ol> |
| |
| |
| <p>The RemoteViews class also includes methods that you can use to easily add a |
| {@link android.widget.Chronometer} or {@link android.widget.ProgressBar} |
| in your notification's expanded view. For more information about creating custom layouts with |
| RemoteViews, refer to the {@link android.widget.RemoteViews} class reference.</p> |
| |
| <p class="warning"><strong>Note:</strong> |
| When creating a custom expanded view, you must take special care to ensure that your |
| custom layout functions properly in different device orientations and resolutions. While this |
| advice applies to all View layouts created on Android, it is especially important in this case |
| because your layout real estate is very restricted. So don't make your custom layout too |
| complex and be sure to test it in various configurations.</p> |
| |
| |
| |
| |