App-Links testen

Wenn Sie die Funktion für App-Links implementieren, sollten Sie die Verknüpfungsfunktion testen, um sicherzustellen, dass das System Ihre App Ihren Websites zuordnen und URL-Anfragen wie erwartet verarbeiten kann.

Wenn Sie eine vorhandene Statement-Datei testen möchten, können Sie das Tool Statement List Generator and Tester verwenden.

In den folgenden Abschnitten wird beschrieben, wie Sie die Bestätigung von App-Links manuell testen. Alternativ können Sie die Bestätigung über das Tool Play Deep Links oder den App-Link-Assistenten in Android Studio testen.

Liste der zu bestätigenden Hosts bestätigen

Beim Testen sollten Sie die Liste der zugehörigen Hosts bestätigen, die das System für Ihre App bestätigen soll. Erstellen Sie eine Liste aller URLs, deren entsprechende Intent-Filter die folgenden Attribute und Elemente enthalten:

  • Attribut android:scheme mit dem Wert http oder https
  • Attribut android:host mit einem Domain-URL-Muster
  • Aktionselement android.intent.action.VIEW
  • Kategorieelement android.intent.category.BROWSABLE

Anhand dieser Liste können Sie prüfen, ob auf jedem genannten Host und jeder genannten Subdomain eine Digital Asset Links-JSON-Datei vorhanden ist.

Digital Asset Links-Dateien bestätigen

Bestätigen Sie für jede Website mit der Digital Asset Links API, dass die Digital Asset Links-JSON-Datei ordnungsgemäß gehostet und definiert ist:

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

Bei dynamischen App-Links können Sie auch die Beziehungserweiterungen prüfen.

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

Im Rahmen des Testprozesses können Sie die aktuellen Systemeinstellungen für die Linkverarbeitung prüfen. Verwenden Sie den folgenden Befehl, um eine Liste der vorhandenen Richtlinien zur Linkverarbeitung für alle Apps auf Ihrem verbundenen Gerät abzurufen:

adb shell dumpsys package domain-preferred-apps

Der folgende Befehl bewirkt dasselbe:

adb shell dumpsys package d

Der Befehl gibt eine Liste der einzelnen Nutzer oder Profile zurück, die auf dem Gerät definiert sind. Vorangestellt ist ein Header im folgenden Format:

App linkages for user 0:

Nach diesem Header wird in der Ausgabe das folgende Format verwendet, um die Einstellungen für die Linkverarbeitung für diesen Nutzer aufzulisten:

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

In dieser Liste ist angegeben, welche Apps für diesen Nutzer mit welchen Domains verknüpft sind:

  • Package : Identifiziert eine App anhand ihres Paketnamens, wie im Manifest deklariert.
  • Domains : Enthält die vollständige Liste der Hosts, deren Weblinks von dieser App verarbeitet werden. Die einzelnen Hosts sind durch Leerzeichen getrennt.
  • Status : Zeigt die aktuelle Einstellung für die Linkverarbeitung für diese App an. Für eine App, die die Bestätigung bestanden hat und deren Manifest android:autoVerify="true" enthält, wird der Status always angezeigt. Die Hexadezimalzahl nach diesem Status bezieht sich auf den Eintrag des Android-Systems zu den Einstellungen des Nutzers für die App-Verknüpfung. Dieser Wert gibt nicht an, ob die Bestätigung erfolgreich war.

Testbeispiel

Damit die Bestätigung von App-Links erfolgreich ist, muss das System Ihre App mit jeder der Websites bestätigen können, die Sie in einem bestimmten Intent-Filter angeben, der die Kriterien für App-Links erfüllt. Das folgende Beispiel zeigt eine Manifestkonfiguration mit mehreren definierten App-Links:

<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>

Die Liste der Hosts, die die Plattform anhand des vorherigen Manifests bestätigen würde, sieht so aus:

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

Die Liste der Hosts, die die Plattform anhand des vorherigen Manifests nicht bestätigen würde, sieht so aus:

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

Weitere Informationen zu Statement-Listen finden Sie unter Statement-Liste erstellen.

Ab Android 17 können Sie das Flag --debug-link mit dem Befehl des Aktivitätsmanagers (am start) verwenden, um zu diagnostizieren, wie das System eine bestimmte URL auflöst. Dieses Tool bietet eine detaillierte Aufschlüsselung der Kandidaten-Apps, die dem Intent entsprochen haben, sowie der spezifischen Regeln aus dem App-Manifest und der Datei assetlinks.json (für dynamische App-Links), die während der Auflösung ausgewertet wurden.

Wenn Sie die Linkauflösung für eine bestimmte URL testen möchten, führen Sie den folgenden Befehl in einem Terminalfenster aus:

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

Die Diagnoseausgabe wird unter dem Header App Link Resolution Debug ausgegeben und enthält die folgenden Abschnitte, die Ihnen helfen, den Auflösungsprozess zu verstehen:

  • Target details:Identifiziert jede übereinstimmende Kandidaten-App anhand ihres Paketnamens und der Zielaktivität.
  • Intent Filter Match (AndroidManifest.xml): Zeigt, welche statischen Attribute im Manifest-Intent-Filter (z. B. scheme, host, path, pathPrefix oder pathPattern) mit dem URI übereinstimmen.
  • App-Link-Bestätigung:Zeigt den aktuellen Status der Domainbestätigung an (z. B. STATE_SUCCESS).
  • Dynamic App Links:Wenn die App in ihrer Datei assetlinks.json Regeln für dynamische App-Links verwendet, werden in diesem Abschnitt alle Regeln aufgeführt, die für den URI ausgewertet wurden. Für jede Regel werden die übereinstimmenden URI-Filter (z. B. Pfadpräfixe oder -muster) und ein Feld allow angegeben:
    • allow = 0: Eine Zulassungs-/Einschlussregel (allow: true). Wenn diese Regel übereinstimmt, darf die App den URI öffnen.
    • allow = 1: Eine Blockierungs-/Ausschlussregel (allow: false / exclude: true). Wenn diese Regel übereinstimmt, kann die App den URI nicht öffnen.
    • Hinweis: Eine leere Filterstring (filter =) gibt ein leeres Pfad präfix an, das mit allen Pfaden unter der Domain übereinstimmt (als Platzhalter oder Catch-all).

Beispiel für eine Debugausgabe

Nehmen wir an, eine App (com.example.xyzapp) ist mit der Domain https://xyz.com verknüpft und definiert in ihrer Datei assetlinks.json dynamische Regeln, um /foo* auszuschließen, während alle anderen Pfade zugelassen werden:

[
  {
    "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},
          {"/": "*"}
        ]
      }
    }
  }
]

Wenn Sie die URL https://xyz.com/foo mit --debug-link diagnostizieren:

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

Der Befehl gibt die folgende Diagnoseaufschlüsselung aus:

--- 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 }

In diesem Beispiel hat das System die beiden Regeln für dynamische App-Links aus assetlinks.json ausgewertet:

  • Regel 0 (allow = 1, filter = /foo): Diese Regel wurde aus {"/": "/foo*", "exclude": true} generiert und ist eine Ausschlussregel (allow: false), die URLs blockiert, die mit dem /foo Pfadpräfix beginnen.
  • Regel 1 (allow = 0, filter =): Diese Regel wurde aus {"/": "*"} generiert und ist eine Einschlussregel (allow: true) mit einem leeren Pfadpräfix (filter =), die mit allen Pfaden unter xyz.com übereinstimmt (Catch-all).

So funktioniert die Auflösung in diesem Szenario :

  1. Sowohl Regel 0 als auch Regel 1 stimmen mit der URL https://xyz.com/foo überein.
  2. Regeln für dynamische App-Links werden der Reihe nach von oben nach unten ausgewertet (die erste übereinstimmende Regel wird angewendet).
  3. Da Regel 0 in der Statement-Liste zuerst aufgeführt wird und eine Ausschlussregel (allow = 1) ist, hat sie Vorrang vor der allgemeinen Zulassungsregel (Regel 1).
  4. Die App wird daher von der Verarbeitung von https://xyz.com/foo ausgeschlossen, sodass das System auf den Browser zurückgreift oder ein Dialogfeld zur Auswahl anzeigt.