En una aplicación de Android podemos definir patrones de URI que asignan URI a actividades utilizando filtros de intención. Para obtener más información sobre esto, debe leer esta documentación proporcionada por Google https://developer.android.com/training/app-links Una vez que hayamos definido qué URI maneja nuestra aplicación en nuestro manifiesto, podemos inspeccionar el URI de Intenciones del enlace entrante y decida cómo actuar en consecuencia. La API Deep Linking se encarga de manejar los enlaces entrantes asignando patrones de URI a los de Command. Estos comandos se pueden usar para iniciar una actividad, mostrar un fragmento, mostrar alguna otra interfaz de usuario o cualquier otra cosa que pueda hacer en el contexto de la actividad que maneja sus enlaces profundos. El enfoque está inspirado en el patrón Front Controller de Martin Fowler. Agregar dependencias Paso 1. Agregue el repositorio JitPack a su archivo de compilación allprojects { repositorios { … maven { url ‘https://jitpack.io’ } } } Paso 2. Agregue las dependencias { implementación ‘com.github.justeattakeaway :android-deep-links:1.0.0’ } Guía de uso Primero debemos designar una actividad que manejará los enlaces profundos entrantes y agregar los filtros de intención necesarios para la actividad en nuestro AndroidManifest.xml de la siguiente manera.





Con nuestro filtro de intención definido, podemos definir nuestro enrutamiento; para el enfoque más simple, usamos la función de extensión deepLinkRouter para realizar la mayor parte de la configuración por nosotros. clase EjemploDeepLinkActivity: ComponentActivity() { anular diversión onCreate(savedInstanceState: ¿Paquete?) { super.onCreate(savedInstanceState) deepLinkRouter { esquemas(«https») hosts(«simple.site.com») «/home» mapTo { HomeCommand() } «/productos/[a-zA-Z0-9]*» mapTo { ProductCommand() } }.route(intent.data ?: Uri.EMPTY) } } En el ejemplo asignamos rutas /home a un HomeCommand y también a /product/[a-zA-Z0-9]* a un ProductCommand respectivamente. La parte de la ruta es lo que sigue a la parte del host del URI, como https://simple.site.com/products/123, y en nuestro mapeo la definimos como Regex. Para ProductCommand lo asignamos a una expresión regular que coincide con un ID de producto del patrón. [a-zA-Z0-9]* Comandos Con nuestro mapeo definido y asignado a comandos, necesitamos hacer que nuestros comandos hagan algo. Normalmente, un comando simplemente iniciará una actividad, pero puede hacer más (más sobre esto más adelante). El siguiente comando es para el patrón de ruta /home. clase HomeCommand: Comando() { anular diversión ejecutar() = navegar { contexto -> contexto.startActivity(Intent(context, HomeActivity::class.java)) } } Al observar el ejemplo de HomeCommand, observe el bloque navegar { .. }. Los comandos deben terminar con un bloque de navegación {} y el bloque debe definir lo que debe suceder una vez que se complete el comando. La razón de esto es que los comandos pueden funcionar con corrutinas (más sobre esto más adelante) y, a veces, un comando puede tardar más en completarse y también pasar por cambios de configuración de Android. El bloque de navegación {} se llamará en un momento en el que sea seguro hacerlo en el ciclo de vida de la interfaz de usuario de Android y se le dará el contexto actual para que pueda realizar de forma segura cosas como la navegación por intención. Aparte de la larga explicación para el bloque de navegación, un comando es en su mayoría simple y todo lo que hace es redirigir a una actividad, en este caso HomeActivity. El siguiente ejemplo es el ProductCommand que está asignado al patrón /products/[a-zA-Z0-9]* clase ProductCommand: Command() { valor privado productId por pathSegment(1) anular diversión ejecutar() = navegar { contexto -> contexto.startActivity( Intent(context, ProductActivity::class.java) .putExtra(«productId», productId ) ) } } Este comando extrae un segmento de ruta de la posición 1 en el URI, que es la parte que coincidió [a-zA-Z0-9]*dandonos el ID del producto. Logramos esto utilizando el conveniente delegado de propiedad pathSegment(index). Al igual que con pathSegment(index), también podemos usar queryParam(name) para obtener los parámetros de consulta del URI; si eso no es suficiente, puede acceder a un uri de propiedad que le proporcionará android.net.Uri. ProductCommand concluye navegando { } construyendo un Intent para ProductActivity pasando el ID del producto extraído del Uri como un intent adicional. Probando sus enlaces profundos Para probar los enlaces, puede usar un comando de shell ADB para iniciar su aplicación y darle un enlace; el siguiente ejemplo muestra cómo iniciar con un enlace que se asigna a HomeCommand. adb shell am start -W -a android.intent.action.VIEW -d «https://simple.site.com/home» com.jet.android.links En el comando especificamos qué aplicación iniciar usando el nombre del paquete com.jet.android.links. Puede leer más sobre esto en los documentos oficiales para desarrolladores de Android https://developer.android.com/training/app-links/deep-linking#testing-filters De manera similar, para asignar a ProductCommand, podemos usar el patrón URI con la identificación del producto. como sigue. adb shell am start -W -a android.intent.action.VIEW -d «https://simple.site.com/products/abcd1234» com.jet.android.links Requisitos del comando Interceptar un enlace profundo y entregarlo en un El comando es útil, podemos inspeccionar el enlace profundo y enrutarlo a la aplicación a una actividad u otra. A veces, sin embargo, es posible que necesitemos más información del usuario que realiza un vínculo profundo a la aplicación o podemos exigirle que cumpla con un estado particular, como estar autenticado o estar ubicado geográficamente. Para manejar estas situaciones podemos usar Requisitos de comando, una manera elegante de suspender un comando hasta que se cumplan los requisitos. El siguiente ejemplo muestra cómo lograr esto utilizando las funciones require() y satisfacción(Any) de la API de enlace. clase OrderDetailsCommand: Command() { valor privado orderId por pathSegment(1) var privado loginResult: LoginResult? = nulo anular diversión ejecutar() { lanzar { loginResult = require() } navegar { contexto -> contexto.startActivity( Intent(context, OrderDetailsActivity::class.java) .putExtra(«orderId», orderId) .putExtra(«loginName «, loginResult!!.name) ) } } } En el comando anterior, cuando lleguemos a la línea loginResult = require() nuestro comando se suspenderá y esperará el valor de require(). Para que el comando continúe, debemos indicarle al enrutador/controlador que satisfaga (cualquiera) el requisito. El siguiente ejemplo muestra una configuración de enrutador de enlace profundo que asigna un enlace profundo entrante con el patrón de ruta /orders/[a-zA-Z0-9]* al comando OrderDertails. Esto coincidirá con un enlace profundo como https://requirements.site.com/orders/abcd1234 clase EjemploDeepLinkActivity: ComponentActivity() { enrutador de valor privado por lazy { deepLinkRouter { esquemas(«https») hosts(«requirements.site. com») «/home» mapTo { HomeCommand() } «/pedidos/[a-zA-Z0-9]*» mapTo { OrderDetailsCommand() } } } val privado loginForResult = RegisterForActivityResult(StartActivityForResult()) { val loginName = it.data!!.getStringExtra(«loginName»)!! router.satisfy(LoginResult(nombre = loginName)) } anular diversión onCreate(savedInstanceState: ¿Paquete?) { super.onCreate(savedInstanceState) router.onRequirement(this) { if (it == LoginResult::class.java) { startLoginActivity() } } router.route(intent.data?: Uri.EMPTY) } private fun startLoginActivity() { loginForResult.launch(Intent(this, LoginActivity::class.java)) } } Usamos la API de resultados de actividad para iniciar una nueva actividad LoginActivity, el usuario ingresa su nombre y regresa con un botón Iniciar sesión. Cuando el usuario regresa a EjemploDeepLinkActivity, extraemos el argumento loginName del resultado Intent (el nombre que ingresaron en el campo de nombre en la pantalla de inicio de sesión) y luego llamamos a router.satisfy(LoginResult(name = loginName)) pasando en el nombre de inicio de sesión. Para iniciar LoginActivity necesitamos decirle al enrutador qué hacer cuando un comando encuentra un requisito router.onRequirement(this) { if (it == LoginResult::class.java) { startLoginActivity() } } Logramos esto llamando a onRequirement y si hemos probado el requisito de LoginResult y si es verdadero, iniciamos la actividad de inicio de sesión usando startLoginActivity() que simplemente inicia LoginActivity. Finalización del comando Cuando se completa un comando, el comportamiento predeterminado al usar la función de extensión deepLinkRouter para configurar un enrutador llamará a la función de navegación (Contexto) del comando y luego llamará a terminar() en la actividad. Si desea hacer algo diferente, puede proporcionar su propia devolución de llamada de finalización de comando. router.onCommandComplete(this) { cuando (it) { es DeepLinkRouter.Result.Complete -> { // TODO hacer algo antes de navegarlo.navigate(this) // TODO hacer algo después de navegar finalizar() } es DeepLinkRouter.Result. Cancelado -> { // TODO maneja la cancelación del comando } } } Mirando el ejemplo, llamamos a onCommpandComplete(LifecycleOwner, (DeepLinkRouter.Result) -> Unit) con una devolución de llamada que puede manejar el resultado y luego debe llamarlo.navigate(this) para ejecutar los comandos de la función de navegación manualmente. Luego puedes finalizar() la actividad (el patrón habitual) o hacer otra cosa. Además de manejar la finalización del comando, también podemos definir qué sucede cuando se cancela el comando; esto ocurrirá si se cancela la rutina del comando Job. Referencias LICENCIA Copyright 2022 Just Eat Takeaway Licenciado bajo la Licencia Apache, Versión 2.0 (la «Licencia»); no puede utilizar este archivo excepto de conformidad con la Licencia. Puede obtener una copia de la Licencia en http://www.apache.org/licenses/LICENSE-2.0 A menos que lo exija la ley aplicable o se acuerde por escrito, el software distribuido bajo la Licencia se distribuye «TAL CUAL», SIN GARANTÍAS NI CONDICIONES DE NINGÚN TIPO, ya sean expresas o implícitas. Consulte la Licencia para conocer el idioma específico que rige los permisos y limitaciones de la Licencia.

Source link