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 ... 99 Intent resultIntent = new Intent(this, ResultActivity.class); 100 TaskStackBuilder stackBuilder = TaskStackBuilder.create(this); 101 // Adds the back stack 102 stackBuilder.addParentStack(ResultActivity.class); 103 // Adds the Intent to the top of the stack 104 stackBuilder.addNextIntent(resultIntent); 105 // Gets a PendingIntent containing the entire back stack 106 PendingIntent resultPendingIntent = 107 stackBuilder.getPendingIntent(0, PendingIntent.FLAG_UPDATE_CURRENT); 108 ... 109 NotificationCompat.Builder builder = new NotificationCompat.Builder(this); 110 builder.setContentIntent(resultPendingIntent); 111 NotificationManager mNotificationManager = 112 (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE); 113 mNotificationManager.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"><activity></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 <activity 162 android:name=".ResultActivity" 163 ... 164 android:launchMode="singleTask" 165 android:taskAffinity="" 166 android:excludeFromRecents="true"> 167 </activity> 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. 201 NotificationCompat.Builder builder = new NotificationCompat.Builder(this); 202 // Creates an Intent for the Activity 203 Intent notifyIntent = 204 new Intent(new ComponentName(this, ResultActivity.class)); 205 // Sets the Activity to start in a new, empty task 206 notifyIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | 207 Intent.FLAG_ACTIVITY_CLEAR_TASK); 208 // Creates the PendingIntent 209 PendingIntent 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 218 builder.setContentIntent(notifyIntent); 219 // Notifications are issued by sending them to the 220 // NotificationManager system service. 221 NotificationManager mNotificationManager = 222 (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE); 223 // Builds an anonymous Notification object from the builder, and 224 // passes it to the NotificationManager 225 mNotificationManager.notify(id, builder.build()); 226 </pre> 227 </li> 228 </ol> 229