diff options
author | && repo sync -j8 <kmccormick@google.com> | 2012-11-27 16:49:36 -0800 |
---|---|---|
committer | Android (Google) Code Review <android-gerrit@google.com> | 2012-11-27 16:49:37 -0800 |
commit | b7863a3ce4db964322783ff7e84acc5713e04d1d (patch) | |
tree | d10f3ab3a1b6c19c7b16fae3f0a0d2073f0ec159 /docs | |
parent | ddf10d44c12fbd8ffb115c847913296b455f412d (diff) | |
parent | 0aae00051c3e96a6271840c50f6b9e448c7064f4 (diff) | |
download | frameworks_base-b7863a3ce4db964322783ff7e84acc5713e04d1d.zip frameworks_base-b7863a3ce4db964322783ff7e84acc5713e04d1d.tar.gz frameworks_base-b7863a3ce4db964322783ff7e84acc5713e04d1d.tar.bz2 |
Merge "Doc update: new Notify User AU class" into jb-dev-docs
Diffstat (limited to 'docs')
-rw-r--r-- | docs/downloads/training/NotifyUser.zip | bin | 0 -> 130795 bytes | |||
-rw-r--r-- | docs/html/images/training/notifications-bigview.png | bin | 0 -> 20177 bytes | |||
-rw-r--r-- | docs/html/images/training/notifications-normalview.png | bin | 0 -> 5879 bytes | |||
-rw-r--r-- | docs/html/training/notify-user/build-notification.jd | 160 | ||||
-rw-r--r-- | docs/html/training/notify-user/display-progress.jd | 182 | ||||
-rw-r--r-- | docs/html/training/notify-user/expanded.jd | 167 | ||||
-rw-r--r-- | docs/html/training/notify-user/index.jd | 102 | ||||
-rw-r--r-- | docs/html/training/notify-user/managing.jd | 107 | ||||
-rw-r--r-- | docs/html/training/notify-user/navigation.jd | 228 | ||||
-rw-r--r-- | docs/html/training/training_toc.cs | 84 |
10 files changed, 1006 insertions, 24 deletions
diff --git a/docs/downloads/training/NotifyUser.zip b/docs/downloads/training/NotifyUser.zip Binary files differnew file mode 100644 index 0000000..c335157 --- /dev/null +++ b/docs/downloads/training/NotifyUser.zip diff --git a/docs/html/images/training/notifications-bigview.png b/docs/html/images/training/notifications-bigview.png Binary files differnew file mode 100644 index 0000000..83a5610 --- /dev/null +++ b/docs/html/images/training/notifications-bigview.png diff --git a/docs/html/images/training/notifications-normalview.png b/docs/html/images/training/notifications-normalview.png Binary files differnew file mode 100644 index 0000000..06ea970 --- /dev/null +++ b/docs/html/images/training/notifications-normalview.png diff --git a/docs/html/training/notify-user/build-notification.jd b/docs/html/training/notify-user/build-notification.jd new file mode 100644 index 0000000..ba66028 --- /dev/null +++ b/docs/html/training/notify-user/build-notification.jd @@ -0,0 +1,160 @@ +page.title=Building a Notification +parent.title=Notifying the User +parent.link=index.html + +trainingnavtop=true +next.title=Preserving Navigation when Starting an Activity +next.link=navigation.html + +@jd:body + +<div id="tb-wrapper"> +<div id="tb"> + +<!-- table of contents --> +<h2>This lesson teaches you to</h2> +<ol> + <li><a href="#builder">Create a Notification Builder</a></li> + <li><a href="#action">Define the Notification's Action</a></li> + <li><a href="#click">Set the Notification's Click Behavior</a></li> + <li><a href="#notify">Issue the Notification</a></li> +</ol> + +<!-- other docs (NOT javadocs) --> +<h2>You should also read</h2> + +<ul> + <li> + <a href="{@docRoot}guide/topics/ui/notifiers/notifications.html">Notifications</a> API Guide + </li> + <li> + <a href="{@docRoot}guide/components/intents-filters.html"> + Intents and Intent Filters + </a> + </li> + <li> + <a href="{@docRoot}design/patterns/notifications.html">Notifications</a> Design Guide + </li> +</ul> + + +</div> +</div> + + +<p>This lesson explains how to create and issue a notification.</p> + +<p>The examples in this class are based on the +{@link android.support.v4.app.NotificationCompat.Builder} class. +{@link android.support.v4.app.NotificationCompat.Builder} +is in the <a href="{@docRoot}">Support Library</a>. You should use +{@link android.support.v4.app.NotificationCompat} and its subclasses, +particularly {@link android.support.v4.app.NotificationCompat.Builder}, to +provide the best notification support for a wide range of platforms. </p> + +<h2 id="builder">Create a Notification Builder</h2> + +<p>When creating a notification, specify the UI content and actions with a +{@link android.support.v4.app.NotificationCompat.Builder} object. At bare minimum, +a {@link android.support.v4.app.NotificationCompat.Builder Builder} +object must include the following:</p> + +<ul> + <li> + A small icon, set by + {@link android.support.v4.app.NotificationCompat.Builder#setSmallIcon setSmallIcon()} + </li> + <li> + A title, set by + {@link android.support.v4.app.NotificationCompat.Builder#setContentTitle setContentTitle()} + </li> + <li> + Detail text, set by + {@link android.support.v4.app.NotificationCompat.Builder#setContentText setContentText()} + </li> +</ul> +<p> For example: </p> +<pre> +NotificationCompat.Builder mBuilder = + new NotificationCompat.Builder(this) + .setSmallIcon(R.drawable.notification_icon) + .setContentTitle("My notification") + .setContentText("Hello World!"); +</pre> + +<h2 id="action">Define the Notification's Action</h2> + + +<p>Although actions are optional, you should add at least one action to your +notification. An action takes users directly from the notification to an +{@link android.app.Activity} in your application, where they can look at the +event that caused the notification or do further work. Inside a notification, the action itself is +defined by a {@link android.app.PendingIntent} containing an {@link +android.content.Intent} that starts an {@link android.app.Activity} in your +application.</p> + +<p>How you construct the {@link android.app.PendingIntent} depends on what type +of {@link android.app.Activity} you're starting. When you start an {@link +android.app.Activity} from a notification, you must preserve the user's expected +navigation experience. In the snippet below, clicking the notification opens a +new activity that effectively extends the behavior of the notification. In this +case there is no need to create an artificial back stack (see +<a href="navigation.html">Preserving Navigation when Starting an Activity</a> for +more information):</p> + +<pre>Intent resultIntent = new Intent(this, ResultActivity.class); +... +// Because clicking the notification opens a new ("special") activity, there's +// no need to create an artificial back stack. +PendingIntent resultPendingIntent = + PendingIntent.getActivity( + this, + 0, + resultIntent, + PendingIntent.FLAG_UPDATE_CURRENT +); +</pre> + +<h2 id="click">Set the Notification's Click Behavior</h2> + +<p> +To associate the {@link android.app.PendingIntent} created in the previous +step with a gesture, call the appropriate method of {@link +android.support.v4.app.NotificationCompat.Builder}. For example, to start an +activity when the user clicks the notification text in the notification drawer, +add the {@link android.app.PendingIntent} by calling {@link +android.support.v4.app.NotificationCompat.Builder#setContentIntent +setContentIntent()}. For example:</p> + +<pre>PendingIntent resultPendingIntent; +... +mBuilder.setContentIntent(resultPendingIntent);</pre> + +<h2 id="notify">Issue the Notification</h2> + +<p>To issue the notification:</p> +<ul> +<li>Get an instance of {@link android.app.NotificationManager}.</li> + +<li>Use the {@link android.app.NotificationManager#notify notify()} method to issue the +notification. When you call {@link android.app.NotificationManager#notify notify()}, specify a notification ID. +You can use this ID to update the notification later on. This is described in more detail in +<a href="managing.html">Managing Notifications</a>.</li> + +<li>Call {@link +android.support.v4.app.NotificationCompat.Builder#build() build()}, which +returns a {@link android.app.Notification} object containing your +specifications.</li> + +<p>For example:</p> + +<pre> +// Sets an ID for the notification +int mNotificationId = 001; +// Gets an instance of the NotificationManager service +NotificationManager mNotifyMgr = + (NotificationManager) getSystemService(NOTIFICATION_SERVICE); +// Builds the notification and issues it. +mNotifyMgr.notify(mNotificationId, builder.build()); +</pre> + diff --git a/docs/html/training/notify-user/display-progress.jd b/docs/html/training/notify-user/display-progress.jd new file mode 100644 index 0000000..2b2b3ae --- /dev/null +++ b/docs/html/training/notify-user/display-progress.jd @@ -0,0 +1,182 @@ +page.title=Displaying Progress in a Notification +parent.title=Notifying the User +parent.link=index.html + +trainingnavtop=true +previous.title=Using Expanded Notification Styles +previous.link=expanded.html + +@jd:body + +<div id="tb-wrapper"> +<div id="tb"> + +<!-- table of contents --> +<h2>This lesson teaches you to</h2> +<ol> + <li><a href="#FixedProgress">Display a Fixed-duration progress Indicator</a></li> + <li><a href="#ActivityIndicator">Display a Continuing Activity Indicator</a></li> +</ol> + +<!-- other docs (NOT javadocs) --> +<h2>You should also read</h2> + +<ul> + <li> + <a href="{@docRoot}guide/topics/ui/notifiers/notifications.html">Notifications</a> API Guide + </li> + <li> + <a href="{@docRoot}guide/components/intents-filters.html"> + Intents and Intent Filters + </a> + </li> + <li> + <a href="{@docRoot}design/patterns/notifications.html">Notifications</a> Design Guide + </li> +</ul> + + +</div> +</div> + + + +<p> + Notifications can include an animated progress indicator that shows users the status + of an ongoing operation. If you can estimate how long the operation takes and how much of it + is complete at any time, use the "determinate" form of the indicator + (a progress bar). If you can't estimate the length of the operation, use the + "indeterminate" form of the indicator (an activity indicator). +</p> +<p> + Progress indicators are displayed with the platform's implementation of the + {@link android.widget.ProgressBar} class. +</p> +<p> + To use a progress indicator, call + {@link android.support.v4.app.NotificationCompat.Builder#setProgress setProgress()}. The + determinate and indeterminate forms are described in the following sections. +</p> +<!-- ------------------------------------------------------------------------------------------ --> +<h2 id="FixedProgress">Display a Fixed-duration Progress Indicator</h2> +<p> + To display a determinate progress bar, add the bar to your notification by calling + {@link android.support.v4.app.NotificationCompat.Builder#setProgress + setProgress(max, progress, false)} and then issue the notification. + The third argument is a boolean that indicates whether the + progress bar is indeterminate (<strong>true</strong>) or determinate (<strong>false</strong>). + As your operation proceeds, + increment <code>progress</code>, and update the notification. At the end of the operation, + <code>progress</code> should equal <code>max</code>. A common way to call + {@link android.support.v4.app.NotificationCompat.Builder#setProgress setProgress()} + is to set <code>max</code> to 100 and then increment <code>progress</code> as a + "percent complete" value for the operation. +</p> +<p> + You can either leave the progress bar showing when the operation is done, or remove it. In + either case, remember to update the notification text to show that the operation is complete. + To remove the progress bar, call + {@link android.support.v4.app.NotificationCompat.Builder#setProgress + setProgress(0, 0, false)}. For example: +</p> +<pre> +... +mNotifyManager = + (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE); +mBuilder = new NotificationCompat.Builder(this); +mBuilder.setContentTitle("Picture Download") + .setContentText("Download in progress") + .setSmallIcon(R.drawable.ic_notification); +// Start a lengthy operation in a background thread +new Thread( + new Runnable() { + @Override + public void run() { + int incr; + // Do the "lengthy" operation 20 times + for (incr = 0; incr <= 100; incr+=5) { + // Sets the progress indicator to a max value, the + // current completion percentage, and "determinate" + // state + mBuilder.setProgress(100, incr, false); + // Displays the progress bar for the first time. + mNotifyManager.notify(0, mBuilder.build()); + // Sleeps the thread, simulating an operation + // that takes time + try { + // Sleep for 5 seconds + Thread.sleep(5*1000); + } catch (InterruptedException e) { + Log.d(TAG, "sleep failure"); + } + } + // When the loop is finished, updates the notification + mBuilder.setContentText("Download complete") + // Removes the progress bar + .setProgress(0,0,false); + mNotifyManager.notify(ID, mBuilder.build()); + } + } +// Starts the thread by calling the run() method in its Runnable +).start(); +</pre> +<p> + The resulting notifications are shown in figure 1. On the left side is a snapshot of the + notification during the operation; on the right side is a snapshot of it after the operation + has finished. +</p> +<img + id="figure1" + src="{@docRoot}images/ui/notifications/progress_bar_summary.png" + height="84" + alt="" /> +<p class="img-caption"> +<strong>Figure 1.</strong> The progress bar during and after the operation.</p> +<!-- ------------------------------------------------------------------------------------------ --> +<h2 id="ActivityIndicator">Display a Continuing Activity Indicator</h2> +<p> + To display a continuing (indeterminate) activity indicator, add it to your notification with + {@link android.support.v4.app.NotificationCompat.Builder#setProgress setProgress(0, 0, true)} + and issue the notification. The first two arguments are ignored, and the third argument + declares that the indicator is indeterminate. The result is an indicator + that has the same style as a progress bar, except that its animation is ongoing. +</p> +<p> + Issue the notification at the beginning of the operation. The animation will run until you + modify your notification. When the operation is done, call + {@link android.support.v4.app.NotificationCompat.Builder#setProgress + setProgress(0, 0, false)} and then update the notification to remove the activity indicator. + Always do this; otherwise, the animation will run even when the operation is complete. Also + remember to change the notification text to indicate that the operation is complete. +</p> +<p> + To see how continuing activity indicators work, refer to the preceding snippet. Locate the following lines: +</p> +<pre> +// Sets the progress indicator to a max value, the current completion +// percentage, and "determinate" state +mBuilder.setProgress(100, incr, false); +// Issues the notification +mNotifyManager.notify(0, mBuilder.build()); +</pre> +<p> + Replace the lines you've found with the following lines. Notice that the third parameter + in the {@link android.support.v4.app.NotificationCompat.Builder#setProgress setProgress()} + call is set to {@code true} to indicate that the progress bar is + indeterminate: +</p> +<pre> + // Sets an activity indicator for an operation of indeterminate length +mBuilder.setProgress(0, 0, true); +// Issues the notification +mNotifyManager.notify(0, mBuilder.build()); +</pre> +<p> + The resulting indicator is shown in figure 2: +</p> +<img + id="figure2" + src="{@docRoot}images/ui/notifications/activity_indicator.png" + height="99" + alt="" /> +<p class="img-caption"><strong>Figure 2.</strong> An ongoing activity indicator.</p> diff --git a/docs/html/training/notify-user/expanded.jd b/docs/html/training/notify-user/expanded.jd new file mode 100644 index 0000000..a3cc6ad --- /dev/null +++ b/docs/html/training/notify-user/expanded.jd @@ -0,0 +1,167 @@ +page.title=Using Big View Styles +Styles parent.title=Notifying the User +parent.link=index.html + +trainingnavtop=true +next.title=Displaying Progress in a Notification +next.link=display-progress.html + +@jd:body + +<div id="tb-wrapper"> +<div id="tb"> + +<!-- table of contents --> +<h2>This lesson teaches you to</h2> +<ol> + <li><a href="#activity">Set Up the Notification to Launch a New Activity</a></li> + <li><a href="#big-view">Construct the Big View</a></li> +</ol> + +<!-- other docs (NOT javadocs) --> +<h2>You should also read</h2> + +<ul> + <li> + <a href="{@docRoot}guide/topics/ui/notifiers/notifications.html">Notifications</a> API Guide + </li> + <li> + <a href="{@docRoot}guide/components/intents-filters.html"> + Intents and Intent Filters + </a> + </li> + <li> + <a href="{@docRoot}design/patterns/notifications.html">Notifications</a> Design Guide + </li> +</ul> + + +</div> +</div> + +<p>Notifications in the notification drawer appear in two main visual styles, +normal view and big view. The big view of a notification only appears when the +notification is expanded. This happens when the notification is at the top of +the drawer, or the user clicks the notification. </p> + +<p>Big views were introduced in +Android 4.1, and they're not supported on older devices. This lesson describes +how to incorporate big view notifications into your app while still providing +full functionality via the normal view. See the <a +href="{@docRoot}guide/topics/ui/notifiers/notifications.html#BigNotify"> +Notifications API guide</a> for more discussion of big views.</p> + +<p>Here is an example of a normal view: </p> + +<img src="{@docRoot}images/training/notifications-normalview.png" width="300" height="58" alt="normal view" /> + +<p class="img-caption"> + <strong>Figure 1.</strong> Normal view notification. +</p> + + +<p>Here is an example of a big view:</p> + +<img src="{@docRoot}images/training/notifications-bigview.png" width="300" height="143" alt="big view" /> +<p class="img-caption"> + <strong>Figure 2.</strong> Big view notification. +</p> + + +<p> In the sample application shown in this lesson, both the normal view and the +big view give users access to same functionality:</p> + +<ul> + <li>The ability to snooze or dismiss the notification.</li> + <li>A way to view the reminder text the user set as part of the timer.</li> +</ul> + +<p>The normal view provides these features through a new activity that launches +when the user clicks the notification. Keep this in mind as you design your notifications—first +provide the functionality in the normal view, since +this is how many users will interact with the notification.</p> + +<h2 id="activity">Set Up the Notification to Launch a New Activity</h2> + +<p>The sample application uses an {@link android.app.IntentService} subclass ({@code PingService}) +to construct and issue the notification.</p> + + +<p>In this snippet, the +{@link android.app.IntentService} method +{@link android.app.IntentService#onHandleIntent onHandleIntent()} specifies the new activity +that will be launched if the user +clicks the notification itself. The method +{@link android.support.v4.app.NotificationCompat.Builder#setContentIntent setContentIntent()} +defines a pending intent that should be fired when the user +clicks the notification, thereby launching the activity.</p> + +<pre>Intent resultIntent = new Intent(this, ResultActivity.class); +resultIntent.putExtra(CommonConstants.EXTRA_MESSAGE, msg); +resultIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | + Intent.FLAG_ACTIVITY_CLEAR_TASK); + +// Because clicking the notification launches a new ("special") activity, +// there's no need to create an artificial back stack. +PendingIntent resultPendingIntent = + PendingIntent.getActivity( + this, + 0, + resultIntent, + PendingIntent.FLAG_UPDATE_CURRENT +); + +// This sets the pending intent that should be fired when the user clicks the +// notification. Clicking the notification launches a new activity. +builder.setContentIntent(resultPendingIntent); +</pre> + +<h2 id="big-view">Construct the Big View</h2> + +<p>This snippet shows how to set up the buttons that will appear in the big view:</p> + +<pre> +// Sets up the Snooze and Dismiss action buttons that will appear in the +// big view of the notification. +Intent dismissIntent = new Intent(this, PingService.class); +dismissIntent.setAction(CommonConstants.ACTION_DISMISS); +PendingIntent piDismiss = PendingIntent.getService(this, 0, dismissIntent, 0); + +Intent snoozeIntent = new Intent(this, PingService.class); +snoozeIntent.setAction(CommonConstants.ACTION_SNOOZE); +PendingIntent piSnooze = PendingIntent.getService(this, 0, snoozeIntent, 0); +</pre> + +<p>This snippet shows how to construct the +{@link android.support.v4.app.NotificationCompat.Builder Builder} object. +It sets the style for the big +view to be "big text," and sets its content to be the reminder message. It uses +{@link android.support.v4.app.NotificationCompat.Builder#addAction addAction()} +to add the <strong>Snooze</strong> and <strong>Dismiss</strong> buttons (and +their associated pending intents) that will appear in the notification's +big view:</p> + +<pre>// Constructs the Builder object. +NotificationCompat.Builder builder = + new NotificationCompat.Builder(this) + .setSmallIcon(R.drawable.ic_stat_notification) + .setContentTitle(getString(R.string.notification)) + .setContentText(getString(R.string.ping)) + .setDefaults(Notification.DEFAULT_ALL) // requires VIBRATE permission + /* + * Sets the big view "big text" style and supplies the + * text (the user's reminder message) that will be displayed + * in the detail area of the expanded notification. + * These calls are ignored by the support library for + * pre-4.1 devices. + */ + .setStyle(new NotificationCompat.BigTextStyle() + .bigText(msg)) + .addAction (R.drawable.ic_stat_dismiss, + getString(R.string.dismiss), piDismiss) + .addAction (R.drawable.ic_stat_snooze, + getString(R.string.snooze), piSnooze); +</pre> + + + diff --git a/docs/html/training/notify-user/index.jd b/docs/html/training/notify-user/index.jd new file mode 100644 index 0000000..510f2c4 --- /dev/null +++ b/docs/html/training/notify-user/index.jd @@ -0,0 +1,102 @@ +page.title=Notifying the User +trainingnavtop=true +startpage=true +next.title=Build a Notification +next.link=build-notification.html + + +@jd:body +<div id="tb-wrapper"> +<div id="tb"> + +<!-- Required platform, tools, add-ons, devices, knowledge, etc. --> +<h2>Dependencies and prerequisites</h2> + +<ul> + <li>Android 1.6 (API Level 4) or higher</li> +</ul> +<h2>You should also read</h2> +<ul> + <li> + <a href="{@docRoot}guide/topics/ui/notifiers/notifications.html">Notifications</a> API Guide + </li> + <li> + <a href="{@docRoot}guide/components/intents-filters.html"> + Intents and Intent Filters + </a> + </li> + <li> + <a href="{@docRoot}design/patterns/notifications.html">Notifications</a> Design Guide + </li> +</ul> + +<h2>Try it out</h2> + +<div class="download-box"> + <a href="{@docRoot}shareables/training/NotifyUser.zip" +class="button">Download the sample</a> + <p class="filename">NotifyUser.zip</p> +</div> + +</div> +</div> + +<p> + A notification is a user interface element that you display outside your app's normal UI to indicate + that an event has occurred. Users can choose to view the notification while using other apps and respond + to it when it's convenient for them. + +</p> + +<p> + The <a href="{@docRoot}design/patterns/notifications.html">Notifications design guide</a> shows + you how to design effective notifications and when to use them. This class shows you how to + implement the most common notification designs. +</p> +<h2>Lessons</h2> + +<dl> + <dt> + <strong><a href="build-notification.html">Building a Notification</a></strong> + </dt> + <dd> + Learn how to create a notification + {@link android.support.v4.app.NotificationCompat.Builder Builder}, set the + required features, and issue the notification. + </dd> + <dt> + <strong><a href="navigation.html">Preserving Navigation when Starting an Activity</a></strong> + </dt> + <dd> + Learn how to enforce the proper + navigation for an {@link android.app.Activity} started from a notification. + </dd> + <dt> + <strong> + <a href="managing.html">Updating Notifications</a> + </strong> + </dt> + <dd> + Learn how to update and remove notifications. + </dd> + <dt> + <strong> + <a href="expanded.html">Using Big View Styles</a> + </strong> + </dt> + <dd> + Learn how to create a big view within an expanded notification, while still maintaining + backward compatibility. + </dd> + + <dt> + <strong> + <a href="display-progress.html">Displaying Progress in a Notification</a> + </strong> + </dt> + <dd> + Learn how to display the progress of an operation in a notification, both for + operations where you can estimate how much has been completed (determinate progress) and + operations where you don't know how much has been completed (indefinite progress). + </dd> +</dl> diff --git a/docs/html/training/notify-user/managing.jd b/docs/html/training/notify-user/managing.jd new file mode 100644 index 0000000..4782734 --- /dev/null +++ b/docs/html/training/notify-user/managing.jd @@ -0,0 +1,107 @@ +page.title=Updating Notifications +parent.title=Notifying the User +parent.link=index.html + +trainingnavtop=true +next.title=Creating Expanded Notifications +next.link=expanded.html + +@jd:body + +<div id="tb-wrapper"> +<div id="tb"> + +<!-- table of contents --> +<h2>This lesson teaches you to</h2> +<ol> + <li><a href="#Updating">Modify a Notification</a></li> + <li><a href="#Removing">Remove Notifications</a></li> +</ol> + +<!-- other docs (NOT javadocs) --> +<h2>You should also read</h2> + +<ul> + <li> + <a href="{@docRoot}guide/topics/ui/notifiers/notifications.html">Notifications</a> API Guide + </li> + <li> + <a href="{@docRoot}guide/components/intents-filters.html"> + Intents and Intent Filters + </a> + </li> + <li> + <a href="{@docRoot}design/patterns/notifications.html">Notifications</a> Design Guide + </li> +</ul> + + +</div> +</div> +<p> + When you need to issue a notification multiple times for the same type of event, you + should avoid making a completely new notification. Instead, you should consider updating a + previous notification, either by changing some of its values or by adding to it, or both. +</p> + +<p> + The following section describes how to update notifications and also how to remove them. +</p> +<h2 id="Updating">Modify a Notification</h2> +<p> + To set up a notification so it can be updated, issue it with a notification ID by + calling {@link android.app.NotificationManager#notify(int, Notification) + NotificationManager.notify(ID, notification)}. To update this notification once you've issued + it, update or create a {@link android.support.v4.app.NotificationCompat.Builder} object, + build a {@link android.app.Notification} object from it, and issue the + {@link android.app.Notification} with the same ID you used previously. +</p> +<p> + The following snippet demonstrates a notification that is updated to reflect the + number of events that have occurred. It stacks the notification, showing a summary: +</p> +<pre> +mNotificationManager = + (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE); +// Sets an ID for the notification, so it can be updated +int notifyID = 1; +mNotifyBuilder = new NotificationCompat.Builder(this) + .setContentTitle("New Message") + .setContentText("You've received new messages.") + .setSmallIcon(R.drawable.ic_notify_status) +numMessages = 0; +// Start of a loop that processes data and then notifies the user +... + mNotifyBuilder.setContentText(currentText) + .setNumber(++numMessages); + // Because the ID remains unchanged, the existing notification is + // updated. + mNotificationManager.notify( + notifyID, + mNotifyBuilder.build()); +... +</pre> + +<!-- ------------------------------------------------------------------------------------------ --> +<h2 id="Removing">Remove Notifications</h2> +<p> + Notifications remain visible until one of the following happens: +</p> +<ul> + <li> + The user dismisses the notification either individually or by using "Clear All" (if + the notification can be cleared). + </li> + <li> + The user touches the notification, and you called + {@link android.support.v4.app.NotificationCompat.Builder#setAutoCancel setAutoCancel()} when + you created the notification. + </li> + <li> + You call {@link android.app.NotificationManager#cancel(int) cancel()} for a specific + notification ID. This method also deletes ongoing notifications. + </li> + <li> + You call {@link android.app.NotificationManager#cancelAll() cancelAll()}, which removes + all of the notifications you previously issued. + </li> diff --git a/docs/html/training/notify-user/navigation.jd b/docs/html/training/notify-user/navigation.jd new file mode 100644 index 0000000..ac4689a --- /dev/null +++ b/docs/html/training/notify-user/navigation.jd @@ -0,0 +1,228 @@ +page.title=Preserving Navigation when Starting an Activity +parent.title=Notifying the User +parent.link=index.html + +trainingnavtop=true +next.title=Updating Notifications +next.link=managing.html + +@jd:body + +<div id="tb-wrapper"> +<div id="tb"> + +<!-- table of contents --> +<h2>This lesson teaches you to</h2> +<ol> + <li><a href="#DirectEntry">Set up a regular activity PendingIntent</a></li> + <li><a href="#ExtendedNotification">Set up a special activity PendingIntent</a></li> +</ol> + +<!-- other docs (NOT javadocs) --> +<h2>You should also read</h2> + +<ul> + <li> + <a href="{@docRoot}guide/topics/ui/notifiers/notifications.html">Notifications</a> API Guide + </li> + <li> + <a href="{@docRoot}guide/components/intents-filters.html"> + Intents and Intent Filters + </a> + </li> + <li> + <a href="{@docRoot}design/patterns/notifications.html">Notifications</a> Design Guide + </li> +</ul> + + +</div> +</div> +<p> + Part of designing a notification is preserving the user's expected navigation experience. + For a detailed discussion of this topic, see the + <a href="{@docRoot}guide/topics/ui/notifiers/notifications.html#NotificationResponse">Notifications</a> + API guide. + There are two general situations: +</p> +<dl> + <dt> + Regular activity + </dt> + <dd> + You're starting an {@link android.app.Activity} that's part of the application's normal + workflow. + </dd> + <dt> + Special activity + </dt> + <dd> + The user only sees this {@link android.app.Activity} if it's started from a notification. + In a sense, the {@link android.app.Activity} extends the notification by providing + information that would be hard to display in the notification itself. + </dd> +</dl> +<!-- ------------------------------------------------------------------------------------------ --> +<h2 id="DirectEntry">Set Up a Regular Activity PendingIntent</h2> +<p> + To set up a {@link android.app.PendingIntent} that starts a direct entry + {@link android.app.Activity}, follow these steps: +</p> +<ol> + <li> + Define your application's {@link android.app.Activity} hierarchy in the manifest. The final XML should look like this: + </p> +<pre> +<activity + android:name=".MainActivity" + android:label="@string/app_name" > + <intent-filter> + <action android:name="android.intent.action.MAIN" /> + <category android:name="android.intent.category.LAUNCHER" /> + </intent-filter> +</activity> +<activity + android:name=".ResultActivity" + android:parentActivityName=".MainActivity"> + <meta-data + android:name="android.support.PARENT_ACTIVITY" + android:value=".MainActivity"/> +</activity> +</pre> + </li> + <li> + Create a back stack based on the {@link android.content.Intent} that starts the + {@link android.app.Activity}. For example: +</p> +<pre> +... +Intent resultIntent = new Intent(this, ResultActivity.class); +TaskStackBuilder stackBuilder = TaskStackBuilder.create(this); +// Adds the back stack +stackBuilder.addParentStack(ResultActivity.class); +// Adds the Intent to the top of the stack +stackBuilder.addNextIntent(resultIntent); +// Gets a PendingIntent containing the entire back stack +PendingIntent resultPendingIntent = + stackBuilder.getPendingIntent(0, PendingIntent.FLAG_UPDATE_CURRENT); +... +NotificationCompat.Builder builder = new NotificationCompat.Builder(this); +builder.setContentIntent(resultPendingIntent); +NotificationManager mNotificationManager = + (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE); +mNotificationManager.notify(id, builder.build()); +</pre> +<!-- ------------------------------------------------------------------------------------------ --> +<h2 id="ExtendedNotification">Set Up a Special Activity PendingIntent</h2> + +<p> + A special {@link android.app.Activity} doesn't need a back stack, so you don't have to + define its {@link android.app.Activity} hierarchy in the manifest, and you don't have + to call + {@link android.support.v4.app.TaskStackBuilder#addParentStack addParentStack()} to build a + back stack. Instead, use the manifest to set up the {@link android.app.Activity} task options, + and create the {@link android.app.PendingIntent} by calling + {@link android.app.PendingIntent#getActivity getActivity()}: +</p> +<ol> + <li> + In your manifest, add the following attributes to the +<code><a href="{@docRoot}guide/topics/manifest/activity-element.html"><activity></a></code> + element for the {@link android.app.Activity}: + <dl> + <dt> +<code><a href="{@docRoot}guide/topics/manifest/activity-element.html#nm">android:name</a>="<i>activityclass</i>"</code> + </dt> + <dd> + The activity's fully-qualified class name. + </dd> + <dt> +<code><a href="{@docRoot}guide/topics/manifest/activity-element.html#aff">android:taskAffinity</a>=""</code> + </dt> + <dd> + Combined with the + {@link android.content.Intent#FLAG_ACTIVITY_NEW_TASK FLAG_ACTIVITY_NEW_TASK} flag + that you set in code, this ensures that this {@link android.app.Activity} doesn't + go into the application's default task. Any existing tasks that have the + application's default affinity are not affected. + </dd> + <dt> +<code><a href="{@docRoot}guide/topics/manifest/activity-element.html#exclude">android:excludeFromRecents</a>="true"</code> + </dt> + <dd> + Excludes the new task from <i>Recents</i>, so that the user can't accidentally + navigate back to it. + </dd> + </dl> + <p> + This snippet shows the element: + </p> +<pre> +<activity + android:name=".ResultActivity" +... + android:launchMode="singleTask" + android:taskAffinity="" + android:excludeFromRecents="true"> +</activity> +... +</pre> + </li> + <li> + Build and issue the notification: + <ol style="list-style-type: lower-alpha;"> + <li> + Create an {@link android.content.Intent} that starts the + {@link android.app.Activity}. + </li> + <li> + Set the {@link android.app.Activity} to start in a new, empty task by calling + {@link android.content.Intent#setFlags setFlags()} with the flags + {@link android.content.Intent#FLAG_ACTIVITY_NEW_TASK FLAG_ACTIVITY_NEW_TASK} + and + {@link android.content.Intent#FLAG_ACTIVITY_CLEAR_TASK FLAG_ACTIVITY_CLEAR_TASK}. + </li> + <li> + Set any other options you need for the {@link android.content.Intent}. + </li> + <li> + Create a {@link android.app.PendingIntent} from the {@link android.content.Intent} + by calling {@link android.app.PendingIntent#getActivity getActivity()}. + You can then use this {@link android.app.PendingIntent} as the argument to + {@link android.support.v4.app.NotificationCompat.Builder#setContentIntent + setContentIntent()}. + </li> + </ol> + <p> + The following code snippet demonstrates the process: + </p> +<pre> +// Instantiate a Builder object. +NotificationCompat.Builder builder = new NotificationCompat.Builder(this); +// Creates an Intent for the Activity +Intent notifyIntent = + new Intent(new ComponentName(this, ResultActivity.class)); +// Sets the Activity to start in a new, empty task +notifyIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | + Intent.FLAG_ACTIVITY_CLEAR_TASK); +// Creates the PendingIntent +PendingIntent notifyIntent = + PendingIntent.getActivity( + this, + 0, + notifyIntent, + PendingIntent.FLAG_UPDATE_CURRENT +); + +// Puts the PendingIntent into the notification builder +builder.setContentIntent(notifyIntent); +// Notifications are issued by sending them to the +// NotificationManager system service. +NotificationManager mNotificationManager = + (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE); +// Builds an anonymous Notification object from the builder, and +// passes it to the NotificationManager +mNotificationManager.notify(id, builder.build()); +</pre> + </li> +</ol> diff --git a/docs/html/training/training_toc.cs b/docs/html/training/training_toc.cs index ece5582..c1cb590 100644 --- a/docs/html/training/training_toc.cs +++ b/docs/html/training/training_toc.cs @@ -417,7 +417,6 @@ </li> </ul> </li> - <li class="nav-section"> <div class="nav-section-header"> <a href="<?cs var:toroot ?>training/efficient-downloads/index.html" @@ -601,6 +600,66 @@ </li> </ul> </li> + + <li class="nav-section"> + <div class="nav-section-header"> + <a href="<?cs var:toroot ?>training/notify-user/index.html" + description= + "How to display messages called notifications outside of + your application's UI." + >Notifying the User</a> + </div> + <ul> + <li> + <a href="<?cs var:toroot ?>training/notify-user/build-notification.html"> + Building a Notification + </a> + </li> + <li> + <a href="<?cs var:toroot ?>training/notify-user/navigation.html"> + Preserving Navigation when Starting an Activity + </a> + </li> + <li> + <a href="<?cs var:toroot ?>training/notify-user/managing.html"> + Updating Notifications + </a> + </li> + <li> + <a href="<?cs var:toroot ?>training/notify-user/expanded.html"> + Using Big View Styles + </a> + </li> + <li> + <a href="<?cs var:toroot ?>training/notify-user/display-progress.html"> + Displaying Progress in a Notification + </a> + </li> + </ul> + </li> + + <li class="nav-section"> + <div class="nav-section-header"> + <a href="<?cs var:toroot ?>training/search/index.html" + description= + "How to properly add a search interface to your app and create a searchable database." + >Adding Search Functionality</a> + </div> + <ul> + <li><a href="<?cs var:toroot ?>training/search/setup.html"> + Setting up the Search Interface + </a> + </li> + <li><a href="<?cs var:toroot ?>training/search/search.html"> + Storing and Searching for Data + </a> + </li> + <li><a href="<?cs var:toroot ?>training/search/backward-compat.html"> + Remaining Backward Compatible + </a> + </li> + </ul> + </li> <li class="nav-section"> @@ -660,29 +719,6 @@ </li> </ul> </li> - - <li class="nav-section"> - <div class="nav-section-header"> - <a href="<?cs var:toroot ?>training/search/index.html" - description= - "How to properly add a search interface to your app and create a searchable database." - >Adding Search Functionality</a> - </div> - <ul> - <li><a href="<?cs var:toroot ?>training/search/setup.html"> - Setting up the Search Interface - </a> - </li> - <li><a href="<?cs var:toroot ?>training/search/search.html"> - Storing and Searching for Data - </a> - </li> - <li><a href="<?cs var:toroot ?>training/search/backward-compat.html"> - Remaining Backward Compatible - </a> - </li> - </ul> - </li> <li class="nav-section"> <div class="nav-section-header"> |