A partire dalla versione 1.2.0, Navigation 3 supporta il deep linking alle destinazioni nella tua app utilizzando le classi DeepLinkRequest e DeepLinkMatcher.
Per supportare i deep link nella tua app, completa i seguenti passaggi:
- Definisci i filtri per intent nel tuo
AndroidManifest.xmlper specificare quali URI possono essere gestiti dalla tua app. - Crea istanze
DeepLinkMatcherper mappare le richieste in entrata alle tue chiavi di navigazione. - Abbina le richieste in arrivo nel metodo
onCreateoonNewIntentdella tua attività e aggiorna il back stack di conseguenza.
Crea un DeepLinkRequest
Un DeepLinkRequest rappresenta un deep link in entrata. Contiene un elemento DeepLinkUri e un elemento RequestExtras facoltativo con informazioni aggiuntive, ad esempio l'azione dell'intent o il 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") } )
Fornire DeepLinkRequest extra
Per memorizzare informazioni aggiuntive relative al deep link, utilizza la classe RequestExtras. Per rendere sicura la definizione e l'istanza degli extra,
la libreria fornisce l'interfaccia RequestExtrasKey e
il DSL requestExtras.
Inoltre, la libreria fornisce due chiavi aggiuntive e gli helper associati:
MimeTypeExtrasKey: utilizzato per archiviare un tipo MIMEString.ActionExtrasKey(solo Android): utilizzato per archiviare un'azioneStringdi 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)
Per definire i tuoi extra personalizzati, implementa l'interfaccia RequestExtrasKey con un tipo generico:
// Define a custom typed key: object CampaignIdExtrasKey : RequestExtrasKey<String> val customExtras: RequestExtras = requestExtras { put(CampaignIdExtrasKey, "123") } val campaignId: String? = customExtras[CampaignIdExtrasKey]
Puoi anche utilizzare emptyRequestExtras() per creare un'istanza vuota o combinare gli extra utilizzando gli operatori + (plus) e - (minus).
Crea un DeepLinkRequest da un Intent
Su Android, puoi creare un DeepLinkRequest direttamente da un Intent. Se costruito in questo modo, DeepLinkRequest viene creato come segue:
uriviene copiato dal campodatadell'intent.- Se non è null, il tipo MIME e gli extra dell'azione vengono impostati dai campi dell'intent corrispondenti.
- Tutti i
intent.extrascon valori non null vengono salvati comeSavedStateinDeepLinkRequest.IntentExtrasKey. - Vengono aggiunti eventuali extra aggiuntivi forniti utilizzando il parametro
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 DeepLinkMatcher istanze
Un DeepLinkMatcher mappa le istanze DeepLinkRequest in entrata alle chiavi di navigazione che possono essere aggiunte al back stack della tua app. Navigation 3
fornisce tre matcher integrati: UriDeepLinkMatcher per
la corrispondenza degli URI basata su pattern, StaticKeyDeepLinkMatcher per i link di base e
BackStackMatcher per la creazione di back stack sintetici. La libreria supporta anche matcher personalizzati per i casi d'uso non coperti dai matcher integrati.
Per saperne di più, consulta Crea DeepLinkMatcher.
Aggiungi filtri per intent
Per consentire a un deep link di avviare la tua attività, devi definire gli elementi <intent-filter> corrispondenti nel file AndroidManifest.xml della tua app. Per saperne di più, consulta Aggiungi filtri per intent per i link in entrata.
Corrispondenza con una richiesta in entrata
Dopo aver creato le istanze DeepLinkMatcher, puoi abbinare le richieste in entrata nella tua attività.
Per trovare una corrispondenza con una richiesta in arrivo, segui questi passaggi:
- Crea un'istanza delle tue istanze
DeepLinkMatcher. - Raggruppa tutte le istanze
DeepLinkMatcher, in modo esplicito o utilizzando i multibinding. - Crea un
DeepLinkRequestdalIntentin entrata. - Confronta la richiesta con tutti i matcher e trova la corrispondenza migliore.
- Crea il back stack dal risultato della corrispondenza.
// 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) } } }