• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1page.title=Preserving Navigation when Starting an Activity
2parent.title=Notifying the User
3parent.link=index.html
4
5trainingnavtop=true
6next.title=Updating Notifications
7next.link=managing.html
8
9@jd:body
10
11<div id="tb-wrapper">
12<div id="tb">
13
14<!-- table of contents -->
15<h2>This lesson teaches you to</h2>
16<ol>
17  <li><a href="#DirectEntry">Set up a regular activity PendingIntent</a></li>
18  <li><a href="#ExtendedNotification">Set up a special activity PendingIntent</a></li>
19</ol>
20
21<!-- other docs (NOT javadocs) -->
22<h2>You should also read</h2>
23
24<ul>
25    <li>
26        <a href="{@docRoot}guide/topics/ui/notifiers/notifications.html">Notifications</a> API Guide
27    </li>
28    <li>
29        <a href="{@docRoot}guide/components/intents-filters.html">
30        Intents and Intent Filters
31        </a>
32    </li>
33    <li>
34        <a href="{@docRoot}design/patterns/notifications.html">Notifications</a> Design Guide
35    </li>
36</ul>
37
38
39</div>
40</div>
41<p>
42    Part of designing a notification is preserving the user's expected navigation experience.
43    For a detailed discussion of this topic, see the
44    <a href="{@docRoot}guide/topics/ui/notifiers/notifications.html#NotificationResponse">Notifications</a>
45    API guide.
46    There are two general situations:
47</p>
48<dl>
49    <dt>
50        Regular activity
51    </dt>
52    <dd>
53        You're starting an {@link android.app.Activity} that's part of the application's normal
54        workflow.
55    </dd>
56    <dt>
57        Special activity
58    </dt>
59    <dd>
60        The user only sees this {@link android.app.Activity} if it's started from a notification.
61        In a sense, the {@link android.app.Activity} extends the notification by providing
62        information that would be hard to display in the notification itself.
63    </dd>
64</dl>
65<!-- ------------------------------------------------------------------------------------------ -->
66<h2 id="DirectEntry">Set Up a Regular Activity PendingIntent</h2>
67<p>
68    To set up a {@link android.app.PendingIntent} that starts a direct entry
69    {@link android.app.Activity}, follow these steps:
70</p>
71<ol>
72    <li>
73        Define your application's {@link android.app.Activity} hierarchy in the manifest. The final XML should look like this:
74        </p>
75<pre>
76&lt;activity
77    android:name=".MainActivity"
78    android:label="&#64;string/app_name" &gt;
79    &lt;intent-filter&gt;
80        &lt;action android:name="android.intent.action.MAIN" /&gt;
81        &lt;category android:name="android.intent.category.LAUNCHER" /&gt;
82    &lt;/intent-filter&gt;
83&lt;/activity&gt;
84&lt;activity
85    android:name=".ResultActivity"
86    android:parentActivityName=".MainActivity"&gt;
87    &lt;meta-data
88        android:name="android.support.PARENT_ACTIVITY"
89        android:value=".MainActivity"/&gt;
90&lt;/activity&gt;
91</pre>
92    </li>
93    <li>
94        Create a back stack based on the {@link android.content.Intent} that starts the
95        {@link android.app.Activity}. For example:
96</p>
97<pre>
98...
99Intent resultIntent = new Intent(this, ResultActivity.class);
100TaskStackBuilder stackBuilder = TaskStackBuilder.create(this);
101// Adds the back stack
102stackBuilder.addParentStack(ResultActivity.class);
103// Adds the Intent to the top of the stack
104stackBuilder.addNextIntent(resultIntent);
105// Gets a PendingIntent containing the entire back stack
106PendingIntent resultPendingIntent =
107        stackBuilder.getPendingIntent(0, PendingIntent.FLAG_UPDATE_CURRENT);
108...
109NotificationCompat.Builder builder = new NotificationCompat.Builder(this);
110builder.setContentIntent(resultPendingIntent);
111NotificationManager mNotificationManager =
112    (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
113mNotificationManager.notify(id, builder.build());
114</pre>
115<!-- ------------------------------------------------------------------------------------------ -->
116<h2 id="ExtendedNotification">Set Up a Special Activity PendingIntent</h2>
117
118<p>
119    A special {@link android.app.Activity} doesn't need a back stack, so you don't have to
120    define its {@link android.app.Activity} hierarchy in the manifest, and you don't have
121    to call
122    {@link android.support.v4.app.TaskStackBuilder#addParentStack  addParentStack()} to build a
123    back stack. Instead, use the manifest to set up the {@link android.app.Activity} task options,
124    and create the {@link android.app.PendingIntent} by calling
125    {@link android.app.PendingIntent#getActivity getActivity()}:
126</p>
127<ol>
128    <li>
129        In your manifest, add the following attributes to the
130<code><a href="{@docRoot}guide/topics/manifest/activity-element.html">&lt;activity&gt;</a></code>
131        element for the {@link android.app.Activity}:
132        <dl>
133            <dt>
134<code><a href="{@docRoot}guide/topics/manifest/activity-element.html#nm">android:name</a>="<i>activityclass</i>"</code>
135            </dt>
136            <dd>
137                The activity's fully-qualified class name.
138            </dd>
139            <dt>
140<code><a href="{@docRoot}guide/topics/manifest/activity-element.html#aff">android:taskAffinity</a>=""</code>
141            </dt>
142            <dd>
143                Combined with the
144                {@link android.content.Intent#FLAG_ACTIVITY_NEW_TASK FLAG_ACTIVITY_NEW_TASK} flag
145                that you set in code, this ensures that this {@link android.app.Activity} doesn't
146                go into the application's default task. Any existing tasks that have the
147                application's default affinity are not affected.
148            </dd>
149            <dt>
150<code><a href="{@docRoot}guide/topics/manifest/activity-element.html#exclude">android:excludeFromRecents</a>="true"</code>
151            </dt>
152            <dd>
153                Excludes the new task from <i>Recents</i>, so that the user can't accidentally
154                navigate back to it.
155            </dd>
156        </dl>
157        <p>
158            This snippet shows the element:
159        </p>
160<pre>
161&lt;activity
162    android:name=".ResultActivity"
163...
164    android:launchMode="singleTask"
165    android:taskAffinity=""
166    android:excludeFromRecents="true"&gt;
167&lt;/activity&gt;
168...
169</pre>
170    </li>
171    <li>
172        Build and issue the notification:
173        <ol style="list-style-type: lower-alpha;">
174            <li>
175                Create an {@link android.content.Intent} that starts the
176                {@link android.app.Activity}.
177            </li>
178            <li>
179                Set the {@link android.app.Activity} to start in a new, empty task by calling
180                {@link android.content.Intent#setFlags setFlags()} with the flags
181                {@link android.content.Intent#FLAG_ACTIVITY_NEW_TASK FLAG_ACTIVITY_NEW_TASK}
182                and
183                {@link android.content.Intent#FLAG_ACTIVITY_CLEAR_TASK FLAG_ACTIVITY_CLEAR_TASK}.
184            </li>
185            <li>
186                Set any other options you need for the {@link android.content.Intent}.
187            </li>
188            <li>
189                Create a {@link android.app.PendingIntent} from the {@link android.content.Intent}
190                by calling {@link android.app.PendingIntent#getActivity getActivity()}.
191                You can then use this {@link android.app.PendingIntent} as the argument to
192                {@link android.support.v4.app.NotificationCompat.Builder#setContentIntent
193                setContentIntent()}.
194            </li>
195        </ol>
196    <p>
197        The following code snippet demonstrates the process:
198    </p>
199<pre>
200// Instantiate a Builder object.
201NotificationCompat.Builder builder = new NotificationCompat.Builder(this);
202// Creates an Intent for the Activity
203Intent notifyIntent =
204        new Intent(new ComponentName(this, ResultActivity.class));
205// Sets the Activity to start in a new, empty task
206notifyIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK |
207        Intent.FLAG_ACTIVITY_CLEAR_TASK);
208// Creates the PendingIntent
209PendingIntent notifyIntent =
210        PendingIntent.getActivity(
211        this,
212        0,
213        notifyIntent,
214        PendingIntent.FLAG_UPDATE_CURRENT
215);
216
217// Puts the PendingIntent into the notification builder
218builder.setContentIntent(notifyIntent);
219// Notifications are issued by sending them to the
220// NotificationManager system service.
221NotificationManager mNotificationManager =
222    (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
223// Builds an anonymous Notification object from the builder, and
224// passes it to the NotificationManager
225mNotificationManager.notify(id, builder.build());
226</pre>
227    </li>
228</ol>
229