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