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

Lorsque vous démarrez une activité à partir d'une notification, vous devez préserver l'expérience de navigation attendue par l'utilisateur. Lorsque l'utilisateur appuie sur le bouton "Retour", il doit revenir à l'écran d'accueil en suivant le flux de travail normal de l'application. Lorsqu'il ouvre l'écran "Actions récentes", l'activité doit s'afficher en tant que tâche distincte. Pour préserver cette expérience de navigation, démarrez l'activité dans une nouvelle tâche.

L'approche de base pour définir le comportement au toucher de 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 pile de tâches et une pile « Retour ». La marche à suivre dépend du type d'activité que vous lancez :

  • Activité régulière : 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, permettant à l'utilisateur 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 est lancée à partir d'une notification. Dans un sens, cette activité étend l'UI de notification en fournissant des informations difficiles à afficher dans la notification elle-même. Cette activité n'a pas besoin de pile "Retour".

Configurer un PendingIntent d'activité régulière

Pour démarrer une activité régulière à 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 d'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 "Retour" d'activités, 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 pour chaque activité comme décrit précédemment, vous pouvez appeler getPendingIntent() pour recevoir un PendingIntent qui inclut l'intégralité de la pile "Retour".

// 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
    )
}

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

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

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

Configurer un PendingIntent d'activité spéciale

Étant donné qu'une activité spéciale qui démarre à partir d'une notification n'a pas besoin d'une pile de retour, vous pouvez créer l'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, définissez cet attribut sur "blank" (vide) pour vous assurer que cette activité ne soit pas incluse dans la tâche par défaut de l'application. Les tâches existantes qui ont l'affinité par défaut de l'application ne sont pas affectées.
    android:excludeFromRecents="true"
    Exclut la nouvelle tâche de l'écran "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 un Intent qui démarre le Activity.
    2. Définissez Activity pour qu'il démarre dans une nouvelle tâche vide en appelant setFlags() avec les indicateurs 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 :

    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
    )

  3. Transmettez PendingIntent à la notification comme d'habitude :

    val builder = NotificationCompat.Builder(this, CHANNEL_ID).apply {
        setContentIntent(notifyPendingIntent)
        // ...
    }
    with(NotificationManagerCompat.from(this)) {
        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 Tâches et pile "Retour".