Avviare un'attività da una notifica

Quando avvii un'attività da una notifica, devi preservare l'esperienza di navigazione prevista dall'utente. Se tocchi il pulsante Indietro, l'utente deve tornare alla schermata Home tramite il normale flusso di lavoro dell'app e l'apertura della schermata Recenti deve mostrare l'attività come un'attività separata. Per preservare questa esperienza di navigazione, avvia l'attività in un nuovo task.

L'approccio di base per impostare il comportamento di tocco per la notifica è descritto in Creare una notifica di base. Questa pagina descrive come configurare un PendingIntent per l'azione della notifica in modo che crei un nuovo task e back stack. La procedura dipende dal tipo di attività che stai avviando:

  • Attività regolare: si tratta di un'attività che fa parte del flusso UX normale dell'app. Quando l'utente arriva all'attività dalla notifica, il nuovo task deve includere un back stack completo, che consente all'utente di toccare il pulsante Indietro per spostarsi verso l'alto nella gerarchia dell'app.
  • Attività speciale: l'utente vede questa attività solo se è stata avviata da una notifica. In un certo senso, questa attività estende l'interfaccia utente delle notifiche fornendo informazioni difficili da visualizzare nella notifica stessa. Questa attività non richiede un back stack.

Configurare un PendingIntent di attività regolare

Per avviare un'attività normale dalla notifica, configura PendingIntent utilizzando TaskStackBuilder in modo che crei una nuova back stack nel seguente modo.

Definisci la gerarchia delle attività della tua app

Definisci la gerarchia naturale per le tue attività aggiungendo l'attributo android:parentActivityName a ogni elemento <activity> nel file manifest dell'app. Vedi l'esempio di seguito:

<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>

Crea un PendingIntent con un back stack

Per avviare un'attività che include uno stack precedente di attività, crea un'istanza di TaskStackBuilder e chiama addNextIntentWithParentStack(), passando Intent per l'attività che vuoi avviare.

Se definisci l'attività principale per ogni attività come descritto in precedenza, puoi chiamare getPendingIntent() per ricevere un PendingIntent che include l'intero back stack.

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

Se necessario, puoi aggiungere argomenti agli oggetti Intent nello stack chiamando TaskStackBuilder.editIntentAt(). A volte è necessario per garantire che un'attività nel back stack mostri dati significativi quando l'utente la raggiunge.

A questo punto, puoi passare PendingIntent alla notifica come di consueto:

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

Configurare un PendingIntent di attività speciale

Poiché un'attività speciale che inizia da una notifica non richiede uno stack indietro, puoi creare l'intent PendingIntent chiamando getActivity(). Tuttavia, definisci le opzioni dell'attività appropriate nel manifest.

  1. Nel manifest, aggiungi i seguenti attributi all'elemento <activity>.

    android:taskAffinity=""
    Se combinato con il flag FLAG_ACTIVITY_NEW_TASK che utilizzi nel codice, imposta questo attributo su vuoto per assicurarti che questa attività non venga inserita nell'attività predefinita dell'app. Le attività esistenti che hanno l'affinità predefinita dell'app non sono interessate.
    android:excludeFromRecents="true"
    Esclude la nuova attività dalla schermata Recenti in modo che l'utente non possa tornare accidentalmente alla schermata.

    Ciò è mostrato nel seguente esempio:

    <activity
    android:name=".ResultActivity"
    android:launchMode="singleTask"
    android:taskAffinity=""
    android:excludeFromRecents="true">
    </activity>

  2. Crea ed emetti la notifica:

    1. Crea un Intent che avvii l'Activity.
    2. Imposta Activity per iniziare una nuova attività vuota chiamando setFlags() con i flag FLAG_ACTIVITY_NEW_TASK e FLAG_ACTIVITY_CLEAR_TASK.
    3. Crea un PendingIntent chiamando il numero getActivity().

    Ciò è mostrato nel seguente esempio:

    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. Passa PendingIntent alla notifica come di consueto:

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

Per saperne di più sulle varie opzioni delle attività e su come funziona il back stack, consulta Attività e back stack.