Testowanie linków aplikacji

Podczas wdrażania funkcji połączenia z aplikacją przetestuj funkcję połączenia, aby upewnić się, że system może powiązać aplikację z witrynami i obsługiwać żądania adresów URL zgodnie z oczekiwaniami.

Aby przetestować istniejący plik stanu, możesz użyć narzędzia Statement List Generator and Tester.

W sekcjach poniżej opisano, jak ręcznie przetestować weryfikację linków aplikacji. Jeśli wolisz, możesz przetestować weryfikację za pomocą narzędzia Precyzyjne linki w Google Play lub Asystenta linków do aplikacji w Android Studio.

Potwierdzanie listy hostów do zweryfikowania

Podczas testowania należy potwierdzić listę powiązanych hostów, które system powinien zweryfikować pod kątem aplikacji. Utwórz listę wszystkich adresów URL, których odpowiednie filtry intencji zawierają te atrybuty i elementy:

  • Atrybut android:scheme z wartością http lub https
  • Atrybut android:host ze wzorcem adresu URL domeny
  • android.intent.action.VIEW element działania
  • Element kategorii android.intent.category.BROWSABLE

Użyj tej listy, aby sprawdzić, czy plik JSON protokołu Digital Asset Links jest dostępny na każdym nazwanym hoście i w każdej nazwanej subdomenie.

Potwierdzanie plików Digital Asset Links

W przypadku każdej witryny użyj interfejsu Digital Asset Links API, aby sprawdzić, czy plik JSON protokołu Digital Asset Links jest prawidłowo hostowany i zdefiniowany:

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

W przypadku dynamicznych linków do aplikacji możesz też sprawdzić rozszerzenia relacji.

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

W ramach procesu testowania możesz sprawdzić bieżące ustawienia systemowe dotyczące obsługi linków. Aby wyświetlić listę istniejących zasad obsługi linków dla wszystkich aplikacji na połączonym urządzeniu, użyj tego polecenia:

adb shell dumpsys package domain-preferred-apps

To samo robi to polecenie:

adb shell dumpsys package d

Polecenie zwraca listę wszystkich użytkowników lub profili zdefiniowanych na urządzeniu, poprzedzoną nagłówkiem w tym formacie:

App linkages for user 0:

Po tym nagłówku dane wyjściowe mają następujący format, w którym wyświetlane są ustawienia obsługi linków dla tego użytkownika:

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

Ta lista wskazuje, które aplikacje są powiązane z którymi domenami tego użytkownika:

  • Package – identyfikuje aplikację według nazwy pakietu zadeklarowanej w pliku manifestu.
  • Domains – pokazuje pełną listę hostów, których linki internetowe są obsługiwane przez tę aplikację, używając spacji jako separatorów.
  • Status – pokazuje bieżące ustawienie obsługi linków w tej aplikacji. Aplikacja, która przeszła weryfikację i której plik manifestu zawiera android:autoVerify="true", ma stan always. Liczba szesnastkowa po tym stanie jest powiązana z zapisem w systemie Android dotyczącym preferencji użytkownika dotyczących połączeń z aplikacją. Ta wartość nie wskazuje, czy weryfikacja się powiodła.

Przykładowy test

Aby weryfikacja linków do aplikacji się powiodła, system musi mieć możliwość zweryfikowania aplikacji w każdej witrynie określonej w danym filtrze intencji, który spełnia kryteria linków do aplikacji. Poniższy przykład pokazuje konfigurację pliku manifestu z kilkoma zdefiniowanymi linkami do aplikacji:

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

Lista hostów, które platforma spróbuje zweryfikować na podstawie poprzedniego pliku manifestu:

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

Lista hostów, których platforma nie będzie próbowała zweryfikować na podstawie poprzedniego pliku manifestu:

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

Więcej informacji o listach instrukcji znajdziesz w artykule Tworzenie listy instrukcji.

Począwszy od Androida 17, możesz używać flagi --debug-link z poleceniem menedżera aktywności (am start), aby diagnozować, jak system rozpoznaje konkretny adres URL. To narzędzie udostępnia szczegółowe zestawienie aplikacji kandydujących, które pasowały do intencji, wraz z konkretnymi regułami z pliku manifestu aplikacji i pliku assetlinks.json (w przypadku dynamicznych linków do aplikacji), które zostały ocenione podczas rozwiązywania problemu.

Aby przetestować rozpoznawanie linków dla konkretnego adresu URL, uruchom w oknie terminala to polecenie:

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

Dane wyjściowe diagnostyki są wyświetlane pod nagłówkiem App Link Resolution Debug i zawierają te sekcje, które pomogą Ci zrozumieć proces rozwiązywania problemu:

  • Szczegóły celu: identyfikuje każdą pasującą aplikację kandydującą według nazwy pakietu i aktywności docelowej.
  • Dopasowanie filtra intencji (AndroidManifest.xml): pokazuje, które atrybuty statyczne w filtrze intencji pliku manifestu (takie jak scheme, host, path, pathPrefix lub pathPattern) pasują do identyfikatora URI.
  • Weryfikacja linku do aplikacji:pokazuje bieżący stan weryfikacji domeny (np. STATE_SUCCESS).
  • Dynamiczne linki do aplikacji: jeśli aplikacja używa reguł dopasowywania dynamicznych linków do aplikacji w pliku assetlinks.json, w tej sekcji znajdziesz wszystkie reguły, które zostały ocenione pod kątem identyfikatora URI. Każda reguła wskazuje dopasowane filtry identyfikatorów URI (takie jak prefiksy lub wzorce ścieżek) oraz pole allow:
    • allow = 0: reguła zezwalania/uwzględniania (allow: true). Jeśli ta reguła jest spełniona, aplikacja może otworzyć identyfikator URI.
    • allow = 1: reguła blokowania/wykluczania (allow: false / exclude: true). Jeśli ta reguła jest zgodna, aplikacja nie może otworzyć identyfikatora URI.
    • Uwaga: pusty ciąg znaków filtra (filter =) oznacza pusty prefiks ścieżki, który pasuje do wszystkich ścieżek w domenie (działa jako symbol wieloznaczny lub uniwersalny).

Przykładowe dane wyjściowe debugowania

Rozważmy aplikację (com.example.xyzapp) powiązaną z domeną https://xyz.com, która definiuje reguły dynamiczne w pliku assetlinks.json, aby wykluczyć /foo*, zezwalając jednocześnie na wszystkie inne ścieżki:

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

Podczas diagnozowania adresu URL https://xyz.com/foo za pomocą narzędzia --debug-link:

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

Wynik polecenia zawiera następujące dane diagnostyczne:

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

W tym przykładzie system ocenił 2 reguły dynamicznych linków aplikacji z assetlinks.json:

  • Reguła 0 (allow = 1, filter = /foo): wygenerowana na podstawie {"/": "/foo*", "exclude": true}. Jest to reguła wykluczająca (allow: false) blokująca adresy URL zaczynające się od prefiksu ścieżki /foo.
  • Reguła 1 (allow = 0, filter =): wygenerowana na podstawie {"/": "*"}. Jest to reguła uwzględniania (allow: true) z pustym prefiksem ścieżki (filter =), która pasuje do wszystkich ścieżek w domenie xyz.com (reguła ogólna).

Jak działa rozwiązywanie problemów w tym scenariuszu:

  1. Zarówno reguła 0, jak i reguła 1 pasują do adresu URL https://xyz.com/foo.
  2. Reguły dynamicznych linków do aplikacji są oceniane po kolei od góry do dołu (stosowana jest pierwsza pasująca reguła).
  3. Ponieważ Reguła 0 pojawia się jako pierwsza na liście instrukcji i jest regułą wykluczającą (allow = 1), ma pierwszeństwo przed ogólną regułą zezwalającą (Reguła 1).
  4. Aplikacja nie może więc obsługiwać linków https://xyz.com/foo, co powoduje, że system wraca do przeglądarki lub wyświetla okno uściślania.