Avviare un'attività da una notifica

Quando avvii un'attività da una notifica, devi preservare l'esperienza di navigazione prevista. Il tocco sul pulsante Indietro deve riportare l'utente indietro attraverso il normale flusso di lavoro dell'app fino alla schermata Home e aprendo le sullo schermo deve essere visualizzata l'attività come un'attività separata. Per mantenere questa navigazione inizia l'attività con un'altra.

L'approccio di base per impostare il comportamento del tocco per la notifica è descritto nella sezione Creare un modello di base di notifica. In questa pagina viene descritto come impostare un PendingIntent per il tuo l'azione di una notifica in modo da creare una nuova attività e tornare stack. Come funziona dipende dal tipo di attività che stai iniziando:

Attività regolare
Si tratta di un'attività che rientra nel normale flusso UX della tua app. Quando l'utente arriva nell'attività dalla notifica, la nuova attività deve Includere una pila dorsale completa, in modo che l'utente possa toccare il pulsante Indietro per navigare la gerarchia delle app.
Attività speciale
L'utente vede questa attività solo se viene avviata da una notifica. In un questa attività estende l'UI di notifica fornendo informazioni che è difficile da visualizzare nella notifica stessa. Questa attività non richiede back stack.

Configura un PendingIntent per l'attività regolare

Per avviare un'attività regolare dalla notifica, configura PendingIntent utilizzando TaskStackBuilder in modo da creare un nuovo back stack come segue.

Definire la gerarchia delle attività dell'app

Definisci la gerarchia naturale delle tue attività aggiungendo il parametro android:parentActivityName a ogni <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>

Creazione di un PendingIntent con uno stack esistente

Per avviare un'attività che includa uno stack di attività precedente, crea un istanza di TaskStackBuilder e richiama addNextIntentWithParentStack(), passando Intent per l'attività che desideri iniziare.

Purché tu definisca l'attività principale per ogni attività come descritto puoi chiamare getPendingIntent() per ricevere un PendingIntent che include 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 agli oggetti Intent nello stack richiamando TaskStackBuilder.editIntentAt() A volte questo è necessario per garantire che un'attività nel back stack mostra dati significativi quando l'utente vi accede.

Dopodiché puoi passare 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());

Configura un'attività speciale PendingIntent

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

  1. Nel file manifest, aggiungi i seguenti attributi alla Elemento <activity>.
    android:taskAffinity=""
    In combinazione con FLAG_ACTIVITY_NEW_TASK che usi nel codice, imposta questo attributo vuoto per assicurarti questa attività non viene inclusa nell'attività predefinita dell'app. Qualsiasi le attività esistenti con l'affinità predefinita dell'app non sono interessati.
    android:excludeFromRecents="true"
    Esclude la nuova attività dalla schermata Recenti in modo che l'utente non puoi accedervi per errore.

    Ciò è 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 Intent che avvii Activity.
    2. Imposta Activity in modo che inizi in una nuova attività vuota chiamata setFlags() con i flag FLAG_ACTIVITY_NEW_TASK e FLAG_ACTIVITY_CLEAR_TASK.
    3. Crea un PendingIntent chiamando getActivity().

    Ciò è 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 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 su come vedi Tasks e lo stack precedente.