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 ...
     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">&lt;activity&gt;</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 &lt;activity
    162     android:name=".ResultActivity"
    163 ...
    164     android:launchMode="singleTask"
    165     android:taskAffinity=""
    166     android:excludeFromRecents="true"&gt;
    167 &lt;/activity&gt;
    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