Tester les liens vers une application

Lorsque vous implémentez la fonctionnalité d'association d'applications, vous devez tester la fonctionnalité d'association pour vous assurer que le système peut associer votre application à vos sites Web et gérer les requêtes d'URL comme prévu.

Pour tester un fichier de relevé existant, vous pouvez utiliser l'outil Statement List Generator and Tester.

Les sections suivantes décrivent comment tester manuellement la validation des liens d'application. Si vous préférez, vous pouvez tester la validation à partir de l'outil Play Deep Links ou de l'Assistant pour les liens vers des applications Android Studio.

Confirmer la liste des hôtes à valider

Lors des tests, vous devez confirmer la liste des hôtes associés que le système doit vérifier pour votre application. Établissez une liste de toutes les URL dont les filtres d'intent correspondants incluent les attributs et éléments suivants :

  • Attribut android:scheme avec la valeur http ou https
  • Attribut android:host avec un format d'URL de domaine
  • Élément d'action android.intent.action.VIEW
  • Élément de catégorie android.intent.category.BROWSABLE

Utilisez cette liste pour vérifier qu'un fichier JSON Digital Asset Links est fourni sur chaque hôte et sous-domaine nommés.

Confirmer les fichiers Digital Asset Links

Pour chaque site Web, utilisez l'API Digital Asset Links pour vérifier que le fichier JSON Digital Asset Links est correctement hébergé et défini :

https://digitalassetlinks.googleapis.com/v1/statements:list?
   source.web.site=https://<var>domain.name</var>:<var>optional_port</var>&amp;
   relation=delegate_permission/common.handle_all_urls

Pour les liens d'application dynamiques, vous pouvez également vérifier les extensions de relation.

https://digitalassetlinks.googleapis.com/v1/statements:list?source.web.site=https://www.example.com&relation=delegate_permission/common.handle_all_urls&return_relation_extensions=true

Dans le cadre de votre processus de test, vous pouvez vérifier les paramètres système actuels pour la gestion des liens. Utilisez la commande suivante pour obtenir la liste des règles de gestion des liens existantes pour toutes les applications sur votre appareil connecté :

adb shell dumpsys package domain-preferred-apps

La commande suivante fait la même chose :

adb shell dumpsys package d

La commande renvoie la liste de chaque utilisateur ou profil défini sur l'appareil, précédée d'un en-tête au format suivant :

App linkages for user 0:

Sous cet en-tête, la sortie utilise le format suivant pour lister les paramètres de gestion des liens pour cet utilisateur :

Package: com.android.vending
Domains: play.google.com market.android.com
Status: always : 200000002

Cette liste indique les applications associées à chaque domaine pour cet utilisateur :

  • Package : identifie une application par son nom de package, tel qu'il est déclaré dans son fichier manifeste.
  • Domains : affiche la liste complète des hôtes dont cette application gère les liens Web, en utilisant des espaces comme délimiteurs.
  • Status : affiche le paramètre actuel de gestion des liens pour cette application. Une application qui a réussi la validation et dont le fichier manifeste contient android:autoVerify="true" affiche l'état always. Le nombre hexadécimal qui suit cet état est lié à l'enregistrement par le système Android des préférences de l'utilisateur concernant l'association d'applications. Cette valeur n'indique pas si la validation a réussi.

Exemple de test

Pour que la validation des liens d'application réussisse, le système doit pouvoir valider votre application avec chacun des sites Web que vous spécifiez dans un filtre d'intent donné qui répond aux critères des liens d'application. L'exemple suivant montre une configuration de fichier manifeste avec plusieurs liens d'application définis :

<activity android:name="MainActivity">
        <intent-filter android:autoVerify="true">
            <action android:name="android.intent.action.VIEW" />
            <category android:name="android.intent.category.DEFAULT" />
            <category android:name="android.intent.category.BROWSABLE" />
            <data android:scheme="https" />
            <data android:scheme="https" />
            <data android:host="www.example.com" />
            <data android:host="mobile.example.com" />
        </intent-filter>
        <intent-filter>
            <action android:name="android.intent.action.VIEW" />
            <category android:name="android.intent.category.BROWSABLE" />
            <data android:scheme="https" />
            <data android:host="www.example2.com" />
        </intent-filter>
    </activity>

    <activity android:name="SecondActivity">
        <intent-filter>
            <action android:name="android.intent.action.VIEW" />
            <category android:name="android.intent.category.DEFAULT" />
            <category android:name="android.intent.category.BROWSABLE" />
            <data android:scheme="https" />
            <data android:host="account.example.com" />
        </intent-filter>
    </activity>

      <activity android:name="ThirdActivity">
        <intent-filter>
            <action android:name="android.intent.action.VIEW" />
            <category android:name="android.intent.category.DEFAULT" />
            <data android:scheme="https" />
            <data android:host="map.example.com" />
        </intent-filter>
        <intent-filter>
            <action android:name="android.intent.action.VIEW" />
            <category android:name="android.intent.category.BROWSABLE" />
            <data android:scheme="market" />
            <data android:host="example.com" />
        </intent-filter>
      </activity>

</application>

Voici la liste des hôtes que la plate-forme tenterait de valider à partir du fichier manifeste précédent :

www.example.com
mobile.example.com
www.example2.com
account.example.com

Voici la liste des hôtes que la plate-forme ne tentera pas de valider à partir du fichier manifeste précédent :

map.example.com (it does not have android.intent.category.BROWSABLE)
market://example.com (it does not have either an "http" or "https" scheme)

Pour en savoir plus sur les listes d'instructions, consultez Créer une liste d'instructions.

À partir d'Android 17, vous pouvez utiliser l'indicateur --debug-link avec la commande du gestionnaire d'activités (am start) pour diagnostiquer la façon dont le système résout une URL spécifique. Cet outil fournit une analyse détaillée des applications candidates qui correspondent à l'intention, ainsi que les règles spécifiques du fichier manifeste de l'application et du fichier assetlinks.json (pour les liens d'application dynamiques) qui ont été évaluées lors de la résolution.

Pour tester la résolution des liens pour une URL spécifique, exécutez la commande suivante dans une fenêtre de terminal :

adb shell am start --debug-link -a android.intent.action.VIEW -d "https://xyz.com/foo"

Le résultat du diagnostic est imprimé sous l'en-tête App Link Resolution Debug et contient les sections suivantes pour vous aider à comprendre le processus de résolution :

  • Détails de la cible : identifie chaque application candidate correspondante par son nom de package et son activité cible.
  • Correspondance du filtre d'intent (AndroidManifest.xml) : indique les attributs statiques du filtre d'intent du fichier manifeste (tels que scheme, host, path, pathPrefix ou pathPattern) qui correspondent à l'URI.
  • Validation des liens vers l'application : affiche l'état actuel de la validation du domaine (par exemple, STATE_SUCCESS).
  • Liens d'application dynamiques : si l'application utilise des règles de correspondance pour les liens d'application dynamiques dans son fichier assetlinks.json, cette section liste chaque règle qui a été évaluée par rapport à l'URI. Chaque règle indique les filtres d'URI correspondants (tels que les préfixes ou les modèles de chemin d'accès) et un champ allow :
    • allow = 0 : règle d'autorisation/d'inclusion (allow: true). Si cette règle correspond, l'application est autorisée à ouvrir l'URI.
    • allow = 1 : règle de blocage/d'exclusion (allow: false / exclude: true). Si cette règle correspond, l'application ne peut pas ouvrir l'URI.
    • Remarque : Une chaîne de filtre vide (filter =) indique un préfixe de chemin vide qui correspond à tous les chemins du domaine (agissant comme un caractère générique ou un filtre général).

Exemple de résultat de débogage

Prenons l'exemple d'une application (com.example.xyzapp) associée au domaine https://xyz.com qui définit des règles dynamiques dans son fichier assetlinks.json pour exclure /foo* tout en autorisant tous les autres chemins :

[
  {
    "relation": [
      "delegate_permission/common.handle_all_urls"
    ],
    "target": {
      "namespace": "android_app",
      "package_name": "com.example.xyzapp",
      "sha256_cert_fingerprints": ["..."]
    },
    "relation_extensions": {
      "delegate_permission/common.handle_all_urls": {
        "dynamic_app_link_components": [
          {"/": "/foo*", "exclude": true},
          {"/": "*"}
        ]
      }
    }
  }
]

Lorsque vous diagnostiquez l'URL https://xyz.com/foo à l'aide de --debug-link :

adb shell am start --debug-link -a android.intent.action.VIEW -d "https://xyz.com/foo"

La commande génère la répartition des diagnostics suivante :

--- App Link Resolution Debug ---

URI: https://xyz.com/foo
Resolution: Ambiguous (Multiple apps or Browser fallback)
This usually happens when multiple apps can handle the link and no default is set.

All Matching Candidates:

Target:
  Package: com.example.xyzapp
  Activity: com.example.xyzapp.MainActivity

  Intent Filter Match (AndroidManifest.xml)
    Scheme: 'https' matched android:scheme="https"
    Host: 'xyz.com' matched android:host="xyz.com"

App Link Verification:
  Verification status: STATE_SUCCESS
  Dynamic App Links:
    -> Matched Rule 0: UriRelativeFilterGroup { allow = 1, uri_filters = {UriRelativeFilter { uriPart = PATH, patternType = PREFIX, filter = /foo }},  }
    -> Matched Rule 1: UriRelativeFilterGroup { allow = 0, uri_filters = {UriRelativeFilter { uriPart = PATH, patternType = PREFIX, filter =  }},  }

Target:
  Package: org.chromium.webview_shell
  Activity: org.chromium.webview_shell.WebViewBrowserActivity

  Intent Filter Match (AndroidManifest.xml)
    Scheme: 'https' matched android:scheme="https"

---------------------------------

Starting: Intent { act=android.intent.action.VIEW dat=https://xyz.com/foo }

Dans cet exemple, le système a évalué les deux règles de liens dynamiques vers l'application à partir de assetlinks.json :

  • Règle 0 (allow = 1, filter = /foo) : générée à partir de {"/": "/foo*", "exclude": true}, il s'agit d'une règle d'exclusion (allow: false) qui bloque les URL commençant par le préfixe de chemin d'accès /foo.
  • Règle 1 (allow = 0, filter =) : générée à partir de {"/": "*"}, il s'agit d'une règle d'inclusion (allow: true) avec un préfixe de chemin vide (filter =), qui correspond à tous les chemins sous xyz.com (règle générique).

Fonctionnement de la résolution dans ce scénario :

  1. Les règles 0 et 1 correspondent toutes les deux à l'URL https://xyz.com/foo.
  2. Les règles de liens d'application dynamiques sont évaluées l'une après l'autre, de haut en bas (la première règle correspondante est appliquée).
  3. Comme la règle 0 apparaît en premier dans la liste des instructions et qu'il s'agit d'une règle d'exclusion (allow = 1), elle est prioritaire sur la règle d'autorisation générale (règle 1).
  4. L'application est donc exclue de la gestion de https://xyz.com/foo, ce qui entraîne le retour du système au navigateur ou l'affichage d'une boîte de dialogue de clarification.