Тестирование ссылок на приложение

При реализации функции связывания приложений необходимо протестировать ее, чтобы убедиться, что система может связать ваше приложение с вашими сайтами и обрабатывать запросы URL так, как вы ожидаете.

Чтобы проверить существующий файл манифеста, воспользуйтесь инструментом для создания и тестирования списка манифестов.

В разделах ниже описано, как вручную протестировать проверку ссылок на приложение. Вы также можете протестировать проверку с помощью инструмента "Ссылки на контент" в Play Console или App Links Assistant в Android Studio.

Подтвердите список хостов для проверки

При тестировании необходимо подтвердить список связанных хостов, которые система должна проверить для вашего приложения. Составьте список всех URL, фильтры интентов которых включают следующие атрибуты и элементы:

  • Атрибут android:scheme со значением http или https.
  • Атрибут android:host с шаблоном URL домена
  • android.intent.action.VIEW элемент действия
  • Элемент категории "android.intent.category.BROWSABLE"

Используйте этот список, чтобы проверить, есть ли файл JSON протокола связи цифровых объектов на каждом указанном хосте и субдомене.

Проверьте файлы протокола связи цифровых объектов

Для каждого сайта используйте Digital Asset Links API, чтобы убедиться, что файл JSON протокола связи цифровых объектов правильно размещен и определен.

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

Для динамических ссылок на приложения можно также проверить расширения отношений.

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

В рамках тестирования вы можете проверить текущие системные настройки обработки ссылок. Чтобы получить список существующих правил обработки ссылок для всех приложений на подключенном устройстве, используйте следующую команду:

adb shell dumpsys package domain-preferred-apps

Следующая команда делает то же самое:

adb shell dumpsys package d

Команда возвращает список всех пользователей или профилей, определенных на устройстве, перед которым находится заголовок в следующем формате:

App linkages for user 0:

После этого заголовка в выходных данных используется следующий формат для перечисления настроек обработки ссылок для этого пользователя:

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

В этом списке указано, какие приложения связаны с какими доменами для этого пользователя:

  • Package – идентифицирует приложение по названию пакета, указанному в манифесте.
  • Domains – показывает полный список хостов, веб-ссылки которых обрабатывает это приложение. В качестве разделителей используются пробелы.
  • Status – показывает текущую настройку обработки ссылок для этого приложения. Если приложение прошло проверку и его манифест содержит android:autoVerify="true", будет показан статус always. Шестнадцатеричное число после этого статуса связано с записью в системе Android о предпочтениях пользователя в отношении связывания приложений. Это значение не указывает, была ли проверка успешной.

Пример теста

Чтобы проверка ссылок на приложение прошла успешно, система должна иметь возможность проверить ваше приложение на каждом из сайтов, указанных в фильтре интентов, который соответствует критериям для ссылок на приложение. Ниже приведен пример конфигурации манифеста с несколькими ссылками на приложение.

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

Список хостов, которые платформа попытается проверить на основе приведенного выше манифеста:

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

Список хостов, которые платформа не будет пытаться проверить на основе приведенного выше манифеста:

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

Подробнее о создании списка деклараций…

Начиная с Android 17 вы можете использовать флаг --debug-link с командой менеджера действий (am start), чтобы диагностировать, как система разрешает определенный URL. Инструмент предоставляет подробную информацию о приложениях-кандидатах, соответствующих намерению, а также о конкретных правилах из манифеста приложения и файла assetlinks.json (для динамических ссылок на контент), которые оценивались в процессе разрешения.

Чтобы проверить разрешение ссылок для определенного URL, выполните в окне терминала следующую команду:

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

Выходные данные диагностики выводятся под заголовком App Link Resolution Debug и содержат следующие разделы, которые помогут вам понять процесс разрешения:

  • Сведения о цели. Идентифицирует каждое подходящее приложение-кандидат по названию пакета и целевому действию.
  • Соответствие фильтру интентов (AndroidManifest.xml). Показывает, какие статические атрибуты в фильтре интентов манифеста (например, scheme, host, path, pathPrefix или pathPattern) соответствуют URI.
  • Проверка ссылок на приложение. Показывает текущий статус проверки домена, например STATE_SUCCESS.
  • Динамические ссылки на приложение. Если в файле assetlinks.json приложения используются правила сопоставления динамических ссылок на приложение, в этом разделе перечислены все правила, которые были проверены на соответствие URI. Каждое правило содержит фильтры URI (например, префиксы или шаблоны путей) и поле allow:
    • allow = 0 – правило разрешения/включения (allow: true). Если оно выполняется, приложению разрешено открывать URI.
    • allow = 1 – правило блокировки/исключения (allow: false / exclude: true). Если оно выполняется, приложение не может открыть URI.
    • Примечание. Пустая строка фильтра (filter =) означает пустой префикс пути, который соответствует всем путям в домене (действует как подстановочный знак или универсальный символ).

Пример выходных данных отладки

Предположим, что приложение (com.example.xyzapp) связано с доменом https://xyz.com, в файле assetlinks.json которого заданы динамические правила, исключающие /foo* и разрешающие все остальные пути:

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

При диагностике URL https://xyz.com/foo с помощью --debug-link:

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

Результат выполнения команды содержит следующие диагностические данные:

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

В этом примере система оценила два правила динамических ссылок на приложение из assetlinks.json:

  • Правило 0 (allow = 1, filter = /foo). Создано на основе {"/": "/foo*", "exclude": true}. Это правило исключения (allow: false), блокирующее URL, которые начинаются с префикса пути /foo.
  • Правило 1 (allow = 0, filter =). Создано на основе {"/": "*"}. Это правило включения (allow: true) с пустым префиксом пути (filter =), которое соответствует всем путям в xyz.com (универсальное правило).

Как работает разрешение в этом сценарии:

  1. Правило 0 и правило 1 соответствуют URL https://xyz.com/foo.
  2. Правила динамических ссылок на приложения оцениваются по порядку сверху вниз (применяется первое подходящее правило).
  3. Поскольку правило 0 указано в списке первым и является правилом исключения (allow = 1), оно имеет приоритет над общим правилом разрешения (правило 1).
  4. Поэтому приложение не может обрабатывать https://xyz.com/foo, и система открывает браузер или показывает диалоговое окно для устранения неоднозначности.