Démarrer une activité à partir d'une notification

Lorsque vous démarrez une activité à partir d'une notification, vous devez conserver l'expérience de navigation attendue de l'utilisateur. Lorsque l'utilisateur appuie sur le bouton "Retour", il doit revenir dans le flux de travail normal de l'application jusqu'à l'écran d'accueil. L'ouverture de l'écran "Recents" (Éléments récents) doit afficher l'activité en tant que tâche distincte. Pour conserver cette expérience de navigation, démarrez l'activité dans une nouvelle tâche.

L'approche de base pour définir le comportement d'appui pour votre notification est décrite dans Créer une notification de base. Cette page explique comment configurer un PendingIntent pour l'action de votre notification afin de créer une nouvelle pile de tâche et de retour. La procédure à suivre dépend du type d'activité que vous lancez:

Activité régulière
Il s'agit d'une activité qui fait partie du flux d'expérience utilisateur normal de votre application. Lorsque l'utilisateur arrive dans l'activité à partir de la notification, la nouvelle tâche doit inclure une pile "Retour" complète, ce qui lui permet d'appuyer sur le bouton "Retour" pour remonter dans la hiérarchie de l'application.
Activité spéciale
L'utilisateur ne voit cette activité que si elle a été lancée à partir d'une notification. En clair, cette activité étend l'interface utilisateur des notifications en fournissant des informations difficiles à afficher dans la notification elle-même. Cette activité n'a pas besoin d'une pile "Retour".

Configurer un PendingIntent d'activité standard

Pour démarrer une activité standard à partir de votre notification, configurez PendingIntent à l'aide de TaskStackBuilder afin qu'il crée une pile "Retour" comme suit.

Définir la hiérarchie des activités de votre application

Définissez la hiérarchie naturelle de vos activités en ajoutant l'attribut android:parentActivityName à chaque élément <activity> dans le fichier manifeste de votre application. Consultez l'exemple suivant :

<activity
    android:name=".MainActivity"
    android:label="@string/app_name" >
    <intent-filter>
        <action android:name="android.intent.action.MAIN" />
        <category android:name="android.intent.category.LAUNCHER" />
    </intent-filter>
</activity>
<!-- MainActivity is the parent for ResultActivity. -->
<activity
    android:name=".ResultActivity"
    android:parentActivityName=".MainActivity" />
    ...
</activity>

Créer un PendingIntent avec une pile "Retour"

Pour démarrer une activité qui inclut une pile d'activités "Retour", créez une instance de TaskStackBuilder et appelez addNextIntentWithParentStack(), en lui transmettant le Intent de l'activité que vous souhaitez démarrer.

Tant que vous définissez l'activité parente de chaque activité comme décrit précédemment, vous pouvez appeler getPendingIntent() pour recevoir un PendingIntent comprenant l'intégralité de la pile "Retour".

Kotlin

// Create an Intent for the activity you want to start.
val resultIntent = Intent(this, ResultActivity::class.java)
// Create the TaskStackBuilder.
val resultPendingIntent: PendingIntent? = TaskStackBuilder.create(this).run {
    // Add the intent, which inflates the back stack.
    addNextIntentWithParentStack(resultIntent)
    // Get the PendingIntent containing the entire back stack.
    getPendingIntent(0,
            PendingIntent.FLAG_UPDATE_CURRENT or PendingIntent.FLAG_IMMUTABLE)
}

Java

// Create an Intent for the activity you want to start.
Intent resultIntent = new Intent(this, ResultActivity.class);
// Create the TaskStackBuilder and add the intent, which inflates the back
// stack.
TaskStackBuilder stackBuilder = TaskStackBuilder.create(this);
stackBuilder.addNextIntentWithParentStack(resultIntent);
// Get the PendingIntent containing the entire back stack.
PendingIntent resultPendingIntent =
        stackBuilder.getPendingIntent(0,
            PendingIntent.FLAG_UPDATE_CURRENT | PendingIntent.FLAG_IMMUTABLE);

Si nécessaire, vous pouvez ajouter des arguments aux objets Intent de la pile en appelant TaskStackBuilder.editIntentAt(). Cela est parfois nécessaire pour garantir qu'une activité dans la pile "Retour" affiche des données pertinentes lorsque l'utilisateur y accède.

Vous pouvez ensuite transmettre PendingIntent à la notification, comme d'habitude:

Kotlin

val builder = NotificationCompat.Builder(this, CHANNEL_ID).apply {
    setContentIntent(resultPendingIntent)
    ...
}
with(NotificationManagerCompat.from(this)) {
    notify(NOTIFICATION_ID, builder.build())
}

Java

NotificationCompat.Builder builder = new NotificationCompat.Builder(this, CHANNEL_ID);
builder.setContentIntent(resultPendingIntent);
...
NotificationManagerCompat notificationManager = NotificationManagerCompat.from(this);
notificationManager.notify(NOTIFICATION_ID, builder.build());

Configurer un PendingIntent d'activité spéciale

Étant donné qu'une activité spéciale qui commence à partir d'une notification n'a pas besoin d'une pile "Retour", vous pouvez créer le PendingIntent en appelant getActivity(). Toutefois, définissez les options de tâche appropriées dans le fichier manifeste.

  1. Dans votre fichier manifeste, ajoutez les attributs suivants à l'élément <activity>.
    android:taskAffinity=""
    Combiné à l'indicateur FLAG_ACTIVITY_NEW_TASK que vous utilisez dans le code, laissez cet attribut vide pour vous assurer que cette activité n'entre pas dans la tâche par défaut de l'application. Les tâches existantes ayant l'affinité par défaut de l'application ne sont pas affectées.
    android:excludeFromRecents="true"
    La nouvelle tâche est exclue de l'écran "Recents" (Éléments récents), afin que l'utilisateur ne puisse pas y revenir accidentellement.

    Ce processus est illustré dans l'exemple suivant :

    <activity
        android:name=".ResultActivity"
        android:launchMode="singleTask"
        android:taskAffinity=""
        android:excludeFromRecents="true">
    </activity>
    
  2. Créez et envoyez la notification :
    1. Créez une Intent qui lance Activity.
    2. Définissez Activity pour qu'il démarre dans une nouvelle tâche vide en appelant setFlags() avec les options FLAG_ACTIVITY_NEW_TASK et FLAG_ACTIVITY_CLEAR_TASK.
    3. Créez un PendingIntent en appelant getActivity().

    Ce processus est illustré dans l'exemple suivant :

    Kotlin

    val notifyIntent = Intent(this, ResultActivity::class.java).apply {
        flags = Intent.FLAG_ACTIVITY_NEW_TASK or Intent.FLAG_ACTIVITY_CLEAR_TASK
    }
    val notifyPendingIntent = PendingIntent.getActivity(
            this, 0, notifyIntent,
            PendingIntent.FLAG_UPDATE_CURRENT or PendingIntent.FLAG_IMMUTABLE
    )
    

    Java

    Intent notifyIntent = new Intent(this, ResultActivity.class);
    // Set the Activity to start in a new, empty task.
    notifyIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK
                        | Intent.FLAG_ACTIVITY_CLEAR_TASK);
    // Create the PendingIntent.
    PendingIntent notifyPendingIntent = PendingIntent.getActivity(
            this, 0, notifyIntent,
            PendingIntent.FLAG_UPDATE_CURRENT | PendingIntent.FLAG_IMMUTABLE
    );
    
  3. Transmettez le PendingIntent à la notification comme d'habitude:

    Kotlin

    val builder = NotificationCompat.Builder(this, CHANNEL_ID).apply {
        setContentIntent(notifyPendingIntent)
        ...
    }
    with(NotificationManagerCompat.from(this)) {
        notify(NOTIFICATION_ID, builder.build())
    }
    

    Java

    NotificationCompat.Builder builder = new NotificationCompat.Builder(this, CHANNEL_ID);
    builder.setContentIntent(notifyPendingIntent);
    ...
    NotificationManagerCompat notificationManager = NotificationManagerCompat.from(this);
    notificationManager.notify(NOTIFICATION_ID, builder.build());
    

Pour en savoir plus sur les différentes options de tâches et sur le fonctionnement de la pile "Retour", consultez la section Tâches et pile "Retour".