A partir da versão 1.2.0, o Navigation 3 oferece suporte a links diretos para
destinos no seu app usando as classes DeepLinkRequest e
DeepLinkMatcher.
Para oferecer suporte a links diretos no seu app, siga estas etapas:
- Defina filtros de intent no
AndroidManifest.xmlpara especificar quais URIs seu app pode processar. - Crie instâncias
DeepLinkMatcherpara mapear as solicitações recebidas para as suas chaves de navegação. - Corresponda às solicitações recebidas no método
onCreateouonNewIntentda sua Activity e atualize o backstack de acordo.
Criar um DeepLinkRequest
Um DeepLinkRequest representa um link direto recebido. Ele contém um
DeepLinkUri e RequestExtras opcionais com informações adicionais, como a ação da intent ou o Tipo 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") } )
Fornecer extras de DeepLinkRequest
Para armazenar informações adicionais relacionadas ao link direto, use a
RequestExtras classe. Para tornar a definição e a instanciação de extras com segurança de tipo,
a biblioteca fornece a interface RequestExtrasKey e a DSL
requestExtras.
Além disso, a biblioteca fornece duas chaves extras e auxiliares associados:
MimeTypeExtrasKey: usado para armazenar um tipo MIMEString.ActionExtrasKey(somente Android): usado para armazenar uma açãoStringdeIntent.
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 seus próprios extras personalizados, implemente a RequestExtrasKey
interface com um genérico tipado:
// Define a custom typed key: object CampaignIdExtrasKey : RequestExtrasKey<String> val customExtras: RequestExtras = requestExtras { put(CampaignIdExtrasKey, "123") } val campaignId: String? = customExtras[CampaignIdExtrasKey]
Também é possível usar emptyRequestExtras() para construir uma instância vazia ou
combinar extras usando os + (plus) e - (minus) operadores.
Criar um DeepLinkRequest de uma Intent
No Android, é possível criar um DeepLinkRequest diretamente de uma Intent. Quando construído dessa forma, o DeepLinkRequest é criado da seguinte maneira:
- O
urié copiado do campodatada intent. - Se não for nulo, o tipo MIME e os extras de ação serão definidos nos campos de intent correspondentes.
- Todos os
intent.extrascom valores não nulos são salvos como umSavedStateemDeepLinkRequest.IntentExtrasKey. - Todos os extras adicionais fornecidos usando o parâmetro
extrassão adicionados.
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"
Criar instâncias de DeepLinkMatcher
Um DeepLinkMatcher mapeia instâncias de DeepLinkRequest recebidas para chaves de navegação que podem ser adicionadas à backstack do seu app. O Navigation 3
fornece três correspondentes integrados: UriDeepLinkMatcher para correspondência de URI baseada em padrões, StaticKeyDeepLinkMatcher para links básicos e
BackStackMatcher para criar pilhas de retorno sintéticas. A biblioteca também
oferece suporte a correspondentes personalizados para casos de uso não cobertos pelos correspondentes integrados.
Para mais informações, consulte Criar DeepLinkMatchers.
Adicionar filtros de intent
Para permitir que um link direto inicie sua atividade, defina os elementos correspondentes
<intent-filter> no AndroidManifest.xml do seu app. Para mais
informações, consulte Adicionar filtros de intent para links recebidos.
Corresponder uma solicitação recebida
Depois de criar as instâncias de DeepLinkMatcher, você pode corresponder
as solicitações recebidas na sua atividade.
Para corresponder uma solicitação recebida, siga estas etapas:
- Instancie as instâncias de
DeepLinkMatcher. - Reúna todas as instâncias de
DeepLinkMatcher, de forma explícita ou usando multibindings. - Crie um
DeepLinkRequestdaIntentrecebida. - Corresponda a solicitação a todos os correspondentes e encontre a melhor correspondência.
- Crie o backstack a partir do resultado da correspondência.
// 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) } } }