À partir de la version 1.2.0, Navigation 3 est compatible avec les liens profonds vers des 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. - Mettez en correspondance les requêtes entrantes dans la méthode
onCreateouonNewIntentde votre activité, puis mettez à jour votre pile d'historique en conséquence.
Créer un élément DeepLinkRequest
Un DeepLinkRequest représente un lien profond entrant. Il contient un DeepLinkUri et un RequestExtras facultatif 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 classe RequestExtras. Pour que la définition et l'instanciation des extras soient de type sécurisé, la bibliothèque fournit l'interface RequestExtrasKey et le DSL requestExtras.
De plus, la bibliothèque fournit deux clés supplémentaires et des assistants associés :
MimeTypeExtrasKey: permet de stocker un type MIMEString.ActionExtrasKey(Android uniquement) : permet de stocker l'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'interface RequestExtrasKey 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 créer une instance vide ou combiner des extras à l'aide des opérateurs + (plus) et - (minus).
Créer un DeepLinkRequest à partir d'un Intent
Sur Android, vous pouvez créer un DeepLinkRequest directement à partir d'un Intent. Lorsqu'il est construit de cette manière, le DeepLinkRequest est créé comme suit :
- Le
uriest copié à partir du champdatade l'intent. - Si la valeur n'est pas nulle, le type MIME et les extras d'action 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 touches de navigation qui peuvent être ajoutées à la pile « Retour » de votre application. Navigation 3 fournit trois outils de mise en correspondance intégrés : UriDeepLinkMatcher pour la mise en correspondance d'URI basée sur des modèles, StaticKeyDeepLinkMatcher pour les liens de base et BackStackMatcher pour créer des piles « Retour » synthétiques. La bibliothèque est également compatible avec les outils de mise en correspondance personnalisés pour les cas d'utilisation non couverts par les outils de mise en correspondance intégrés.
Pour en savoir plus, consultez Créer des DeepLinkMatchers.
Ajouter des filtres d'intent
Pour permettre à un lien profond de démarrer votre activité, vous devez définir les éléments <intent-filter> correspondants dans le fichier AndroidManifest.xml de votre application. Pour en savoir plus, consultez Ajouter des filtres d'intent pour les liens entrants.
Mettre en correspondance une requête entrante
Après avoir créé vos instances DeepLinkMatcher, vous pouvez mettre en correspondance 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, soit explicitement, soit en utilisant des liaisons multiples. - Créez un
DeepLinkRequestà partir duIntententrant. - Mettre en correspondance la requête avec tous les outils de mise en correspondance et trouver la meilleure correspondance.
- 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) } } }