Cómo iniciar una actividad desde una notificación

Cuando inicias una actividad desde una notificación, debes conservar el la experiencia de navegación esperada. Cuando el usuario presiona el botón Atrás, debe regresar el flujo de trabajo normal de la app a la pantalla principal y, luego, abrir la app La pantalla debe mostrar la actividad como una tarea independiente. Para preservar esta navegación experiencia, inicia la actividad en una tarea nueva.

El enfoque básico para configurar el comportamiento de toque de tu notificación se describe en Crea una notificación. En esta página, se describe cómo configurar un PendingIntent para tu la acción de la notificación para crear una tarea nueva la pila. Cómo lo haces según el tipo de actividad que quieras iniciar:

Actividad normal
Corresponde a una actividad que forma parte del flujo normal de la experiencia del usuario de tu app. Cuándo cuando el usuario llega a la actividad desde la notificación, la nueva tarea debe incluir una pila de actividades completa que permita al usuario presionar el botón Atrás para navegar en la jerarquía de las apps.
Actividad especial
El usuario solamente ve esta actividad si se inicia desde una notificación. En una sentido, esta actividad extiende la IU de notificación al proporcionar información que es difícil de mostrar en la notificación. Esta actividad no necesita un en la pila de actividades.

Cómo configurar un PendingIntent de actividad normal

Para iniciar una actividad habitual desde tu notificación, configura el PendingIntent usando TaskStackBuilder de modo que se cree una nueva pila de actividades de la siguiente manera.

Cómo definir la jerarquía de actividades de tu app

Define la jerarquía natural de tus actividades agregando el elemento android:parentActivityName atributo a cada <activity> en el archivo de manifiesto de tu app. Observa el siguiente ejemplo:

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

Cómo compilar un PendingIntent con una pila de actividades

Para iniciar una actividad que incluya una pila de actividades, crea una instancia de TaskStackBuilder y llama addNextIntentWithParentStack(), y pásale el Intent para el actividad que quieres iniciar.

Siempre y cuando definas la actividad principal para cada actividad como se describe antes, puedes llamar getPendingIntent() para recibir un PendingIntent que incluya toda la pila de actividades.

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 es necesario, puedes agregar argumentos a los objetos Intent de la pila llamando a TaskStackBuilder.editIntentAt() Esto es necesario para garantizar que una actividad de la pila de actividades muestra datos significativos cuando el usuario navega hacia ellos.

Luego, puedes pasar el PendingIntent a la notificación como lo haces normalmente:

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

Cómo configurar un PendingIntent de actividad especial

Porque una actividad especial que se inicia a partir de una notificación no necesita un retroceso puedes crear el PendingIntent llamando getActivity() Sin embargo, define las opciones de la tarea apropiadas en el manifiesto.

  1. En tu manifiesto, agrega los siguientes atributos al <activity>.
    android:taskAffinity=""
    En combinación con el FLAG_ACTIVITY_NEW_TASK marca que usas en el código, deja este atributo en blanco para garantizar esta actividad no forma parte de la tarea predeterminada de la app. Cualquiera no se incluyen las tareas existentes con la afinidad predeterminada afectado.
    android:excludeFromRecents="true"
    Excluye la nueva tarea de la pantalla Recientes para que el usuario no puedas volver accidentalmente a ella.

    Esto se muestra en el siguiente ejemplo:

    <activity
        android:name=".ResultActivity"
        android:launchMode="singleTask"
        android:taskAffinity=""
        android:excludeFromRecents="true">
    </activity>
    
  2. Compila y emite la notificación:
    1. Crea un Intent que inicie la Activity
    2. Configura el Activity para que comience en una tarea nueva vacía. llamando setFlags() con las marcas FLAG_ACTIVITY_NEW_TASK y FLAG_ACTIVITY_CLEAR_TASK
    3. Llama para crear un PendingIntent getActivity()

    Esto se muestra en el siguiente ejemplo:

    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. Pasa el PendingIntent a la notificación como de costumbre:

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

Para obtener más información sobre las diferentes opciones de tareas y cómo la pila de actividades , consulta Tareas y la pila de actividades.