Receta de pila de actividades sintética de vínculos directos
En esta receta, se muestra cómo aplicar los principios de Navigation en el contexto de los vínculos directos mediante la administración de una pila de actividades sintética y pilas de tareas.
Estructura de la receta
Esta receta simula una situación del mundo real en la que la "App A" usa vínculos directos a la "App B".
La "App A" se simula con el módulo syntheticbackstack, que
contiene la SyntheticBackStackDeepLinkActivity que te permite crear un intent de vínculo directo y
activarlo en la tarea existente o en una tarea nueva.
La "App B" se simula con el módulo syntheticbackstackapp, que contiene
la SyntheticBackStackAppActivity a la que se vincula directamente. Ese módulo te muestra cómo compilar una pila de actividades sintética y cómo administrar la pila de tareas correctamente para admitir los botones Atrás y Arriba.
Cómo usarlo
Asegúrate de que la app principal y syntheticbackstackapp estén instaladas en el emulador o el dispositivo conectado. Asegúrate de que el syntheticbackstackapp instalado admita
el "www.nav3deeplink.com" vínculo.
En la página de destino de la receta, elige los filtros y haz clic en el botón para usar el vínculo directo. Deberías ir a la actividad de syntheticbackstackapp.
Cómo funciona
La receta sigue los lineamientos de vínculos directos que se resumen aquí.
Para ver el comportamiento de Existing Task, haz lo siguiente:
- Abre el vínculo directo con la tarea actual.
- En el dispositivo, desliza el dedo hacia arriba para ver todas las apps recientes.
- Observa que la nueva actividad se abre en la app de Nav3Recipes.
- Haz clic en el botón Atrás para volver a la actividad original.
- Repite el paso 1.
- Haz clic en el botón Arriba para ir a la pantalla superior.
- En el dispositivo, desliza el dedo hacia arriba para ver todas las apps recientes.
- Observa que la nueva actividad ahora se abre en la app de Nav3SyntheticBackStack.
Para ver el comportamiento de New Task, haz lo siguiente:
- Abre el vínculo directo con la tarea nueva.
- En el dispositivo, desliza el dedo hacia arriba para ver todas las apps recientes.
- Observa que la nueva actividad se abre en la app de Nav3SyntheticBackStack.
- Haz clic en el botón Arriba o Atrás para ir a la pantalla superior.
Implementación principal
Las funciones auxiliares principales para navigateUp y la compilación de la pila de actividades sintética se pueden encontrar aquí
Lecturas adicionales
Consulta la guía de vínculos directos para obtener una guía completa sobre los principios de los vínculos directos y cómo aplicarlos en Navigation 3.
package com.example.nav3recipes.deeplink.handlerequests.syntheticbackstack import android.content.Intent import android.os.Bundle import androidx.activity.ComponentActivity import androidx.activity.compose.setContent import androidx.compose.runtime.getValue import androidx.compose.runtime.mutableStateOf import androidx.compose.runtime.remember import androidx.compose.runtime.setValue import androidx.core.net.toUri import androidx.lifecycle.compose.dropUnlessResumed import com.example.nav3recipes.common.deeplink.EntryScreen import com.example.nav3recipes.common.deeplink.LIST_FIRST_NAMES import com.example.nav3recipes.common.deeplink.LIST_LOCATIONS import com.example.nav3recipes.common.deeplink.MenuDropDown import com.example.nav3recipes.common.deeplink.PaddedButton import com.example.nav3recipes.common.deeplink.TextContent import com.example.nav3recipes.ui.setEdgeToEdgeConfig internal const val ADVANCED_PATH_BASE = "https://www.nav3deeplink.com" /** * The recipe entry point that allows users to create a deep link and make a request with it. * * **HOW THIS RECIPE WORKS** This recipe simulates a real-world scenario where "App A" deep links * into "App B". * * "App A" is simulated by this current module `syntheticbackstack`, which * contains the [SyntheticBackStackDeepLinkActivity] that allows you to create a deeplink intent and * trigger that in either the existing Task, or in a new Task. * * "App B" is simulated by the module `syntheticbackstackapp`, which contains * the SyntheticBackStackAppActivity that you deeplink into. That module shows you how to build a synthetic backStack * and how to manage the Task stack properly in order to support both Back and Up buttons. * * See the [README](README.md) file of current module for more info on advanced deep linking. */ class SyntheticBackStackDeepLinkActivity: ComponentActivity() { override fun onCreate(savedInstanceState: Bundle?) { setEdgeToEdgeConfig() super.onCreate(savedInstanceState) setContent { EntryScreen("Sandbox - Build Your Deeplink Intent") { val initFirstName = MENU_OPTIONS_FIRST_NAME.values.first().first() val initLocation = MENU_OPTIONS_LOCATION.values.last().first() val initTaskStack = MENU_OPTIONS_TASK_STACK.values.first().first() var firstName by remember { mutableStateOf(initFirstName) } var location by remember { mutableStateOf(initLocation) } var taskStack by remember { mutableStateOf(initTaskStack) } // select first name MenuDropDown( menuOptions = MENU_OPTIONS_FIRST_NAME, ) { _, selected -> firstName = selected } // select first name MenuDropDown( menuOptions = MENU_OPTIONS_LOCATION, ) { _, selected -> location = selected } // select current task stack or build new task stack MenuDropDown( menuOptions = MENU_OPTIONS_TASK_STACK, ) { _, selected -> taskStack = selected } // build final deeplink URL and Intent val finalUrl = "${ADVANCED_PATH_BASE}/user/$firstName/$location" // display Intent info val flagString = if (taskStack == TAG_NEW_TASK) { "Intent.FLAG_ACTIVITY_NEW_TASK or Intent.FLAG_ACTIVITY_CLEAR_TASK" } else "<none>" val intentString = """ | Final Intent: | data = "$finalUrl" | action = Intent.ACTION_VIEW | flags = $flagString """.trimMargin() TextContent(intentString) // deeplink to target PaddedButton("Deeplink Away!", onClick = dropUnlessResumed { val intent = Intent().apply { data = finalUrl.toUri() action = Intent.ACTION_VIEW if (taskStack == TAG_NEW_TASK) { flags = Intent.FLAG_ACTIVITY_NEW_TASK or Intent.FLAG_ACTIVITY_CLEAR_TASK } } startActivity(intent) }) } } } } private const val TAG_FIRST_NAME = "firstName" private const val TAG_LOCATION = "location" private const val TAG_TASK_STACK = "Task stack" private const val TAG_CURRENT_TASK = "Use Current Task Stack" private const val TAG_NEW_TASK = "Start New Task Stack" private val MENU_OPTIONS_FIRST_NAME = mapOf( TAG_FIRST_NAME to LIST_FIRST_NAMES ) private val MENU_OPTIONS_LOCATION = mapOf( TAG_LOCATION to LIST_LOCATIONS ) private val MENU_OPTIONS_TASK_STACK = mapOf( TAG_TASK_STACK to listOf(TAG_CURRENT_TASK, TAG_NEW_TASK), )