am cc7bd5ab
: Merge "Update notification documentation to follow current guidelines." into ics-mr1
* commit 'cc7bd5ab550855c14c76701709b35d12a9677eb2': Update notification documentation to follow current guidelines.
This commit is contained in:
@ -113,7 +113,10 @@ public class Notification implements Parcelable
|
|||||||
* {@link android.content.Intent#FLAG_ACTIVITY_NEW_TASK} flag, which requires
|
* {@link android.content.Intent#FLAG_ACTIVITY_NEW_TASK} flag, which requires
|
||||||
* that you take care of task management as described in the
|
* that you take care of task management as described in the
|
||||||
* <a href="{@docRoot}guide/topics/fundamentals/tasks-and-back-stack.html">Tasks and Back
|
* <a href="{@docRoot}guide/topics/fundamentals/tasks-and-back-stack.html">Tasks and Back
|
||||||
* Stack</a> document.
|
* Stack</a> document. In particular, make sure to read the notification section
|
||||||
|
* <a href="{@docRoot}guide/topics/ui/notifiers/notifications.html#HandlingNotifications">Handling
|
||||||
|
* Notifications</a> for the correct ways to launch an application from a
|
||||||
|
* notification.
|
||||||
*/
|
*/
|
||||||
public PendingIntent contentIntent;
|
public PendingIntent contentIntent;
|
||||||
|
|
||||||
@ -765,7 +768,9 @@ public class Notification implements Parcelable
|
|||||||
* Supply a {@link PendingIntent} to send when the notification is clicked.
|
* Supply a {@link PendingIntent} to send when the notification is clicked.
|
||||||
* If you do not supply an intent, you can now add PendingIntents to individual
|
* If you do not supply an intent, you can now add PendingIntents to individual
|
||||||
* views to be launched when clicked by calling {@link RemoteViews#setOnClickPendingIntent
|
* views to be launched when clicked by calling {@link RemoteViews#setOnClickPendingIntent
|
||||||
* RemoteViews.setOnClickPendingIntent(int,PendingIntent)}.
|
* RemoteViews.setOnClickPendingIntent(int,PendingIntent)}. Be sure to
|
||||||
|
* read {@link Notification#contentIntent Notification.contentIntent} for
|
||||||
|
* how to correctly use this.
|
||||||
*/
|
*/
|
||||||
public Builder setContentIntent(PendingIntent intent) {
|
public Builder setContentIntent(PendingIntent intent) {
|
||||||
mContentIntent = intent;
|
mContentIntent = intent;
|
||||||
|
@ -40,7 +40,7 @@ parent.link=index.html
|
|||||||
<li><a href=#reusing_tip>Handle case where no activity matches</a></li>
|
<li><a href=#reusing_tip>Handle case where no activity matches</a></li>
|
||||||
<li><a href=#activity_launching_tip>Consider how to launch your activities</a></li>
|
<li><a href=#activity_launching_tip>Consider how to launch your activities</a></li>
|
||||||
<li><a href=#activities_added_to_task_tip>Allow activities to add to current task</a></li>
|
<li><a href=#activities_added_to_task_tip>Allow activities to add to current task</a></li>
|
||||||
<li><a href=#notifications_get_back_tip>Notifications should let user easily get back</li>
|
<li><a href=#notifications_get_back_tip>Notifications and App Widgets should provide consistent back behavior</li>
|
||||||
<li><a href=#use_notification_tip>Use the notification system</a></li>
|
<li><a href=#use_notification_tip>Use the notification system</a></li>
|
||||||
<li><a href=#taking_over_back_key>Don't take over BACK key unless you absolutely need to</a></li>
|
<li><a href=#taking_over_back_key>Don't take over BACK key unless you absolutely need to</a></li>
|
||||||
</ol>
|
</ol>
|
||||||
@ -1063,110 +1063,23 @@ MAIN and
|
|||||||
</p>
|
</p>
|
||||||
|
|
||||||
|
|
||||||
<h3 id="notifications_get_back_tip">Notifications should let the user easily get back to the previous activity</h3>
|
<h3 id="notifications_get_back_tip">Notifications and App Widgets should provide consistent back behavior</h3>
|
||||||
<p>
|
<p>
|
||||||
Applications that are in the background or not running can have
|
Notifications and app widgets are two common ways that a user can launch
|
||||||
services that send out notifications to the user letting them know about
|
your app through something besides its main icon in Launcher. You must
|
||||||
events of interest. Two examples are Calendar, which can send out notifications of
|
take care when implementing these so that the user has a consistent experience
|
||||||
upcoming events, and Email, which can send out notifications when new
|
with the back button, not causing surprises in where they return to or the
|
||||||
messages arrive. One of the user interface guidelines is that when the
|
state the application ends up in.
|
||||||
user is in activity A, gets a notification for activity B and
|
|
||||||
picks that notification, when they press the BACK key, they should
|
|
||||||
go back to activity A.
|
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
<p>
|
<p>
|
||||||
The following scenario shows how the activity stack should work
|
The
|
||||||
when the user responds to a notification.
|
<a href="{@docRoot}guide/topics/ui/notifiers/notifications.html#HandlingNotifications">Handling
|
||||||
</p>
|
Notifications</a> section of the developer guide's
|
||||||
|
<a href="{@docRoot}guide/topics/ui/notifiers/notifications.html">Status Bar Notifications</a>
|
||||||
<ol>
|
documentation provides an overview of how to write code to correctly handle
|
||||||
<li>
|
notification. This dicussion applies equally to handling interactions with
|
||||||
User is creating a new event in Calendar. They realize they
|
app widgets.
|
||||||
need to copy part of an email message into this event
|
|
||||||
</li>
|
|
||||||
<li>
|
|
||||||
The user chooses Home > Gmail
|
|
||||||
</li>
|
|
||||||
<li>
|
|
||||||
While in Gmail, they receive a notification from Calendar for an upcoming meeting
|
|
||||||
</li>
|
|
||||||
<li>
|
|
||||||
So they choose that notification, which takes them to a
|
|
||||||
dedicated Calendar activity that displays brief details of the
|
|
||||||
upcoming meeting
|
|
||||||
</li>
|
|
||||||
<li>
|
|
||||||
The user chooses this short notice to view further details
|
|
||||||
</li>
|
|
||||||
<li>
|
|
||||||
When done viewing the event, the user presses the BACK
|
|
||||||
key. They should be taken to Gmail, which is where they were
|
|
||||||
when they took the notification
|
|
||||||
</li>
|
|
||||||
</ol>
|
|
||||||
|
|
||||||
<p>
|
|
||||||
This behavior doesn't necessarily happen by default.
|
|
||||||
</p>
|
|
||||||
|
|
||||||
<p>
|
|
||||||
Notifications generally happen primarily in one of two ways:
|
|
||||||
</p>
|
|
||||||
|
|
||||||
<ul>
|
|
||||||
<li>
|
|
||||||
<b>The chosen activity is dedicated for notification only</b> -
|
|
||||||
For example, when the user receives a
|
|
||||||
Calendar notification, choosing that
|
|
||||||
notification starts a special activity that displays a list
|
|
||||||
of upcoming calendar events — this view is available only
|
|
||||||
from the notification, not through the Calendar's own user
|
|
||||||
interface. After viewing this upcoming event, to ensure that
|
|
||||||
the user pressing the BACK key will return to the activity
|
|
||||||
the user was in when they picked the notification, you would
|
|
||||||
make sure this dedicated activity does not have the same
|
|
||||||
task affinity as the Calendar or any other activity. (You do
|
|
||||||
this by setting task affinity to the empty string, which
|
|
||||||
means it has no affinity to anything.) The explanation for
|
|
||||||
this follows.
|
|
||||||
|
|
||||||
<p>
|
|
||||||
Because of the way tasks work, if the taskAffinity of the
|
|
||||||
dedicated activity is kept as its default, then pressing the
|
|
||||||
BACK key (in step 6, above) would go to Calendar, rather
|
|
||||||
than Gmail. The reason is that, by default, all activities
|
|
||||||
in a given application have the same task
|
|
||||||
affinity. Therefore, the task affinity of the dedicated
|
|
||||||
activity matches the Calendar task, which is already running
|
|
||||||
in step 1. This means in step 4, choosing the notification
|
|
||||||
brings the existing Calendar event (in step 1) forward and
|
|
||||||
starts the dedicated activity on top of it. This is not
|
|
||||||
what you want to have happen. Setting the dedicated
|
|
||||||
activity's taskAffinity to empty string fixes this.
|
|
||||||
</p>
|
|
||||||
</li>
|
|
||||||
|
|
||||||
<li>
|
|
||||||
<b>The chosen activity is not dedicated, but always comes to
|
|
||||||
the foreground in its initial state</b> - For example, in
|
|
||||||
response to a notification, when the Gmail application comes
|
|
||||||
to the foreground, it always presents the list of conversations.
|
|
||||||
You can ensure this happens by setting a "clear top" flag in the
|
|
||||||
intent that the notification triggers. This ensures that when the
|
|
||||||
activity is launched, it displays its initial activity, preventing
|
|
||||||
Gmail from coming to the foreground in whatever state the user last
|
|
||||||
happened to be viewing it. (To do this, you put {@link
|
|
||||||
android.content.Intent#FLAG_ACTIVITY_CLEAR_TOP
|
|
||||||
FLAG_ACTIVITY_CLEAR_TOP} in the intent you pass to startActivity()).
|
|
||||||
</li>
|
|
||||||
</ul>
|
|
||||||
|
|
||||||
<p>
|
|
||||||
There are other ways to handle notifications, such as bringing the
|
|
||||||
activity to the foreground, set to display specific data, such as
|
|
||||||
displaying the text message thread for the person who just sent a
|
|
||||||
new text message.
|
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
<p>
|
<p>
|
||||||
|
@ -16,6 +16,7 @@ user clicks it</li>
|
|||||||
<h2>In this document</h2>
|
<h2>In this document</h2>
|
||||||
<ol>
|
<ol>
|
||||||
<li><a href="#Basics">The Basics</a></li>
|
<li><a href="#Basics">The Basics</a></li>
|
||||||
|
<li><a href="#HandlingNotifications">Responding to Notifications</a></li>
|
||||||
<li><a href="#ManageYourNotifications">Managing your Notifications</a></li>
|
<li><a href="#ManageYourNotifications">Managing your Notifications</a></li>
|
||||||
<li><a href="#CreateANotification">Creating a Notification</a>
|
<li><a href="#CreateANotification">Creating a Notification</a>
|
||||||
<ol>
|
<ol>
|
||||||
@ -137,6 +138,138 @@ mNotificationManager.notify(HELLO_ID, notification);
|
|||||||
</ol>
|
</ol>
|
||||||
|
|
||||||
|
|
||||||
|
<h2 id="HandlingNotifications">Responding to Notifications</h2>
|
||||||
|
|
||||||
|
<p>A central part of the user's experience with a notification revolves around
|
||||||
|
how it interacts with the application's UI flow. You must implement
|
||||||
|
this correctly to provide a consistent user experience within your app.</p>
|
||||||
|
|
||||||
|
<p>Two typical examples of notifications are provided by Calendar, which can send out
|
||||||
|
notifications of upcoming events, and Email, which can send out notifications
|
||||||
|
when new messages arrive. These represent the two recommended patterns for handling
|
||||||
|
notifications: either launching into an activity that is separate from the
|
||||||
|
main application, or launching an entirely new instance of the application
|
||||||
|
showing the appropriate point for the notification.</p>
|
||||||
|
|
||||||
|
<p>The following scenario shows how the activity stack should work
|
||||||
|
in these two typical notification flows, first handling a Calendar notification:
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<ol>
|
||||||
|
<li>User is creating a new event in Calendar. They realize they
|
||||||
|
need to copy part of an email message into this event.
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
The user chooses Home > Email.
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
While in Email, they receive a notification from Calendar for an upcoming
|
||||||
|
meeting.
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
So they choose that notification, which takes them to a
|
||||||
|
dedicated Calendar activity that displays brief details of the
|
||||||
|
upcoming meeting.
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
The user has seen enough to know they have a meeting coming up,
|
||||||
|
so they press the BACK button. They are now returned to Email, which
|
||||||
|
is where they were when they took the notification.
|
||||||
|
</li>
|
||||||
|
</ol>
|
||||||
|
|
||||||
|
<p>Handling an Email notification:</p>
|
||||||
|
|
||||||
|
<ol>
|
||||||
|
<li>
|
||||||
|
The user is currently in Email composing a message, and needs to
|
||||||
|
check a date in their calendar.
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
The user chooses Home > Calendar.
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
While in Calendar, they receive a notification from Email about a new
|
||||||
|
message.
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
They select the notification, which brings them to Email with the message
|
||||||
|
details displayed. This has replaced what they were previously doing
|
||||||
|
(writing an e-mail), but that message is still saved in their drafts.
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
The user presses BACK once to go to the message list (the typical flow in the
|
||||||
|
Email app), and press BACK again to return to Calendar as they left it.
|
||||||
|
</li>
|
||||||
|
</ol>
|
||||||
|
|
||||||
|
<p>In an Email style of notification, the UI launched by the notification
|
||||||
|
shows the main application in a state representing that notification.
|
||||||
|
For example, when the Email application comes to the foreground from its
|
||||||
|
notification, it displays either the conversion list or a specific
|
||||||
|
conversation depending on whether there are multiple or only one new
|
||||||
|
email. To achieve this, we want to completely replace whatever current
|
||||||
|
state the application is in with a new activity stack representing the
|
||||||
|
new notification state.</p>
|
||||||
|
|
||||||
|
<p>The following code illustrates how to show this kind of notification. Of
|
||||||
|
most interest is the <code>makeMessageIntentStack()</code> method, which constructs
|
||||||
|
an array of intents representing the app's new activity stack for this state.
|
||||||
|
(If you are using fragments, you may need to initialize your fragment and
|
||||||
|
app state so that pressing BACK will switch the UI back to its parent state.)
|
||||||
|
The core of this is the {@link android.content.Intent#makeRestartActivityTask
|
||||||
|
Intent.makeRestartActivityTask()} method, which constructs the root activity
|
||||||
|
of the stack with the appropriate flags, such as
|
||||||
|
{@link android.content.Intent#FLAG_ACTIVITY_CLEAR_TASK Intent.FLAG_ACTIVITY_CLEAR_TASK}.</p>
|
||||||
|
|
||||||
|
{@sample development/samples/ApiDemos/src/com/example/android/apis/app/IncomingMessage.java
|
||||||
|
app_notification}
|
||||||
|
|
||||||
|
<p>In a Calendar style of notification, the UI launched by the notification
|
||||||
|
is a dedicated activity that is not part of the normal application flow.
|
||||||
|
For example, when the user receives a Calendar notification, choosing that
|
||||||
|
notification starts a special activity that displays a list
|
||||||
|
of upcoming calendar events — this view is available only
|
||||||
|
from the notification, not through the Calendar's normal user
|
||||||
|
interface.</p>
|
||||||
|
|
||||||
|
<p>The code for posting this type of notification is very straight-forward; it
|
||||||
|
is like the above, but the {@link android.app.PendingIntent} is for just a single
|
||||||
|
activity, our dedicated notification activity.</p>
|
||||||
|
|
||||||
|
{@sample development/samples/ApiDemos/src/com/example/android/apis/app/IncomingMessage.java
|
||||||
|
interstitial_notification}
|
||||||
|
|
||||||
|
<p>This is not enough, however. Normally Android considers all activities within
|
||||||
|
an application to be part of that application's UI flow, so simply launching the
|
||||||
|
activity like this can cause it to be mixed with your normal application back stack
|
||||||
|
in undesired ways. To make it behave correctly, in the manifest declaration
|
||||||
|
for the activity the attributes
|
||||||
|
<code>android:launchMode="singleInstance"</code> and
|
||||||
|
<code>android:excludeFromRecents="true"</code>
|
||||||
|
must be set. The full activity declaration for this sample is:</p>
|
||||||
|
|
||||||
|
{@sample development/samples/ApiDemos/AndroidManifest.xml interstitial_affinity}
|
||||||
|
|
||||||
|
<p>Because of the use of <code>singleInstance</code>, you must be careful about launching
|
||||||
|
any other activities from this one. These activities will be launched
|
||||||
|
in their own task, and care must be taken to make sure this interacts
|
||||||
|
well with the current state of your application's task. This is essentially
|
||||||
|
the same as switching to the main application as described for the Email style
|
||||||
|
notification shown before. Given the <code>makeMessageIntentStack()</code>
|
||||||
|
method previously shown, handling a click here would look something like this:</p>
|
||||||
|
|
||||||
|
{@sample development/samples/ApiDemos/src/com/example/android/apis/app/IncomingMessageInterstitial.java
|
||||||
|
app_launch}
|
||||||
|
|
||||||
|
<p>If you don't want to use the <code>singleInstance</code> launch mode for
|
||||||
|
this activity, an alternative approach is to use <code>android:taskAffinity=""</code>.
|
||||||
|
This tells Android that the activity should not be treated as part of the
|
||||||
|
main application flow, so it will not get mixed together with that. All of the
|
||||||
|
other issues discussed here do still apply, though this would allow you to start
|
||||||
|
additional activities that are part of this notification task instead of switching
|
||||||
|
to and replacing the main application task.</p>
|
||||||
|
|
||||||
<h2 id="ManageYourNotifications">Managing your Notifications</h2>
|
<h2 id="ManageYourNotifications">Managing your Notifications</h2>
|
||||||
|
|
||||||
<p>The {@link android.app.NotificationManager} is a system service that manages all
|
<p>The {@link android.app.NotificationManager} is a system service that manages all
|
||||||
|
Reference in New Issue
Block a user