&& repo sync -j8 | 0aae000 | 2012-10-04 16:34:23 -0700 | [diff] [blame] | 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> |