Home | History | Annotate | Download | only in notify-user
      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 &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 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">&lt;activity&gt;</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 &lt;activity
    163     android:name=".ResultActivity"
    164 ...
    165     android:launchMode="singleTask"
    166     android:taskAffinity=""
    167     android:excludeFromRecents="true"&gt;
    168 &lt;/activity&gt;
    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