A partire dalla versione 1.2.0, Navigation 3 supporta i link diretti alle
destinazioni della tua app utilizzando le classi DeepLinkRequest e
DeepLinkMatcher.
Per supportare i link diretti nella tua app, completa i seguenti passaggi:
- Definisci i filtri per intent in
AndroidManifest.xmlper specificare gli URI che la tua app può gestire. - Crea istanze
DeepLinkMatcherper mappare le richieste in entrata alle tue chiavi di navigazione. - Abbina le richieste in entrata nel metodo
onCreateoonNewIntentdell'attività e aggiorna di conseguenza il back stack.
Crea un DeepLinkRequest
Un DeepLinkRequest rappresenta un link diretto in entrata. Contiene un
DeepLinkUri e RequestExtras facoltativi con
informazioni aggiuntive, come l'azione 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") } )
Fornisci gli extra di DeepLinkRequest
Per archiviare informazioni aggiuntive relative al link diretto, utilizza la
RequestExtras classe. Per rendere la definizione e l'istanza degli extra type-safe,
la libreria fornisce l'interfaccia RequestExtrasKey e il DSL requestExtras.
Inoltre, la libreria fornisce due chiavi extra e gli helper associati:
MimeTypeExtrasKey: utilizzata per archiviare unaStringdel tipo MIME.ActionExtrasKey(solo Android): utilizzata per archiviare unaStringdell'azioneIntent.
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'RequestExtrasKey
interfaccia con un generico tipizzato:
// 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. Quando viene creato in questo modo, DeepLinkRequest viene creato come segue:
- Il
uriviene copiato dal campodatadell'intent. - Se non è null, gli extra del tipo MIME e dell'azione vengono impostati dai campi intent corrispondenti.
- Tutti i
intent.extrascon valori non null vengono salvati comeSavedStateinDeepLinkRequest.IntentExtrasKey. - Vengono aggiunti tutti gli 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 istanze di DeepLinkMatcher
Un DeepLinkMatcher mappa le istanze DeepLinkRequest in entrata alle chiavi di navigazione che possono essere aggiunte al back stack dell'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 stack indietro sintetici. La libreria supporta anche
matcher personalizzati per i casi d'uso non coperti dai matcher integrati.
Per saperne di più, vedi Creare DeepLinkMatchers.
Aggiungi filtri per intent
Per consentire a un link diretto di avviare l'attività, devi definire gli elementi corrispondenti
<intent-filter> in AndroidManifest.xml della tua app. Per saperne di più, vedi Aggiungere filtri per intent per i link in entrata.
Abbina una richiesta in entrata
Dopo aver creato le istanze DeepLinkMatcher, puoi abbinare le richieste in entrata
nella tua attività.
Per abbinare una richiesta in entrata:
- Crea un'istanza delle istanze di
DeepLinkMatcher. - Raccogli tutte le istanze di
DeepLinkMatcher, in modo esplicito o utilizzando multibinding. - Crea un
DeepLinkRequestdall'Intentin entrata. - Abbina la richiesta a 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) } } }