1. Avant de commencer
Synthèse rapide sur les liens profonds, les liens Web et Android App Links
Lorsqu'un utilisateur suit un lien profond, c'est dans l'objectif d'accéder au contenu de son choix. Les liens profonds comportent toutes les fonctionnalités pour aider les utilisateurs à atteindre cet objectif. Android gère les types de liens suivants :
- Liens profonds : URI de tout schéma qui redirigent directement les utilisateurs vers une partie spécifique d'une application.
- Liens Web : liens profonds avec les schémas HTTP et HTTPS.
- Android App Links : liens Web avec les schémas HTTP et HTTPS qui contiennent l'attribut
android:autoVerify
.
Pour en savoir plus sur les liens profonds, les liens Web et Android App Links, consultez la documentation Android, et le cours d'initiation sur YouTube et Medium.
Vous connaissez déjà Android App Links ?
Si vous disposez déjà de tous les détails techniques, consultez l'implémentation rapide de l'article de blog connexe pour configurer rapidement la fonctionnalité.
Objectif de l'atelier de programmation
Il explique les bonnes pratiques pour configurer, implémenter et vérifier une application avec Android App Links.
Android App Links présente l'avantage d'être sécurisé, ce qui signifie que seules les applications autorisées peuvent gérer vos liens. L'OS Android doit vérifier les liens d'un site Web dont vous êtes propriétaire pour les qualifier d'Android App Links. Ce processus est appelé association de sites Web.
Cet atelier de programmation s'adresse aux développeurs avec un site Web et une application Android. Android App Links améliore l'expérience utilisateur en permettant l'intégration parfaite de votre application et de votre site Web.
Conditions préalables
- Connaissances de base sur le gestionnaire d'activités adb et le gestionnaire de packages adb.
- Connaissances de base sur le développement et la navigation Android avec Jetpack Compose.
Points abordés
- Apprendre les bonnes pratiques de création des URL pour Android App Links.
- Configurez tous les types de liens profonds dans une application Android.
- Connaître les caractères génériques des chemins (
path
,pathPrefix
,pathPattern
,pathAdvancePattern
). - Découvrir la procédure de validation Android App Links avec importation du fichier Google Digital Asset Links (DAL), la procédure de validation manuelle Android App Links, ainsi que le tableau de bord "Deep links" (Liens profonds) de la Play Console.
- Développer une application avec plusieurs restaurants dans divers endroits.
Ce dont vous aurez besoin
- Android Studio Dolphin (2021.3.1) ou version ultérieure.
- Un domaine pour héberger les fichiers Google Digital Asset Link (DAL). (En option : lisez cet article de blog pour vous préparer en quelques minutes.)
- En option : un compte de développeurs Google Play Console. Vous disposez ainsi d'une autre approche pour déboguer votre configuration Android App Links.
2. Configurer le code
Créer une application Compose vide
Pour lancer un projet Compose, procédez comme suit :
- Dans Android Studio, sélectionnez File > New > New Project (Fichier > Nouveau > Nouveau projet).
New Project (Nouveau > Nouveau projet)." class="l10n-absolute-url-src" l10n-attrs-original-order="alt,style,src,srcset,sizes,class" l10n-encrypted-style="2dV7hbnGKYSuLgQu/MlX0k8zz2uYoEmRhrQeP6/mnhY=" sizes="(max-width: 840px) 100vw, 856px" src="https://developer.android.com/static/codelabs/android-app-links-introduction/img/3d30cedf28504241.png" srcset="/static/codelabs/android-app-links-introduction/img/3d30cedf28504241_36.png 36w,/static/codelabs/android-app-links-introduction/img/3d30cedf28504241_48.png 48w,/static/codelabs/android-app-links-introduction/img/3d30cedf28504241_72.png 72w,/static/codelabs/android-app-links-introduction/img/3d30cedf28504241_96.png 96w,/static/codelabs/android-app-links-introduction/img/3d30cedf28504241_480.png 480w,/static/codelabs/android-app-links-introduction/img/3d30cedf28504241_720.png 720w,/static/codelabs/android-app-links-introduction/img/3d30cedf28504241_856.png 856w,/static/codelabs/android-app-links-introduction/img/3d30cedf28504241_960.png 960w,/static/codelabs/android-app-links-introduction/img/3d30cedf28504241_1440.png 1440w,/static/codelabs/android-app-links-introduction/img/3d30cedf28504241_1920.png 1920w,/static/codelabs/android-app-links-introduction/img/3d30cedf28504241_2880.png 2880w" style="width: 378.00px" />
- Sélectionnez Empty Compose Activity (Activité Compose vide) dans les modèles disponibles.
- Cliquez sur Next (Suivant), configurez votre projet et appelez-le Deep Links Basics. Choisissez une version de Minimum SDK (SDK minimal) ayant au moins le niveau d'API 21, ce qui correspond au niveau d'API minimum accepté par Compose.
- Cliquez sur Finish (Terminer) et attendez que le projet soit généré.
- Démarrez l'application. Vérifiez que l'application s'exécute. Un écran vide avec un message Hello Android! doit s'afficher.
Solution de l'atelier de programmation
Le code nécessaire à la solution de cet atelier de programmation est disponible sur GitHub :
git clone https://github.com/android/deep-links
Vous pouvez également télécharger le dépôt sous forme de fichier ZIP :
Accédez d'abord au répertoire deep-links-introduction. L'application doit se trouver dans le répertoire solution. Nous vous recommandons de suivre l'atelier de programmation étape par étape, à votre rythme, et de consulter la solution si vous le jugez nécessaire. Au cours de cet atelier de programmation, vous découvrirez des extraits de code que vous devrez ajouter au projet.
3. Vérifier la conception d'URL basée sur les liens profonds
Conception de l'API RESTful
Les liens sont essentiels au développement Web. Leur conception a fait l'objet d'une multitude d'itérations à l'origine de différents standards. Il peut valoir la peine d'étudier et d'appliquer ces standards de conception qui visent à simplifier l'utilisation et la gestion des liens de développement Web.
L'un de ces standards, REST (Representational State Transfer) et une architecture généralement utilisée pour concevoir les API des services Web. L'initiative OpenAPI standardise les API REST. Vous pouvez aussi utiliser REST pour concevoir les URL de vos liens profonds.
Notez que vous ne créez pas un service Web. Cette section se penche uniquement sur la conception d'URL.
Conception des URL
Examinez d'abord les URL obtenues sur votre site Web et déterminez ce qu'elles représentent dans l'application Android :
/restaurants
recense tous les restaurants que vous gérez./restaurants/:restaurantName
affiche les détails d'un restaurant./restaurants/:restaurantName/orders
affiche les commandes d'un restaurant./restaurants/:restaurantName/orders/:orderNumber
affiche une commande donnée d'un restaurant./restaurants/:restaurantName/orders/latest
affiche la dernière commande d'un restaurant.
Pourquoi la conception de l'URL est-elle importante ?
Android comporte des filtres d'intent qui gèrent les actions d'un autre composant d'application et permettent d'intercepter les URL. Lorsque vous définissez un filtre d'intent pour qu'il intercepte un URL, vous devez suivre une structure qui repose sur des préfixes de chemin et des caractères génériques simples. Voici un exemple de structuration à partir d'un URL du site Web de votre restaurant :
https://example.com/pawtato-3140-Skinner-Hollow-Road
Même si l'URL spécifie votre restaurant et son emplacement, le chemin peut poser problème pour définir un filtre d'intent permettant à Android d'intercepter l'URL. En effet, votre application est basée sur plusieurs URL de restaurant comme les suivantes :
https://example.com/rawrbucha-2064-carriage-lane
https://example.com/pizzabus-1447-davis-avenue
Lorsque vous définissez un filtre d'intent avec un chemin et un caractère générique pour intercepter ces URL, vous pouvez utiliser un élément comme https://example.com/*
qui, globalement, fonctionne. Pourtant, le problème n'est pas véritablement résolu, puisqu'il existe d'autres chemins vers différentes sections de votre site Web, comme les suivantes :
Livraison : https://example.com/deliveries
Administration : https://example.com/admin
Même si vous ne souhaitez pas qu'Android intercepte ces URL (certains d'entre eux pouvant être internes), le filtre d'intent https://example.com/*
va les intercepter, y compris ceux qui n'existent pas. Lorsqu'un utilisateur clique sur l'une de ces URL, il s'ouvre dans le navigateur (versions > à Android 12) ou une boîte de dialogue de sélection d'application s'affiche (versions < à Android 12). Ce comportement n'est pas intentionnel avec une telle conception.
Android propose désormais des préfixes de chemin qui résolvent le problème, mais impliquent de revoir la conception de l'URL de :
https://example.com/*
en :
https://example.com/restaurants/*
L'ajout d'une structure d'imbrication hiérarchique permet de définir clairement les filtres d'intent. Android intercepte ainsi l'URL qui convient.
Bonnes pratiques pour la conception d'URL
Voici quelques bonnes pratiques inspirées d'OpenAPI à appliquer aux liens profonds :
- Cibler la conception d'URL en fonction des entités commerciales exposées. Par exemple, la conception pour l'e-commerce concerne les clients et les commandes. La conception pour le voyage concerne les billets et les vols. La conception pour votre application et votre site Web de restaurants va concerner les restaurants et les commandes.
- La plupart des méthodes HTTP (GET, POST, DELETE, PUT) sont des verbes qui décrivent la requête en cours, même si l'utilisation de verbes dans les URL pour les points de terminaison peut être nébuleuse.
- Pour décrire les collections, utilisez le pluriel, comme dans
/restaurants/:restaurantName
. Cela simplifie la lecture et la gestion de l'URL. Voici un exemple avec chaque méthode HTTP :
GET /restaurants/pawtato
POST /restaurants
DELETE /restaurants
PUT /restaurants/pawtato
Chaque URL est plus facile à lire et à interpréter. Notez que cet atelier de programmation ne traite pas de la conception des API des services Web ni du fonctionnement de chaque méthode.
- Utilisez l'imbrication logique pour grouper les URL qui contiennent des informations associées. Par exemple, l'URL d'un des restaurants peut avoir des commandes en cours de traitement :
/restaurants/1/orders
4. Vérifier l'élément de données
Le fichier AndroidManifest.xml
est un élément essentiel d'Android. Il décrit les informations de l'application pour les outils de développement d'Android, l'OS Android et Google Play.
Pour les liens profonds, vous devez définir un filtre d'intent avec trois tags principaux : <action>
, <category>
et <data>
. Cette section se concentre sur le tag <data>
.
Un élément <data>
indique à l'OS Android la structure URL d'un lien lorsqu'un utilisateur clique dessus. Le format et la structure URL que vous pouvez appliquer aux filtres d'intent sont les suivants :
<scheme>://<host>:<port>[<path>|<pathPrefix>|<pathPattern>|<pathAdvancedPattern>|<pathSuffix>]
Android lit, analyse et fusionne l'ensemble des éléments <data>
d'un filtre d'intent afin de prendre en compte toutes les variantes des attributs. Exemple :
AndroidManifest.xml
<intent-filter>
...
<data android:scheme="http" />
<data android:scheme="https" />
<data android:host="example.com" />
<data android:path="/restaurants" />
<data android:pathPrefix="/restaurants/orders" />
</intent-filter>
Android va intercepter les URL suivants :
http://example.com/restaurants
https://example.com/restaurants
http://example.com/restaurants/orders/*
https://example.com/restaurants/orders/*
Attributs de chemin
path
(avec API 1)
Cet attribut spécifie un chemin complet commençant par /
qui est mis en correspondance avec le chemin complet de l'intent. Par exemple, android:path="/restaurants/pawtato"
correspond uniquement au chemin de site Web /restaurants/pawtato
. De ce fait, l'URL /restaurant/pawtato
n'est pas mis en correspondance en raison du s
manquant.
pathPrefix
(avec API 1)
Cet attribut spécifie un chemin partiel mis en correspondance uniquement avec la partie initiale du chemin de l'intent. Par exemple :
android:pathPrefix="/restaurants"
correspond aux chemins de restaurant suivants : /restaurants/pawtato
, /restaurants/pizzabus
, etc.
pathSuffix
(avec API 31)
Cet attribut spécifie un chemin mis en correspondance exacte avec la partie finale du chemin de l'intent. Par exemple :
android:pathSuffix="tato"
correspond à tous les chemins de restaurant qui se terminent par tato, comme /restaurants/pawtato
et /restaurants/corgtato
.
pathPattern
(avec API 1)
Cet attribut spécifie un chemin complet mis en correspondance avec un chemin complet avec caractères génériques de l'intent :
- Un astérisque (
*
) correspond à une séquence de zéro à plusieurs occurrences du caractère qui précède. - Un point suivi d'un astérisque (
.*
) représente une séquence de zéro à plusieurs caractères.
Exemples :
/restaurants/piz*abus
: ce schéma correspond au restaurant "Pizzabus", mais il correspond aussi aux restaurants dont le nom comporte zéro à plusieurs caractèresz
, comme/restaurants/pizzabus
,/restaurants/pizzzabus
et/restaurants/pizabus
./restaurants/.*
: ce schéma correspond à tous les noms de restaurant avec le chemin/restaurants
, comme/restaurants/pizzabus
et/restaurants/pawtato
, ainsi qu'à ceux que l'application ne connaît pas, comme/restaurants/wateriehall
.
pathAdvancePattern
(avec API 31)
Cet attribut spécifie un chemin complet mis en correspondance avec un chemin complet avec un schéma de type "expression régulière" :
- Un point (
.
) correspond à n'importe quel caractère. - Un ensemble entre crochets (
[...]
) correspond à une plage de caractères. Il est également compatible avec le modificateur not (^
). - Un astérisque (
*
) correspond à zéro à plusieurs occurrences du caractère qui précède. - Un plus (
+
) correspond à une ou plusieurs occurrences du caractère qui précède. - Les accolades (
{...}
) représentent le nombre de correspondances potentielles d'un schéma.
Cet attribut peut être considéré comme une extension de pathPattern
. Il offre une mise en correspondance plus flexible des URL, par exemple :
/restaurants/[a-zA-Z]*/orders/[0-9]{3}
correspond à n'importe quelle commande de restaurant comportant jusqu'à trois chiffres./restaurants/[a-zA-Z]*/orders/latest
correspond à la dernière commande de n'importe quel restaurant l'application.
5. Créer des liens profonds et des liens Web
Liens profonds avec schémas personnalisés
Les liens profonds avec schémas personnalisés sont les plus génériques. Leur implémentation est la plus facile, mais présente certains inconvénients. Les sites Web ne peuvent pas ouvrir ce type de liens. Toute application qui spécifie être compatible avec un schéma dans son fichier peut ouvrir le lien correspondant.
Vous pouvez utiliser n'importe quel schéma avec l'élément <data>
. Par exemple, l'atelier de programmation utilise l'URL food://restaurants/keybabs
.
- Dans Android Studio, ajoutez le filtre d'intent suivant dans le fichier manifeste :
AndroidManifest.xml
<activity ... >
<intent-filter>
<action android:name="android.intent.action.VIEW"/>
<category android:name="android.intent.category.BROWSABLE"/>
<category android:name="android.intent.category.DEFAULT"/>
<data android:scheme="food"/>
<data android:path="/restaurants/keybabs"/>
</intent-filter>
</activity>
- Pour vérifier que votre application peut ouvrir les liens avec schémas personnalisés, réalisez une capture de l'écran d'accueil et ajoutez les éléments suivants à l'activité principale :
MainActivity.kt
class MainActivity : ComponentActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
// Receive the intent action and data
val action: String? = intent?.action;
val data: Uri? = intent?.data;
setContent {
DeepLinksBasicsTheme {
Surface(
modifier = Modifier.fillMaxSize(),
color = MaterialTheme.colors.background
) {
// Add a Column to print a message per line
Column {
// Print it on the home screen
Greeting("Android")
Text(text = "Action: $action")
Text(text = "Data: $data")
}
}
}
}
}
}
- Pour tester la réception de l'intent, utilisez l'Android Debug Bridge (adb) avec la commande suivante :
adb shell am start -W -a android.intent.action.VIEW -d "food://restaurants/keybabs"
La commande démarre un intent avec l'action VIEW (AFFICHER) et utilise l'URL fournie comme donnée. Lorsque vous exécutez cette commande, l'application lance et reçoit l'intent. Remarquez les modifications qui apparaissent dans les sections de texte de l'écran principal. La première affiche le message Hello Android!, la deuxième affiche l'action pour laquelle l'intent a été appelé, et la troisième affiche l'URL pour lequel l'intent a été appelé.
Dans l'image suivante, notez que la commande adb
mentionnée s'est exécutée dans la section inférieure d'Android Studio. À droite, l'application affiche les informations de l'intent dans l'écran d'accueil, ce qui signifie qu'il a bien été reçu.
Liens Web
Les liens Web sont des liens profonds qui utilisent l'http
et l'https
plutôt que les schémas personnalisés.
Pour implémenter un lien Web, utilisez le chemin /restaurants/keybabs/order/latest.html
, qui représente la dernière commande reçue par le restaurant.
- Adaptez le fichier manifeste en utilisant le filtre d'intent existant.
AndroidManifest.xml
<intent-filter>
<action android:name="android.intent.action.VIEW"/>
<category android:name="android.intent.category.BROWSABLE"/>
<category android:name="android.intent.category.DEFAULT"/>
<data android:scheme="food"/>
<data android:path="/restaurants/keybabs"/>
<!-- Web link configuration -->
<data android:scheme="http"/>
<data android:scheme="https"/>
<data android:host="sabs-deeplinks-test.web.app"/>
<data android:path="/restaurants/keybabs/order/latest.html"/>
</intent-filter>
Les chemins étant partagés (/restaurants/keybabs
), une bonne pratique consiste à les conserver dans le même filtre d'intent. Cela permet de simplifier l'implémentation et la lecture du fichier manifeste.
- Avant de tester le lien Web, redémarrez l'application pour appliquer les modifications.
- Utilisez la même commande adb pour lancer l'intent, mais dans ce cas, mettez à jour l'URL.
adb shell am start -W -a android.intent.action.VIEW -d "https://sabs-deeplinks-test.web.app/restaurants/keybabs/orders/latest.html"
Dans la capture d'écran, notez que l'intent a été reçu et que le navigateur Web est ouvert pour afficher le site Web (fonctionnalité des versions à partir d'Android 12).
6. Configurer Android App Links
Ces liens offrent une expérience utilisateur parfaitement fluide. Ainsi, lorsque l'utilisateur clique sur un lien, il est assuré d'accéder à l'application sans qu'une boîte de dialogue de sélection d'application ne s'ouvre. Implémenté avec Android 6.0, Android App Links propose des liens profonds très spécifiques. Ces liens Web utilisent le schéma http/https
et l'attribut android:autoVerify
, qui font de l'application le gestionnaire par défaut de tous les liens correspondants. Deux étapes principales permettent d'implémenter Android App Links :
- Mettre à jour le fichier manifeste avec le filtre d'intent qui convient.
- Ajouter l'association de sites Web à des fins de validation.
Mettre à jour le fichier manifeste
- Pour accepter Android App Links, dans le fichier manifeste, remplacez l'ancienne configuration par ce qui suit :
AndroidManifest.xml
<!-- Replace deep link and web link configuration with this -->
<!-- Please update the host with your own domain -->
<intent-filter android:autoVerify="true">
<action android:name="android.intent.action.VIEW"/>
<category android:name="android.intent.category.BROWSABLE"/>
<category android:name="android.intent.category.DEFAULT"/>
<data android:scheme="https"/>
<data android:host="example.com"/>
<data android:pathPrefix="/restaurants"/>
</intent-filter>
Ce filtre d'intent ajoute l'attribut android:autoVerify
et le définit sur "True" (Vrai). Cela permet à l'OS Android de vérifier le domaine lorsque l'application est installée et à chaque nouvelle mise à jour.
Association de sites Web
Pour vérifier un élément Android App Links, créez une association entre l'application et le site Web. Un fichier JSON Google Digital Asset Links (DAL) doit être publié sur le site Web pour que la validation soit effective.
Google DAL est un protocole et une API qui définissent les instructions vérifiables concernant les autres applications et sites Web. Dans cet atelier de programmation, vous allez créer une instruction concernant l'application Android dans le fichier assetlinks.json
. Par exemple :
assetlinks.json
[{
"relation": ["delegate_permission/common.handle_all_urls"],
"target": {
"namespace": "android_app",
"package_name": "com.devrel.deeplinksbasics",
"sha256_cert_fingerprints":
["B0:4E:29:05:4E:AB:44:C6:9A:CB:D5:89:A3:A8:1C:FF:09:6B:45:00:C5:FD:D1:3E:3E:12:C5:F3:FB:BD:BA:D3"]
}
}]
Même si l'exemple n'affiche qu'un seul élément, ce fichier peut conserver toute une liste d'instructions. Chaque instruction doit comporter les champs suivants :
- Relation : décrit une ou plusieurs relations déclarées à propos de la cible
- Target (Cible) : désigne le composant visé par l'instruction. Il peut s'agir de l'une des deux cibles disponibles,
web
ouandroid_app
La propriété target
de l'instruction Android comporte les champs suivants :
namespace
:android_app
pour toutes les applications Androidpackage_name
: nom de package complet (com.devrel.deeplinksbasics
)sha256_cert_fingerprints
: empreinte du certificat de l'application. Vous allez apprendre à générer ce certificat dans la section suivante
Empreinte du certificat
Plusieurs méthodes permettent d'obtenir l'empreinte du certificat. Cet atelier de programmation emploie deux méthodes. La première pour créer la release de débogage de l'application et la seconde pour publier l'app sur le Google Play Store.
Configuration du débogage
La première fois qu'Android Studio exécute votre projet, il signe votre application avec un certificat de débogage. Ce certificat se trouve dans $HOME/.android/debug.keystore
. Vous pouvez utiliser une commande Gradle pour obtenir l'empreinte du certificat SHA-256. Pour cela, procédez comme suit :
- Appuyez deux fois sur
Control
pour afficher le menu Run anything (Tout exécuter). S'il n'apparaît pas, accédez au menu Gradle de la barre latérale de droite et cliquez sur l'icône Gradle.
- Saisissez
gradle signingReport
, puis appuyez surEnter
. La commande s'exécute dans la console et affiche des informations sur l'empreinte pour la variante de l'application de débogage.
- Pour terminer l'association de sites Web, copiez l'empreinte du certificat SHA-256, mettez à jour le fichier JSON et importez-le sur votre site Web, dans
https://<domain>/.well-know/assetlinks.json
. Cet article de blog sur Android App Links vous explique comment configurer cette fonctionnalité. - Si l'application s'exécute toujours, appuyez sur Stop (Arrêter) pour l'arrêter.
- Pour relancer la procédure de validation, supprimez l'application du simulateur. Dans le simulateur, cliquez de manière prolongée sur l'icône de l'application Deep Links Basics et sélectionnez App Info (Infos sur l'appli). Cliquez sur Uninstall (Désinstaller), puis sur Confirm (Confirmer) dans la fenêtre modale. Exécutez ensuite l'application afin qu'Android Studio puisse vérifier l'association.
- Assurez-vous d'avoir sélectionné la configuration d'exécution App (Application). Dans le cas contraire, le rapport de signature Gradle s'exécute à nouveau.
- Redémarrez l'application et lancez l'intent avec l'URL Android App Links :
adb shell am start -W -a android.intent.action.VIEW -d "https://sabs-deeplinks-test.web.app/restaurants/"
- Notez que l'application se lance et que l'intent apparaît sur l'écran d'accueil.
Félicitations, vous avez créé votre premier élément Android App Links !
Configuration de release
Pour importer votre application avec Android App Links dans le Play Store, vous devez utiliser un build avec une empreinte de certificat appropriée. Pour le générer et l'importer, procédez comme suit :
- Dans le menu principal d'Android Studio, cliquez sur Build > Generate Signed Bundle/APK (Compiler > Générer un app Bundle/APK signé).
- Dans la boîte de dialogue suivante, sélectionnez Android App Bundle pour "Play App Signing" (Signature d'application Play) ou APK si vous le déployez directement sur un appareil.
- Dans la boîte de dialogue suivante, cliquez sur Create new (Créer) sous Key Store Path (Chemin du keystore). Une nouvelle fenêtre s'ouvre.
- Sélectionnez un chemin pour votre keystore et appelez-le
basics-keystore.jks
. - Créez et confirmez le mot de passe du keystore.
- Conservez l'alias par défaut de la clé.
- Vérifiez que le mot de passe et la confirmation sont identiques à ceux du keystore. Ils doivent correspondre.
- Renseignez les informations sur le certificat et cliquez sur OK.
- Assurez-vous d'avoir coché l'option d'exportation des clés chiffrées pour "Play App Signing" (Signature d'application Play) et cliquez sur Next (Suivant).
- Dans cette boîte de dialogue, sélectionnez la variante de build et cliquez sur Finish (Terminer). Vous pouvez maintenant importer vos applications dans le Google Play Store et utiliser la signature d'application Play.
Signature d'application Play
Avec la signature d'application Play, Google vous permet de gérer et de protéger la clé de signature de vos applications. Il vous suffit d'importer l'app bundle signé que vous avez obtenu à l'étape précédente.
Pour récupérer l'empreinte du certificat du fichier assetlinks.json
et disposer d'Android App Links dans le build de variante de version, procédez comme suit :
- Dans la Google Play Console, cliquez sur Create app (Créer une application).
- Pour le nom de l'application, saisissez Deep Links Basics.
- Sélectionnez App (Application) et Free (Sans frais) pour les deux options suivantes.
- Acceptez les Declarations (Déclarations) et cliquez sur Create app (Créer l'application).
- Pour importer l'app bundle et pouvoir tester Android App Links, sélectionnez Testing > Internal testing (Tests > Tests internes).
- Cliquez sur Create new release (Créer une version).
- Dans la section suivante, cliquez sur Upload (Importer), puis sélectionnez l'app bundle généré lors la dernière section. Vous trouverez le fichier
app-release.aab
sous Deep Links Basics > App > Release (Deep Links Basics > Application > Version). Cliquez sur Open (Ouvrir) et attendez que l'app bundle soit importé. - Une fois importé, ne modifiez pas les autres champs pour le moment. Cliquez sur Save (Enregistrer).
- Pour préparer la section suivante, cliquez sur Review release (Examiner la version). Dans l'écran suivant, cliquez sur Start rollout to Internal testing (Lancer le déploiement du test interne). Ignorer les mises en garde (cet atelier de programmation ne traite pas de la publication sur le Play Store).
- Cliquez sur Rollout (Déployer) dans la fenêtre modale.
- Pour récupérer l'empreinte du certificat SHA-256 créée par la signature d'application Play, accédez à l'onglet Deep links (Liens profonds) du menu de gauche et observez le tableau de bord "Deep links" (Liens profonds).
- Dans la section Domains (Domaines), cliquez sur le domaine du site Web. Notez que la Google Play Console indique que vous n'avez pas validé le domaine associé à votre application (association de sites Web).
- Dans la section Fix Domain Issues (Résoudre les problèmes de domaine), cliquez sur la flèche Show More (Plus).
- Dans cet écran, la Google Play Console vous indique comment mettre à jour le fichier
assetlinks.json
avec l'empreinte du certificat. Copiez l'extrait de code et mettez à jour le fichierassetlinks.json
.
- Une fois le fichier
assetlinks.json
à jour, cliquez sur Recheck verification (Recontrôler la vérification). Si la vérification ne s'est pas encore lancée, attendez cinq minutes que le service de vérification détecte les modifications. - Si vous actualisez le tableau de bord Deep links (Liens profonds), vous constatez que les erreurs de vérification ont disparu.
Vérification de l'application importée
Vous savez déjà vérifier une application qui se trouve dans le simulateur. Vous devez maintenant vérifier l'application importée dans le Play Store.
Pour installer l'application dans l'émulateur et s'assurer qu'Android App Links a bien été vérifié, procédez comme suit :
- Dans la barre latérale de gauche, cliquez sur Releases Overview (Vue d'ensemble des releases) et sélectionnez la release que vous venez d'importer. il doit s'agir de la release 1 (1.0).
- Cliquez sur Release details (Détails de la release) (flèche droite bleue) pour accéder aux détails de la release.
- Cliquez de nouveau sur la flèche droite bleue pour obtenir les informations sur l'app bundle.
- Dans cette fenêtre modale, sélectionnez l'onglet Downloads (Téléchargements), puis cliquez sur Download (Télécharger) pour le composant Signed, universal APK (APK standard signé).
- Avant d'installer l'app bundle dans le simulateur, supprimez la précédente application installée par Android Studio.
- Dans le simulateur, cliquez de manière prolongée sur l'icône de l'application Deep Links Basics et sélectionnez App Info (Infos sur l'appli). Cliquez sur Uninstall (Désinstaller), puis sur Confirm (Confirmer) dans la fenêtre modale.
- Pour installer l'app bundle téléchargé, glissez-déposez le fichier
1.apk
téléchargé dans l'écran du simulateur et attendez qu'il soit installé.
- Pour réaliser le test de validation, ouvrez Terminal dans Android Studio et exécutez la procédure de validation à l'aide des deux commandes suivantes :
adb shell pm verify-app-links --re-verify com.devrel.deeplinksbasics
adb shell pm get-app-links com.devrel.deeplinksbasics
- À l'issue de la commande
get-app-links
, un messageverified
doit s'afficher dans la console. Si vous obtenez un messagelegacy_failure
, vérifiez que l'empreinte du certificat correspond à celle que vous avez importée pour le site Web. Si les empreintes correspondent et que le message de vérification n'apparaît toujours pas, essayez de répéter les étapes 6, 7 et 8.
7. Implémenter Android App Links
Maintenant que tout est configuré, vous pouvez implémenter l'implication.
Utilisez Jetpack Compose pour l'implémentation. Pour en savoir plus sur Jetpack Compose, consultez Build better apps faster with Jetpack Compose (Créez de meilleures applications plus rapidement avec Jetpack Compose).
Dépendances de code
Pour intégrer et mettre à jour les quelques dépendances dont vous avez besoin pour ce projet, procédez comme suit :
- Ajoutez ce qui suit aux fichiers Gradle
Module
etProject
suivants :
build.gradle (Projet)
buildscript {
...
dependencies {
classpath "com.google.dagger:hilt-android-gradle-plugin:2.43"
}
}
build.gradle (Module)
plugins {
...
id 'kotlin-kapt'
id 'dagger.hilt.android.plugin'
}
...
dependencies {
...
implementation 'androidx.compose.material:material:1.2.1'
...
implementation "androidx.lifecycle:lifecycle-viewmodel-ktx:2.5.1"
implementation "androidx.lifecycle:lifecycle-viewmodel-compose:2.5.1"
implementation "androidx.hilt:hilt-navigation-compose:1.0.0"
implementation "com.google.dagger:hilt-android:2.43"
kapt "com.google.dagger:hilt-compiler:2.43"
}
Le fichier ZIP Project comporte un répertoire avec 10 images libres de droits que vous pouvez utiliser pour chaque restaurant. Vous pouvez les utiliser librement ou intégrer vos propres images.
Pour ajouter le point d'entrée principal d'HiltAndroidApp
, procédez comme suit :
- Créez une classe ou un fichier appelé
DeepLinksBasicsApplication.kt
, puis mettez à jour le nom de l'application dans le fichier manifeste.
DeepLinksBasicsApplication.kt
package com.devrel.deeplinksbasics
import android.app.Application
import dagger.hilt.android.HiltAndroidApp
@HiltAndroidApp
class DeepLinksBasicsApplication : Application() {}
AndroidManifest.xml
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools">
<!-- Update name property -->
<application
android:name=".DeepLinksBasicsApplication"
...
Données
Vous devez créer une couche de données pour les restaurants avec une classe Restaurant
, un dépôt et une source de données locale. Vous devez créer un package data
qui doit contenir tous ces éléments. Pour ce faire, procédez comme suit :
- Dans le fichier
Restaurant.kt
, créez une classeRestaurant
avec l'extrait de code suivant :
Restaurant.kt
package com.devrel.deeplinksbasics.data
import androidx.annotation.DrawableRes
import androidx.compose.runtime.Immutable
@Immutable
data class Restaurant(
val id: Int = -1,
val name: String = "",
val address: String = "",
val type: String = "",
val website: String = "",
@DrawableRes val drawable: Int = -1
)
- Dans le fichier
RestaurantLocalDataSource.kt
, ajoutez plusieurs restaurants à la classe de sources de données. N'oubliez pas de mettre à jour les données associées à votre domaine. Reportez-vous à l'extrait de code suivant :
RestaurantLocalDataSource.kt
package com.devrel.deeplinksbasics.data
import com.devrel.deeplinksbasics.R
import javax.inject.Inject
import javax.inject.Singleton
@Singleton
class RestaurantLocalDataSource @Inject constructor() {
val restaurantList = listOf(
Restaurant(
id = 1,
name = "Pawtato",
address = "3140 Skinner Hollow Road, Medford, Oregon 97501",
type = "Potato and gnochi",
// TODO: Update with your own domain
website = "https://your.own.domain/restaurants/pawtato/",
drawable = R.drawable.restaurant1,
),
Restaurant(
id = 2,
name = "Rawrbucha",
address = "2064 Carriage Lane, Mansfield, Ohio 44907",
type = "Kombucha",
// TODO: Update with your own domain
website = "https://your.own.domain/restaurants/rawrbucha/",
drawable = R.drawable.restaurant2,
),
Restaurant(
id = 3,
name = "Pizzabus",
address = "1447 Davis Avenue, Petaluma, California 94952",
type = "Pizza",
// TODO: Update with your own domain
website = "https://your.own.domain/restaurants/pizzabus/",
drawable = R.drawable.restaurant3,
),
Restaurant(
id = 4,
name = "Keybabs",
address = "3708 Pinnickinnick Street, Perth Amboy, New Jersey 08861",
type = "Kebabs",
// TODO: Update with your own domain
website = "https://your.own.domain/restaurants/keybabs/",
drawable = R.drawable.restaurant4,
),
Restaurant(
id = 5,
name = "BBQ",
address = "998 Newton Street, Saint Cloud, Minnesota 56301",
type = "BBQ",
// TODO: Update with your own domain
website = "https://your.own.domain/restaurants/bbq/",
drawable = R.drawable.restaurant5,
),
Restaurant(
id = 6,
name = "Salades",
address = "4522 Rockford Mountain Lane, Oshkosh, Wisconsin 54901",
type = "salads",
// TODO: Update with your own domain
website = "https://your.own.domain/restaurants/salades/",
drawable = R.drawable.restaurant6,
),
Restaurant(
id = 7,
name = "Gyros and moar",
address = "1993 Bird Spring Lane, Houston, Texas 77077",
type = "Gyro",
// TODO: Update with your own domain
website = "https://your.own.domain/restaurants/gyrosAndMoar/",
drawable = R.drawable.restaurant7,
),
Restaurant(
id = 8,
name = "Peruvian ceviche",
address = "2125 Deer Ridge Drive, Newark, New Jersey 07102",
type = "seafood",
// TODO: Update with your own domain
website = "https://your.own.domain/restaurants/peruvianCeviche/",
drawable = R.drawable.restaurant8,
),
Restaurant(
id = 9,
name = "Vegan burgers",
address = "594 Warner Street, Casper, Wyoming 82601",
type = "vegan",
// TODO: Update with your own domain
website = "https://your.own.domain/restaurants/veganBurgers/",
drawable = R.drawable.restaurant9,
),
Restaurant(
id = 10,
name = "Taquitos",
address = "1654 Hart Country Lane, Blue Ridge, Georgia 30513",
type = "mexican",
// TODO: Update with your own domain
website = "https://your.own.domain/restaurants/taquitos/",
drawable = R.drawable.restaurant10,
),
)
}
- Pensez à importer les images dans votre projet.
- Puis, dans le fichier
RestaurantRepository.kt
, ajoutez le dépôtRestaurant
avec une fonction permettant d'obtenir un restaurant grâce à son nom, comme dans l'extrait de code suivant :
RestaurantRepository.kt
package com.devrel.deeplinksbasics.data
import javax.inject.Inject
class RestaurantRepository @Inject constructor(
private val restaurantLocalDataSource: RestaurantLocalDataSource
){
val restaurants: List<Restaurant> = restaurantLocalDataSource.restaurantList
// Method to obtain a restaurant object by its name
fun getRestaurantByName(name: String): Restaurant ? {
return restaurantLocalDataSource.restaurantList.find {
val processedName = it.name.filterNot { it.isWhitespace() }.lowercase()
val nameToTest = name.filterNot { it.isWhitespace() }.lowercase()
nameToTest == processedName
}
}
}
ViewModel
Pour pouvoir sélectionner un restaurant avec l'application et Android App Links, vous devez créer un ViewModel
qui modifie la valeur du restaurant sélectionné. Procédez comme suit :
- Dans le fichier
RestaurantViewModel.kt
, ajoutez l'extrait de code suivant :
RestaurantViewModel.kt
package com.devrel.deeplinksbasics.ui.restaurant
import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope
import com.devrel.deeplinksbasics.data.Restaurant
import com.devrel.deeplinksbasics.data.RestaurantRepository
import dagger.hilt.android.lifecycle.HiltViewModel
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.StateFlow
import kotlinx.coroutines.launch
import javax.inject.Inject
@HiltViewModel
class RestaurantViewModel @Inject constructor(
private val restaurantRepository: RestaurantRepository,
) : ViewModel() {
// restaurants and selected restaurant could be used as one UIState stream
// which will scale better when exposing more data.
// Since there are only these two, it is okay to expose them as separate streams
val restaurants: List<Restaurant> = restaurantRepository.restaurants
private val _selectedRestaurant = MutableStateFlow<Restaurant?>(value = null)
val selectedRestaurant: StateFlow<Restaurant?>
get() = _selectedRestaurant
// Method to update the current restaurant selection
fun updateSelectedRestaurantByName(name: String) {
viewModelScope.launch {
val selectedRestaurant: Restaurant? = restaurantRepository.getRestaurantByName(name)
if (selectedRestaurant != null) {
_selectedRestaurant.value = selectedRestaurant
}
}
}
}
Compose
Maintenant que vous disposez de la logique du ViewModel et des couches de données, vous pouvez ajouter une couche d'interface utilisateur (UI). La bibliothèque Jetpack Compose permet cela en quelques étapes. Pour cette application, vous souhaitez afficher vos restaurants sous la forme d'une grille de cartes. L'utilisateur peut cliquer sur chaque carte pour accéder aux informations du restaurant. Vous devez utiliser trois fonctions composables principales et un composant de navigation qui amène au restaurant en question.
Pour ajouter une couche d'UI, procédez comme suit :
- Commencez par la fonction composable qui affiche les informations de chaque restaurant. Dans le fichier
RestaurantCardDetails.kt
, ajoutez l'extrait de code suivant :
RestaurantCardDetails.kt
package com.devrel.deeplinksbasics.ui
import androidx.activity.compose.BackHandler
import androidx.compose.foundation.Image
import androidx.compose.foundation.clickable
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.Spacer
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.width
import androidx.compose.foundation.shape.CornerSize
import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.foundation.text.selection.SelectionContainer
import androidx.compose.material.Card
import androidx.compose.material.Icon
import androidx.compose.material.MaterialTheme
import androidx.compose.material.Scaffold
import androidx.compose.material.Text
import androidx.compose.material.TopAppBar
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.filled.ArrowBack
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.res.painterResource
import androidx.compose.ui.unit.dp
import com.devrel.deeplinksbasics.data.Restaurant
@Composable
fun RestaurantCardDetails (
restaurant: Restaurant,
onBack: () -> Unit,
) {
BackHandler() {
onBack()
}
Scaffold(
topBar = {
TopAppBar(
backgroundColor = Color.Transparent,
elevation = 0.dp,
) {
Row(
horizontalArrangement = Arrangement.Start,
modifier = Modifier.padding(start = 8.dp)
) {
Icon(
imageVector = Icons.Default.ArrowBack,
contentDescription = "Arrow Back",
modifier = Modifier.clickable {
onBack()
}
)
Spacer(modifier = Modifier.width(8.dp))
Text(text = restaurant.name)
}
}
}
) { paddingValues ->
Card(
modifier = Modifier
.padding(paddingValues)
.fillMaxWidth(),
elevation = 2.dp,
shape = RoundedCornerShape(corner = CornerSize(8.dp))
) {
Column(
modifier = Modifier
.padding(16.dp)
.fillMaxWidth()
) {
Text(text = restaurant.name, style = MaterialTheme.typography.h6)
Text(text = restaurant.type, style = MaterialTheme.typography.caption)
Text(text = restaurant.address, style = MaterialTheme.typography.caption)
SelectionContainer {
Text(text = restaurant.website, style = MaterialTheme.typography.caption)
}
Image(painter = painterResource(id = restaurant.drawable), contentDescription = "${restaurant.name}")
}
}
}
}
- Puis, implémentez la cellule de grille et la grille. Dans le fichier
RastaurantCell.kt
, ajoutez l'extrait de code suivant :
RestaurantCell.kt
package com.devrel.deeplinksbasics.ui
import androidx.compose.foundation.Image
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.shape.CornerSize
import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.material.Card
import androidx.compose.material.MaterialTheme
import androidx.compose.material.Text
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import androidx.compose.ui.res.painterResource
import androidx.compose.ui.unit.dp
import com.devrel.deeplinksbasics.data.Restaurant
@Composable
fun RestaurantCell(
restaurant: Restaurant
){
Card(
modifier = Modifier
.padding(horizontal = 8.dp, vertical = 8.dp)
.fillMaxWidth(),
elevation = 2.dp,
shape = RoundedCornerShape(corner = CornerSize(8.dp))
) {
Column(
modifier = Modifier
.padding(16.dp)
.fillMaxWidth()
) {
Text(text = restaurant.name, style = MaterialTheme.typography.h6)
Text(text = restaurant.address, style = MaterialTheme.typography.caption)
Image(painter = painterResource(id = restaurant.drawable), contentDescription = "${restaurant.name}")
}
}
}
- Dans le fichier
RestaurantGrid.kt
, ajoutez l'extrait de code suivant :
RestaurantGrid.kt
package com.devrel.deeplinksbasics.ui
import androidx.compose.foundation.clickable
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.lazy.grid.GridCells
import androidx.compose.foundation.lazy.grid.LazyVerticalGrid
import androidx.compose.foundation.lazy.grid.items
import androidx.compose.material.Scaffold
import androidx.compose.material.Text
import androidx.compose.material.TopAppBar
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.unit.dp
import com.devrel.deeplinksbasics.data.Restaurant
@Composable
fun RestaurantGrid(
restaurants: List<Restaurant>,
onRestaurantSelected: (String) -> Unit,
navigateToRestaurant: (String) -> Unit,
) {
Scaffold(topBar = {
TopAppBar(
backgroundColor = Color.Transparent,
elevation = 0.dp,
) {
Text(text = "Restaurants", fontWeight = FontWeight.Bold)
}
}) { paddingValues ->
LazyVerticalGrid(
columns = GridCells.Adaptive(minSize = 200.dp),
modifier = Modifier.padding(paddingValues)
) {
items(items = restaurants) { restaurant ->
Column(
modifier = Modifier
.fillMaxWidth()
.clickable(onClick = {
onRestaurantSelected(restaurant.name)
navigateToRestaurant(restaurant.name)
})
) {
RestaurantCell(restaurant)
}
}
}
}
}
- Vous devez ensuite implémenter l'état de l'application et la logique de navigation, puis mettre à jour
MainActivity.kt
. Cela permet d'accéder à un restaurant donné lorsque l'utilisateur clique sur la carte correspondante. Dans le fichierRestaurantAppState.kt
, ajoutez l'extrait de code suivant :
RestaurantAppState.kt
package com.devrel.deeplinksbasics.ui
import androidx.compose.runtime.Composable
import androidx.compose.runtime.remember
import androidx.navigation.NavHostController
import androidx.navigation.compose.rememberNavController
sealed class Screen(val route: String) {
object Grid : Screen("restaurants")
object Name : Screen("restaurants/{name}") {
fun createRoute(name: String) = "restaurants/$name"
}
}
@Composable
fun rememberRestaurantAppState(
navController: NavHostController = rememberNavController(),
) = remember(navController) {
RestaurantAppState(navController)
}
class RestaurantAppState(
val navController: NavHostController,
) {
fun navigateToRestaurant(restaurantName: String) {
navController.navigate(Screen.Name.createRoute(restaurantName))
}
fun navigateBack() {
navController.popBackStack()
}
}
- Pour la navigation, vous devez créer le
NavHost
et utiliser les itinéraires des composables pour arriver à chaque restaurant. Dans le fichierRestaurantApp.kt
, ajoutez l'extrait de code suivant :
RestaurantApp.kt
package com.devrel.deeplinksbasics.ui
import androidx.compose.runtime.Composable
import androidx.compose.runtime.collectAsState
import androidx.compose.runtime.getValue
import androidx.lifecycle.viewmodel.compose.viewModel
import androidx.navigation.compose.NavHost
import androidx.navigation.compose.composable
import com.devrel.deeplinksbasics.ui.restaurant.RestaurantViewModel
@Composable
fun RestaurantApp(
viewModel: RestaurantViewModel = viewModel(),
appState: RestaurantAppState = rememberRestaurantAppState(),
) {
val selectedRestaurant by viewModel.selectedRestaurant.collectAsState()
val onRestaurantSelected: (String) -> Unit = { viewModel.updateSelectedRestaurantByName(it) }
NavHost(
navController = appState.navController,
startDestination = Screen.Grid.route,
) {
// Default route that points to the restaurant grid
composable(Screen.Grid.route) {
RestaurantGrid(
restaurants = viewModel.restaurants,
onRestaurantSelected = onRestaurantSelected,
navigateToRestaurant = { restaurantName ->
appState.navigateToRestaurant(restaurantName)
},
)
}
// Route for the navigation to a particular restaurant when a user clicks on it
composable(Screen.Name.route) {
RestaurantCardDetails(restaurant = selectedRestaurant!!, onBack = appState::navigateBack)
}
}
}
- Vous êtes maintenant prêt à mettre à jour
MainActivity.kt
avec l'instance d'application. Remplacez le fichier par le code suivant :
MainActivity .kt
package com.devrel.deeplinksbasics
import android.os.Bundle
import androidx.activity.ComponentActivity
import androidx.activity.compose.setContent
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.material.MaterialTheme
import androidx.compose.material.Surface
import androidx.compose.ui.Modifier
import com.devrel.deeplinksbasics.ui.RestaurantApp
import com.devrel.deeplinksbasics.ui.theme.DeepLinksBasicsTheme
import dagger.hilt.android.AndroidEntryPoint
@AndroidEntryPoint
class MainActivity : ComponentActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContent {
DeepLinksBasicsTheme {
Surface(
modifier = Modifier.fillMaxSize(),
color = MaterialTheme.colors.background
) {
RestaurantApp()
}
}
}
}
}
- Exécutez l'application pour naviguer dans la grille et sélectionner un restaurant donné. Lorsque vous sélectionnez un restaurant, vous constatez que l'application affiche le restaurant en question et ses informations.
Android App Links
Ajoutez maintenant Android App Links à la grille et à chaque restaurant. La section AndroidManifest.xml
de la grille se trouve déjà dans /restaurants
. Fait intéressant, vous pouvez utiliser la même pour chaque restaurant. Il vous suffit d'ajouter une nouvelle configuration d'itinéraire à la logique. Pour ce faire, procédez comme suit :
- Mettre à jour le fichier manifeste avec le filtre d'intent pour recevoir
/restaurants
sous la forme d'un chemin. Pensez à intégrer votre domaine en tant qu'hôte. Dans le fichierAndroidManifest.xml
, ajoutez l'extrait de code suivant :
AndroidManifest.xml
...
<intent-filter android:autoVerify="true">
<action android:name="android.intent.action.VIEW"/>
<category android:name="android.intent.category.BROWSABLE"/>
<category android:name="android.intent.category.DEFAULT"/>
<data android:scheme="http"/>
<data android:scheme="https"/>
<data android:host="your.own.domain"/>
<data android:pathPrefix="/restaurants"/>
</intent-filter>
- Dans le fichier
RestaurantApp.kt
, ajoutez l'extrait de code suivant :
RestaurantApp.kt
...
import androidx.navigation.NavType
import androidx.navigation.navArgument
import androidx.navigation.navDeepLink
fun RestaurantApp(...){
NavHost(...){
...
// Route for the navigation to a particular restaurant when a user clicks on it
// and for an incoming deep link
// Update with your own domain
composable(Screen.Name.route,
deepLinks = listOf(
navDeepLink { uriPattern = "https://your.own.domain/restaurants/{name}" }
),
arguments = listOf(
navArgument("name") {
type = NavType.StringType
}
)
) { entry ->
val restaurantName = entry.arguments?.getString("name")
if (restaurantName != null) {
LaunchedEffect(restaurantName) {
viewModel.updateSelectedRestaurantByName(restaurantName)
}
}
selectedRestaurant?.let {
RestaurantCardDetails(
restaurant = it,
onBack = appState::navigateBack
)
}
}
}
}
En arrière-plan, le NavHost
correspond aux données Uri
de l'intent Android avec les itinéraires composables. Si un itinéraire correspond, le composable
s'affiche.
Le composant composable
peut accepter un paramètre deepLinks
, qui comporte une liste des URI envoyés par le filtre d'intent. Dans cet atelier de programmation, vous devez ajouter l'URL du site Web créé et définir le paramètre d'ID pour recevoir l'information et envoyer l'utilisateur vers le restaurant en question.
- Pour vous assurer que la logique d'application envoie l'utilisateur vers le restaurant après avoir cliqué sur un élément Android App Links, utilisez
adb
:
adb shell am start -W -a android.intent.action.VIEW -d "https://sabs-deeplinks-test.web.app/restaurants/gyrosAndMoar"
Notez que l'application affiche le restaurant en question.
8. Vérifier le tableau de bord de la Play Console
Vous avez déjà examiné le tableau de bord "Deep links" (Liens profonds). Ce tableau de bord fournit toutes les informations nécessaires pour garantir que vos liens profonds fonctionnent correctement. Vous pouvez même connaître la version de l'application ! Il indique les domaines, les liens et les liens personnalisés ajoutés au fichier manifeste. Il précise même quelles informations du fichier assetlinks.json
mettre à jour en cas de problème.
9. Conclusion
Félicitations, vous venez de créer votre première application Android App Links !
Vous connaissez désormais la procédure de conception, de configuration, de création et de test Android App Links. Cette procédure comporte de nombreux aspects. Cet atelier de programmation réunit toutes les informations correspondantes, afin que vous puissiez réussir votre développement d'OS Android.
Vous savez maintenant quelles sont les étapes clés pour qu'Android App Links fonctionne.
Complément d'informations
- Introduction to deep links (Présentation des liens profonds)
- Deep links from Zero to Hero (Les liens profonds de zéro à héros)
- Troubleshooting your deep links (Dépanner vos liens profonds)