A partir de la versión 1.2.0, Navigation 3 admite vínculos directos a
destinos en 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
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 objeto 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") } )
Proporciona extras de DeepLinkRequest
Para almacenar información adicional relacionada con el vínculo directo, usa la
RequestExtras clase. Para que la definición y la creación de instancias de extras sean seguras para el tipo,
la biblioteca proporciona la interfaz RequestExtrasKey y el DSL
requestExtras.
Además, la biblioteca proporciona dos claves de extras y asistentes asociados:
MimeTypeExtrasKey: Se usa para almacenar unStringde tipo MIME.ActionExtrasKey(solo para Android): Se usa para almacenar unStringde acciónIntent.
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 RequestExtrasKey
interfaz 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).
Cómo crear 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 crea de la siguiente manera:
- El
urise copia del campodatadel intent. - Si no es nulo, los extras de tipo MIME y acción extras se establecen desde los campos de intent correspondientes.
- Todos los
intent.extrascon valores no nulos se guardan como unSavedStateenDeepLinkRequest.IntentExtrasKey. - Se agregan todos 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"
Cómo crear instancias de DeepLinkMatcher
Un objeto DeepLinkMatcher asigna instancias DeepLinkRequest entrantes 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 cubren 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 para iniciar tu actividad, debes definir los elementos coincidentes
<intent-filter> en el AndroidManifest.xml de tu app. Para obtener más
información, consulta Cómo agregar filtros de intents para vínculos entrantes.
Cómo hacer coincidir una solicitud entrante
Después de crear tus instancias de DeepLinkMatcher, puedes hacer coincidir
las solicitudes entrantes en tu actividad.
Para hacer coincidir una solicitud entrante, completa los siguientes pasos:
- Crea instancias de tus instancias de
DeepLinkMatcher. - Recopila todas tus instancias de
DeepLinkMatcher, ya sea de forma explícita o con vinculaciones múltiples. - Crea un
DeepLinkRequesta partir delIntententrante. - Haz coincidir 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) } } }