A partir de la versión 1.2.0, Navigation 3 admite la vinculación directa a destinos de tu app con las clases DeepLinkRequest y DeepLinkMatcher.
Para admitir vínculos directos en tu app, completa los siguientes pasos:
- Define filtros de intents en tu
AndroidManifest.xmlpara especificar qué URIs puede controlar tu app. - Crea instancias de
DeepLinkMatcherpara asignar solicitudes entrantes a tus claves de navegación. - Haz coincidir las solicitudes entrantes en el método
onCreateoonNewIntentde tu actividad y actualiza la pila de actividades según corresponda.
Cómo crear un DeepLinkRequest
Un DeepLinkRequest representa un vínculo directo entrante. Contiene un DeepLinkUri y un RequestExtras opcional con información adicional, como la acción de intent o el tipo de MIME.
// Create a request with a String URI val request = DeepLinkRequest(uri = "https://www.example.com/home") // Create a request from a DeepLinkUri val deepLinkUri = DeepLinkUri("https://www.example.com/home") val requestFromUri = DeepLinkRequest(uri = deepLinkUri) // Create a request with a URI and action val requestWithAction = DeepLinkRequest( uri = "https://www.example.com/home", extras = DeepLinkRequest.actionExtra("android.intent.action.VIEW") ) // Create a request with URI, action and mimeType val requestWithMimeType = DeepLinkRequest( uri = "https://www.example.com/image", extras = requestExtras { put(DeepLinkRequest.ActionExtrasKey, "android.intent.action.VIEW") put(DeepLinkRequest.Companion.MimeTypeExtrasKey, "image/png") } )
Proporcionar extras de DeepLinkRequest
Para almacenar información adicional relacionada con el vínculo directo, usa la clase RequestExtras. Para que la definición y la creación de instancias de extras sean seguras para los tipos,
la biblioteca proporciona la interfaz RequestExtrasKey y
el DSL requestExtras.
Además, la biblioteca proporciona dos claves adicionales y asistentes asociados:
MimeTypeExtrasKey: Se usa para almacenar un tipo de MIMEString.ActionExtrasKey(solo para Android): Se usa para almacenar la acciónStringde unIntent.
val extras: RequestExtras = requestExtras { put(DeepLinkRequest.Companion.MimeTypeExtrasKey, "application/json") put(DeepLinkRequest.ActionExtrasKey, Intent.ACTION_VIEW) } // Access typed values using the get operator val mimeType: String? = extras[DeepLinkRequest.Companion.MimeTypeExtrasKey] val action: String? = extras[DeepLinkRequest.ActionExtrasKey] // Create extras using helper functions and combine them val mimeTypeExtras: RequestExtras = DeepLinkRequest.mimeTypeExtra("application/json") val combinedExtras: RequestExtras = extras + DeepLinkRequest.actionExtra(Intent.ACTION_VIEW)
Para definir tus propios extras personalizados, implementa la interfaz RequestExtrasKey con un genérico con tipo:
// Define a custom typed key: object CampaignIdExtrasKey : RequestExtrasKey<String> val customExtras: RequestExtras = requestExtras { put(CampaignIdExtrasKey, "123") } val campaignId: String? = customExtras[CampaignIdExtrasKey]
También puedes usar emptyRequestExtras() para construir una instancia vacía o combinar extras con los operadores + (plus) y - (minus).
Crea un DeepLinkRequest a partir de un Intent
En Android, puedes crear un DeepLinkRequest directamente desde un Intent. Cuando se construye de esta manera, el DeepLinkRequest se compila de la siguiente manera:
- El
urise copia del campodatadel intent. - Si no es nulo, el tipo de MIME y los extras de la acción se establecen a partir de los campos de intent correspondientes.
- Todos los
intent.extrascon valores no nulos se guardan como unSavedStateenDeepLinkRequest.IntentExtrasKey. - Se agregan los extras adicionales que se proporcionan con el parámetro
extras.
object CampaignIdExtrasKey : RequestExtrasKey<String> val intent = Intent(Intent.ACTION_VIEW).apply { data = Uri.parse("https://www.example.com/item/42") type = "application/json" putExtra("user_id", "123") } val request = DeepLinkRequest( intent = intent, extras = requestExtras { put(CampaignIdExtrasKey, "spring_promo") } ) // The resulting DeepLinkRequest contains: val uri = request.uri // "https://www.example.com/item/42" val action = request.extras[DeepLinkRequest.ActionExtrasKey] // "android.intent.action.VIEW" val mimeType = request.extras[DeepLinkRequest.Companion.MimeTypeExtrasKey] // "application/json" val intentExtras: SavedState? = request.extras[DeepLinkRequest.IntentExtrasKey] val userId: String? = intentExtras?.read { getStringOrNull("user_id") } // "123" val campaignId: String? = request.extras[CampaignIdExtrasKey] // "spring_promo"
Crea instancias de DeepLinkMatcher
Un DeepLinkMatcher asigna instancias entrantes de DeepLinkRequest a claves de navegación que se pueden agregar a la pila de actividades de tu app. Navigation 3 proporciona tres comparadores integrados: UriDeepLinkMatcher para la coincidencia de URI basada en patrones, StaticKeyDeepLinkMatcher para vínculos básicos y BackStackMatcher para compilar pilas de actividades sintéticas. La biblioteca también admite comparadores personalizados para casos de uso que no están cubiertos por los comparadores integrados.
Para obtener más información, consulta Cómo crear DeepLinkMatchers.
Cómo agregar filtros de intents
Para habilitar un vínculo directo que inicie tu actividad, debes definir los elementos <intent-filter> correspondientes en el AndroidManifest.xml de tu app. Para obtener más información, consulta Cómo agregar filtros de intents para vínculos entrantes.
Coincidir con una solicitud entrante
Después de crear tus instancias de DeepLinkMatcher, puedes hacer coincidir
las solicitudes entrantes en tu actividad.
Para que coincida con una solicitud entrante, completa los siguientes pasos:
- Crea una instancia de tus instancias de
DeepLinkMatcher. - Intercala todas tus instancias de
DeepLinkMatcher, ya sea de forma explícita o con vinculaciones múltiples. - Crea un
DeepLinkRequesta partir delIntententrante. - Compara la solicitud con todos los comparadores y encuentra la mejor coincidencia.
- Crea la pila de actividades a partir del resultado de la coincidencia.
// 1. Instantiate your DeepLinkMatcher instances. val homeMatcher = StaticKeyDeepLinkMatcher(HomeKey, listOf(DeepLinkMatcher.actionFilter(Intent.ACTION_VIEW))) val userProfileMatcher = UriDeepLinkMatcher( DeepLinkUri("www.example.com/users/{id}"), serializer<UserProfileKey>() ).withBackStack { matchResult -> listOf(HomeKey, matchResult.key) } val telMatcher = TelDeepLinkMatcher() // 2. Collate all of your DeepLinkMatcher instances. // Note: Collating matchers with different generic types requires wildcards, // erasing the specific generic types. val deepLinkMatchers: List<DeepLinkMatcher<*, *>> = listOf( homeMatcher, userProfileMatcher, telMatcher ) class MainActivity : ComponentActivity() { override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) // ... // 3. Create a DeepLinkRequest from the incoming Intent val request = DeepLinkRequest(intent = intent) // 4. Match the request against all matchers and find the best match. // Because DeepLinkMatcher.MatchResult implements Comparable, you can // use maxOrNull() to find the best match. val matchResult = deepLinkMatchers .mapNotNull { it.match(request) } // List<DeepLinkMatcher.MatchResult<*>> .maxOrNull() // DeepLinkMatcher.MatchResult<*>? // 5. Create the back stack from the match result (or fall back to a default). val backStack: List<NavKey> = when (matchResult) { // If no match is found, use the default back stack (e.g., HomeKey) null -> listOf(HomeKey) // If a BackStackMatchResult is found, use the back stack from the result is BackStackMatchResult<*, *> -> { // Because star-projected matchers erase the key type, cast the back stack to List<NavKey>. @Suppress("UNCHECKED_CAST") matchResult.backStack as List<NavKey> } // Otherwise, use the key from the match result to make a single-item back stack else -> listOf(matchResult.key as NavKey) } } }