1 page.title=Preserving Navigation when Starting an Activity 2 parent.title=Notifying the User 3 parent.link=index.html 4 5 trainingnavtop=true 6 next.title=Updating Notifications 7 next.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 <activity 77 android:name=".MainActivity" 78 android:label="@string/app_name" > 79 <intent-filter> 80 <action android:name="android.intent.action.MAIN" /> 81 <category android:name="android.intent.category.LAUNCHER" /> 82 </intent-filter> 83 </activity> 84 <activity 85 android:name=".ResultActivity" 86 android:parentActivityName=".MainActivity"> 87 <meta-data 88 android:name="android.support.PARENT_ACTIVITY" 89 android:value=".MainActivity"/> 90 </activity> 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 int id = 1; 99 ... 100 Intent resultIntent = new Intent(this, ResultActivity.class); 101 TaskStackBuilder stackBuilder = TaskStackBuilder.create(this); 102 // Adds the back stack 103 stackBuilder.addParentStack(ResultActivity.class); 104 // Adds the Intent to the top of the stack 105 stackBuilder.addNextIntent(resultIntent); 106 // Gets a PendingIntent containing the entire back stack 107 PendingIntent resultPendingIntent = 108 stackBuilder.getPendingIntent(0, PendingIntent.FLAG_UPDATE_CURRENT); 109 ... 110 NotificationCompat.Builder builder = new NotificationCompat.Builder(this); 111 builder.setContentIntent(resultPendingIntent); 112 NotificationManager mNotificationManager = 113 (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE); 114 mNotificationManager.notify(id, builder.build()); 115 </pre> 116 <!-- ------------------------------------------------------------------------------------------ --> 117 <h2 id="ExtendedNotification">Set Up a Special Activity PendingIntent</h2> 118 119 <p> 120 A special {@link android.app.Activity} doesn't need a back stack, so you don't have to 121 define its {@link android.app.Activity} hierarchy in the manifest, and you don't have 122 to call 123 {@link android.support.v4.app.TaskStackBuilder#addParentStack addParentStack()} to build a 124 back stack. Instead, use the manifest to set up the {@link android.app.Activity} task options, 125 and create the {@link android.app.PendingIntent} by calling 126 {@link android.app.PendingIntent#getActivity getActivity()}: 127 </p> 128 <ol> 129 <li> 130 In your manifest, add the following attributes to the 131 <code><a href="{@docRoot}guide/topics/manifest/activity-element.html"><activity></a></code> 132 element for the {@link android.app.Activity}: 133 <dl> 134 <dt> 135 <code><a href="{@docRoot}guide/topics/manifest/activity-element.html#nm">android:name</a>="<i>activityclass</i>"</code> 136 </dt> 137 <dd> 138 The activity's fully-qualified class name. 139 </dd> 140 <dt> 141 <code><a href="{@docRoot}guide/topics/manifest/activity-element.html#aff">android:taskAffinity</a>=""</code> 142 </dt> 143 <dd> 144 Combined with the 145 {@link android.content.Intent#FLAG_ACTIVITY_NEW_TASK FLAG_ACTIVITY_NEW_TASK} flag 146 that you set in code, this ensures that this {@link android.app.Activity} doesn't 147 go into the application's default task. Any existing tasks that have the 148 application's default affinity are not affected. 149 </dd> 150 <dt> 151 <code><a href="{@docRoot}guide/topics/manifest/activity-element.html#exclude">android:excludeFromRecents</a>="true"</code> 152 </dt> 153 <dd> 154 Excludes the new task from <i>Recents</i>, so that the user can't accidentally 155 navigate back to it. 156 </dd> 157 </dl> 158 <p> 159 This snippet shows the element: 160 </p> 161 <pre> 162 <activity 163 android:name=".ResultActivity" 164 ... 165 android:launchMode="singleTask" 166 android:taskAffinity="" 167 android:excludeFromRecents="true"> 168 </activity> 169 ... 170 </pre> 171 </li> 172 <li> 173 Build and issue the notification: 174 <ol style="list-style-type: lower-alpha;"> 175 <li> 176 Create an {@link android.content.Intent} that starts the 177 {@link android.app.Activity}. 178 </li> 179 <li> 180 Set the {@link android.app.Activity} to start in a new, empty task by calling 181 {@link android.content.Intent#setFlags setFlags()} with the flags 182 {@link android.content.Intent#FLAG_ACTIVITY_NEW_TASK FLAG_ACTIVITY_NEW_TASK} 183 and 184 {@link android.content.Intent#FLAG_ACTIVITY_CLEAR_TASK FLAG_ACTIVITY_CLEAR_TASK}. 185 </li> 186 <li> 187 Set any other options you need for the {@link android.content.Intent}. 188 </li> 189 <li> 190 Create a {@link android.app.PendingIntent} from the {@link android.content.Intent} 191 by calling {@link android.app.PendingIntent#getActivity getActivity()}. 192 You can then use this {@link android.app.PendingIntent} as the argument to 193 {@link android.support.v4.app.NotificationCompat.Builder#setContentIntent 194 setContentIntent()}. 195 </li> 196 </ol> 197 <p> 198 The following code snippet demonstrates the process: 199 </p> 200 <pre> 201 // Instantiate a Builder object. 202 NotificationCompat.Builder builder = new NotificationCompat.Builder(this); 203 // Creates an Intent for the Activity 204 Intent notifyIntent = 205 new Intent(new ComponentName(this, ResultActivity.class)); 206 // Sets the Activity to start in a new, empty task 207 notifyIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | 208 Intent.FLAG_ACTIVITY_CLEAR_TASK); 209 // Creates the PendingIntent 210 PendingIntent notifyIntent = 211 PendingIntent.getActivity( 212 this, 213 0, 214 notifyIntent, 215 PendingIntent.FLAG_UPDATE_CURRENT 216 ); 217 218 // Puts the PendingIntent into the notification builder 219 builder.setContentIntent(notifyIntent); 220 // Notifications are issued by sending them to the 221 // NotificationManager system service. 222 NotificationManager mNotificationManager = 223 (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE); 224 // Builds an anonymous Notification object from the builder, and 225 // passes it to the NotificationManager 226 mNotificationManager.notify(id, builder.build()); 227 </pre> 228 </li> 229 </ol> 230