À partir de la version 1.2.0, Navigation 3 est compatible avec les liens profonds vers les
destinations de votre application à l'aide des classes DeepLinkRequest et
DeepLinkMatcher.
Pour prendre en charge les liens profonds dans votre application, procédez comme suit :
- Définissez des filtres d'intent dans votre fichier
AndroidManifest.xmlpour spécifier les URI que votre application peut gérer. - Créez des instances
DeepLinkMatcherpour mapper les requêtes entrantes à vos clés de navigation. - Faites correspondre les requêtes entrantes dans la méthode
onCreateouonNewIntentde votre activité, puis mettez à jour votre pile "Retour" en conséquence.
Créer une DeepLinkRequest
Une DeepLinkRequest représente un lien profond entrant. Elle contient une
DeepLinkUri et des RequestExtras facultatifs avec des informations supplémentaires, telles que l'action d'intent ou le type 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") } )
Fournir des extras DeepLinkRequest
Pour stocker des informations supplémentaires liées au lien profond, utilisez la
RequestExtras classe. Pour rendre la définition et l'instanciation des extras de type sécurisé,
la bibliothèque fournit l'interface RequestExtrasKey et le DSL
requestExtras.
De plus, la bibliothèque fournit deux clés d'extras et des assistants associés :
MimeTypeExtrasKey: permet de stocker un type MIMEString.ActionExtrasKey(Android uniquement) : permet de stocker une actionStringd'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)
Pour définir vos propres extras personnalisés, implémentez l'RequestExtrasKey
interface avec un générique typé :
// Define a custom typed key: object CampaignIdExtrasKey : RequestExtrasKey<String> val customExtras: RequestExtras = requestExtras { put(CampaignIdExtrasKey, "123") } val campaignId: String? = customExtras[CampaignIdExtrasKey]
Vous pouvez également utiliser emptyRequestExtras() pour construire une instance vide ou
combiner des extras à l'aide des opérateurs + (plus) et - (minus).
Créer une DeepLinkRequest à partir d'un Intent
Sur Android, vous pouvez créer une DeepLinkRequest directement à partir d'un Intent. Lorsqu'elle est construite de cette manière, la DeepLinkRequest est créée comme suit :
- Le
uriest copié à partir du champdatade l'intent. - S'ils ne sont pas nuls, les extras de type MIME et d'action extras sont définis à partir des champs d'intent correspondants.
- Tous les
intent.extrasavec des valeurs non nulles sont enregistrés en tant queSavedStatedansDeepLinkRequest.IntentExtrasKey. - Tous les extras supplémentaires fournis à l'aide du paramètre
extrassont ajoutés.
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"
Créer des instances DeepLinkMatcher
Un DeepLinkMatcher mappe les instances DeepLinkRequest entrantes aux
clés de navigation qui peuvent être ajoutées à la pile "Retour" de votre application. Navigation 3
fournit trois correspondances intégrées : UriDeepLinkMatcher pour la correspondance d'URI basée sur des modèles, StaticKeyDeepLinkMatcher pour les liens de base et
BackStackMatcher pour la création de piles "Retour" synthétiques. La bibliothèque est également
compatible avec les correspondances personnalisées pour les cas d'utilisation non couverts par les correspondances intégrées.
Pour en savoir plus, consultez Créer des DeepLinkMatchers.
Ajouter des filtres d'intent
Pour qu'un lien profond puisse démarrer votre activité, vous devez définir les éléments correspondants
<intent-filter> dans le AndroidManifest.xml de votre application. Pour en savoir plus, consultez Ajouter des filtres d'intent pour les liens entrants.
Faire correspondre une requête entrante
Une fois que vous avez créé vos instances DeepLinkMatcher, vous pouvez faire correspondre
les requêtes entrantes dans votre activité.
Pour faire correspondre une requête entrante, procédez comme suit :
- Instanciez vos instances
DeepLinkMatcher. - Regroupez toutes vos instances
DeepLinkMatcher, de manière explicite ou à l'aide de multibindings. - Créez une
DeepLinkRequestà partir de l'Intententrant. - Faites correspondre la requête à toutes les correspondances et trouvez la meilleure.
- Créez la pile "Retour" à partir du résultat de la correspondance.
// 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) } } }