Avviare un'attività da una notifica

Quando avvii un'attività da una notifica, devi preservare l'esperienza di navigazione prevista dell'utente. Il tocco del pulsante Indietro deve riportare l'utente alla schermata Home attraverso il normale flusso di lavoro dell'app e l'apertura della schermata Recenti deve mostrare l'attività come attività separata. Per preservare questa esperienza di navigazione, avvia l'attività in una nuova attività.

L'approccio di base per impostare il comportamento del tocco per la notifica è descritto nella sezione Creare una notifica di base. In questa pagina viene descritto come configurare un elemento PendingIntent per l'azione di notifica in modo che crei una nuova attività e un nuovo stack. La procedura dipende dal tipo di attività che inizi:

Attività regolare
Si tratta di un'attività che fa parte del normale flusso UX della tua app. Quando l'utente arriva nell'attività dalla notifica, la nuova attività deve includere uno stack di backup completo che consenta all'utente di toccare il pulsante Indietro per navigare nella gerarchia dell'app.
Attività speciale
L'utente vede questa attività solo se viene avviata da una notifica. In modo, questa attività estende l'interfaccia utente di notifica fornendo informazioni difficili da visualizzare nella notifica stessa. Questa attività non ha bisogno di uno stack back.

Configurare un PendingIntent di attività regolare

Per avviare un'attività regolare dalla notifica, configura PendingIntent utilizzando TaskStackBuilder in modo che crei un nuovo stack di backup come indicato di seguito.

Definire la gerarchia Attività dell'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 che segue:

<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 uno stack di back

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

Purché tu definisca l'attività principale per ogni attività come descritto in precedenza, puoi chiamare getPendingIntent() per ricevere un PendingIntent che includa l'intero back stack.

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

Se necessario, puoi aggiungere argomenti a Intent oggetti nello stack chiamando TaskStackBuilder.editIntentAt(). A volte questa operazione è necessaria per garantire che un'attività nello stack di riserva mostri dati significativi quando l'utente vi accede.

Dopodiché puoi passare il PendingIntent alla notifica come di consueto:

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());

Impostazione di un'attività speciale PendingIntent

Poiché un'attività speciale che inizia da una notifica non ha bisogno di uno stack arretrato, puoi creare PendingIntent chiamando getActivity(). Tuttavia, definisci le opzioni appropriate per le attività nel file manifest.

  1. Nel file manifest, aggiungi i seguenti attributi all'elemento <activity>.
    android:taskAffinity=""
    Combinato con il flag FLAG_ACTIVITY_NEW_TASK che utilizzi nel codice, imposta questo attributo vuoto per assicurarti che questa attività non venga inclusa nell'attività predefinita dell'app. Le attività esistenti con 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 accedervi accidentalmente.

    Questo è quanto mostrato nell'esempio seguente:

    <activity
        android:name=".ResultActivity"
        android:launchMode="singleTask"
        android:taskAffinity=""
        android:excludeFromRecents="true">
    </activity>
    
  2. Crea ed emetti la notifica:
    1. Crea un elemento Intent che avvii Activity.
    2. Imposta Activity per iniziare in una nuova attività vuota chiamando setFlags() con i flag FLAG_ACTIVITY_NEW_TASK e FLAG_ACTIVITY_CLEAR_TASK.
    3. Crea un PendingIntent chiamando getActivity().

    Questo è quanto mostrato nell'esempio seguente:

    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. Passa il PendingIntent alla notifica come al solito:

    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());
    

Per ulteriori informazioni sulle varie opzioni delle attività e sul funzionamento dello stack arretrato, consulta Attività e stack di back.