Проверьте ссылки на приложения Android

Ссылка на приложение Android — это особый тип глубокой ссылки, который позволяет URL-адресам вашего веб-сайта немедленно открывать соответствующий контент в вашем приложении Android, не требуя от пользователя выбора приложения. Ссылки на приложения Android используют API ссылок на цифровые активы, чтобы убедиться в том, что ваше приложение одобрено веб-сайтом, и автоматически открывать ссылки для этого домена. Если система успешно подтвердит, что вы являетесь владельцем URL-адресов, она автоматически перенаправит эти URL-адреса в ваше приложение.

Чтобы убедиться, что вы являетесь владельцем URL-адресов приложения и веб-сайта, выполните следующие действия:

  1. Добавьте фильтры намерений , содержащие атрибут autoVerify . Этот атрибут сигнализирует системе, что она должна проверить, принадлежит ли ваше приложение к доменам URL, используемым в ваших фильтрах намерений.

  2. Объявите связь между вашим веб-сайтом и фильтрами намерений, разместив JSON-файл ссылок на цифровые активы в следующем месте:

    https://domain.name/.well-known/assetlinks.json

Соответствующую информацию вы можете найти на следующих ресурсах:

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

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

<!-- Make sure you explicitly set android:autoVerify to "true". -->
<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" />

    <!-- If a user clicks on a shared link that uses the "http" scheme, your
         app should be able to delegate that traffic to "https". -->
    <data android:scheme="http" />
    <data android:scheme="https" />

    <!-- Include one or more domains that should be verified. -->
    <data android:host="..." />
</intent-filter>

Хотя достаточно включить autoVerify только в одно объявление <intent-filter> для каждого хоста, даже если этот хост используется в других немаркированных объявлениях, для обеспечения согласованности рекомендуется добавлять autoVerify в каждый элемент <intent-filter> . Это также гарантирует, что после удаления или рефакторинга элементов в файле манифеста ваше приложение останется связанным со всеми доменами, которые вы все еще определяете.

Процесс проверки домена требует подключения к Интернету и может занять некоторое время. Чтобы повысить эффективность процесса, система проверяет домен на наличие приложения, предназначенного для Android 12 или более поздней версии, только если этот домен находится внутри элемента <intent-filter> , который содержит точный формат, указанный в предыдущем фрагменте кода.

Поддержка связывания приложений для нескольких хостов

Система должна иметь возможность проверять хост, указанный в элементах данных фильтров намерений URL-адресов приложения, по файлам ссылок на цифровые активы, размещенным на соответствующих веб-доменах в этом фильтре намерений. Если проверка не пройдена, система по умолчанию использует стандартное поведение для разрешения намерения, как описано в разделе «Создание глубоких ссылок на контент приложения» . Однако приложение по-прежнему можно проверить как обработчик по умолчанию для любого шаблона URL-адреса, определенного в других фильтрах намерений приложения.

Примечание. В Android 11 (уровень API 30) и более ранних версиях система не проверяет ваше приложение в качестве обработчика по умолчанию, пока не найдет соответствующий файл ссылок на цифровые активы для всех хостов, которые вы определяете в манифесте.

Например, приложение со следующими фильтрами намерений пройдет проверку только для https://www.example.com , если файл assetlinks.json будет найден по адресу https://www.example.com/.well-known/assetlinks.json , но не https://www.example.net/.well-known/assetlinks.json :

<application>

  <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="http" />
      <data android:scheme="https" />
      <data android:host="www.example.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="www.example.net" />
    </intent-filter>
  </activity>

</application>

Примечание. Все элементы <data> в одном фильтре намерений объединяются вместе, чтобы учесть все варианты их объединенных атрибутов. Например, первый фильтр намерений, приведенный выше, включает элемент <data> , который объявляет только схему HTTPS. Но он объединен с другим элементом <data> , поэтому фильтр намерений поддерживает как http://www.example.com , так и https://www.example.com . Таким образом, вам необходимо создать отдельные фильтры намерений, если вы хотите определить определенные комбинации схем URI и доменов.

Поддержка связывания приложений для нескольких поддоменов

Протокол Digital Asset Links рассматривает субдомены в ваших фильтрах намерений как уникальные отдельные хосты. Поэтому, если в вашем фильтре намерений указано несколько хостов с разными поддоменами, вы должны опубликовать действительный assetlinks.json для каждого домена. Например, следующий фильтр намерений включает www.example.com и mobile.example.com в качестве принятых хостов URL-адресов намерений. Таким образом, действительный assetlinks.json должен быть опубликован как на https://www.example.com/.well-known/assetlinks.json , так и https://mobile.example.com/.well-known/assetlinks.json .

<application>
  <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>
  </activity>
</application>

Альтернативно, если вы объявляете свое имя хоста с подстановочным знаком (например, *.example.com ), вы должны опубликовать файл assetlinks.json в корневом имени хоста ( example.com ). Например, приложение со следующим фильтром намерений пройдет проверку для любого подимени example.com (например, foo.example.com ), если файл assetlinks.json опубликован по адресу https://example.com/.well-known/assetlinks.json :

<application>
  <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:host="*.example.com" />
    </intent-filter>
  </activity>
</application>

Проверьте наличие нескольких приложений, связанных с одним и тем же доменом

Если вы публикуете несколько приложений, каждое из которых связано с одним и тем же доменом, каждое из них можно успешно проверить. Однако если приложения могут разрешать один и тот же хост и путь домена, как это может быть в случае с облегченной и полной версиями приложения, только приложение, которое было установлено последним, может определять веб-намерения для этого домена.

В таком случае проверьте наличие возможных конфликтующих приложений на устройстве пользователя при условии, что у вас есть необходимая видимость пакета . Затем в своем приложении покажите настраиваемый диалог выбора, содержащий результаты вызова queryIntentActivities() . Пользователь может выбрать предпочитаемое приложение из списка подходящих приложений, который появляется в диалоговом окне.

Объявить ассоциации веб-сайтов

На вашем веб-сайте необходимо опубликовать JSON-файл ссылок на цифровые активы, чтобы указать приложения Android, связанные с веб-сайтом, и проверить намерения URL-адреса приложения. В файле JSON используются следующие поля для идентификации связанных приложений:

  • package_name : идентификатор приложения , объявленный в файле build.gradle приложения.
  • sha256_cert_fingerprints : отпечатки SHA256 сертификата подписи вашего приложения. Вы можете использовать следующую команду для создания отпечатка пальца с помощью Java keytool:
    keytool -list -v -keystore my-release-key.keystore
    
    Это поле поддерживает несколько отпечатков пальцев, которые можно использовать для поддержки различных версий вашего приложения, например отладочных и рабочих сборок.

    Если вы используете подпись приложения Play для своего приложения, то отпечаток сертификата, созданный при локальном запуске keytool , обычно не будет совпадать с отпечатком сертификата на устройствах пользователей. Вы можете проверить, используете ли вы подписывание приложений Play для своего приложения в своей учетной записи разработчика Play Console в разделе Release > Setup > App signing ; если да, то на той же странице вы также найдете правильный фрагмент JSON Digital Asset Links для вашего приложения.

В следующем примере файла assetlinks.json предоставляются права на открытие ссылок приложению Android com.example :

[{
  "relation": ["delegate_permission/common.handle_all_urls"],
  "target": {
    "namespace": "android_app",
    "package_name": "com.example",
    "sha256_cert_fingerprints":
    ["14:6D:E9:83:C5:73:06:50:D8:EE:B9:95:2F:34:FC:64:16:A0:83:42:E6:1D:BE:A8:8A:04:96:B2:3F:CF:44:E5"]
  }
}]

Связывание веб-сайта с несколькими приложениями

Веб-сайт может объявлять ассоциации с несколькими приложениями в одном файле assetlinks.json . В следующем листинге файлов показан пример файла инструкций, который объявляет связь с двумя приложениями отдельно и находится по адресу https://www.example.com/.well-known/assetlinks.json :

[{
  "relation": ["delegate_permission/common.handle_all_urls"],
  "target": {
    "namespace": "android_app",
    "package_name": "com.example.puppies.app",
    "sha256_cert_fingerprints":
    ["14:6D:E9:83:C5:73:06:50:D8:EE:B9:95:2F:34:FC:64:16:A0:83:42:E6:1D:BE:A8:8A:04:96:B2:3F:CF:44:E5"]
  }
  },
  {
  "relation": ["delegate_permission/common.handle_all_urls"],
  "target": {
    "namespace": "android_app",
    "package_name": "com.example.monkeys.app",
    "sha256_cert_fingerprints":
    ["14:6D:E9:83:C5:73:06:50:D8:EE:B9:95:2F:34:FC:64:16:A0:83:42:E6:1D:BE:A8:8A:04:96:B2:3F:CF:44:E5"]
  }
}]

Разные приложения могут обрабатывать ссылки на разные ресурсы на одном веб-хосте. Например, приложение1 может объявить фильтр намерений для https://example.com/articles , а приложение2 может объявить фильтр намерений для https://example.com/videos .

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

Связывание нескольких веб-сайтов с одним приложением

Несколько веб-сайтов могут объявлять ассоциации с одним и тем же приложением в своих соответствующих файлах assetlinks.json . В следующих листингах файлов показан пример объявления ассоциации example.com и example.net с app1. В первом листинге показана связь example.com с app1:

https://www.example.com/.well-known/assetlinks.json

[{
  "relation": ["delegate_permission/common.handle_all_urls"],
  "target": {
    "namespace": "android_app",
    "package_name": "com.mycompany.app1",
    "sha256_cert_fingerprints":
    ["14:6D:E9:83:C5:73:06:50:D8:EE:B9:95:2F:34:FC:64:16:A0:83:42:E6:1D:BE:A8:8A:04:96:B2:3F:CF:44:E5"]
  }
}]

Следующий листинг показывает связь example.net с app1. Отличается только место, где размещаются эти файлы ( .com и .net ):

https://www.example.net/.well-known/assetlinks.json

[{
  "relation": ["delegate_permission/common.handle_all_urls"],
  "target": {
    "namespace": "android_app",
    "package_name": "com.mycompany.app1",
    "sha256_cert_fingerprints":
    ["14:6D:E9:83:C5:73:06:50:D8:EE:B9:95:2F:34:FC:64:16:A0:83:42:E6:1D:BE:A8:8A:04:96:B2:3F:CF:44:E5"]
  }
}]

Публикация файла проверки JSON

Вы должны опубликовать файл проверки JSON по следующему адресу:

https://domain.name/.well-known/assetlinks.json

Убедитесь в следующем:

  • Файл assetlinks.json обслуживается с типом контента application/json .
  • Файл assetlinks.json должен быть доступен через соединение HTTPS, независимо от того, объявляют ли фильтры намерений вашего приложения HTTPS в качестве схемы данных.
  • Файл assetlinks.json должен быть доступен без каких-либо перенаправлений (без перенаправлений 301 или 302).
  • Если ссылки вашего приложения поддерживают несколько доменов хоста, вам необходимо опубликовать файл assetlinks.json в каждом домене. См. раздел Поддержка связывания приложений для нескольких хостов .
  • Не публикуйте свое приложение с URL-адресами разработки и тестирования в файле манифеста, которые могут быть недоступны для общественности (например, с URL-адресами, доступными только через VPN). Обходной путь в таких случаях — настроить варианты сборки для создания другого файла манифеста для сборок разработки.

Проверка ссылок на приложения Android

Если android:autoVerify="true" присутствует хотя бы в одном из фильтров намерений вашего приложения, установка вашего приложения на устройство под управлением Android 6.0 (уровень API 23) или выше приводит к тому, что система автоматически проверяет хосты, связанные с URL-адресами в фильтры намерений вашего приложения. В Android 12 и более поздних версиях вы также можете запустить процесс проверки вручную, чтобы проверить логику проверки.

Автоматическая проверка

Автоматическая проверка системы включает в себя следующее:

  1. Система проверяет все фильтры намерений, которые включают любое из следующего:
    • Действие: android.intent.action.VIEW
    • Категории: android.intent.category.BROWSABLE и android.intent.category.DEFAULT
    • Схема данных: http или https
  2. Для каждого уникального имени хоста, найденного в приведенных выше фильтрах намерений, Android запрашивает на соответствующих веб-сайтах файл ссылок на цифровые активы по адресу https:// hostname /.well-known/assetlinks.json .

После того как вы подтвердили список веб-сайтов, которые будут связаны с вашим приложением, и подтвердили, что размещенный файл JSON действителен, установите приложение на свое устройство. Подождите не менее 20 секунд, пока процесс асинхронной проверки завершится. Используйте следующую команду, чтобы проверить, проверила ли система ваше приложение и установила ли правильную политику обработки ссылок:

adb shell am start -a android.intent.action.VIEW \
    -c android.intent.category.BROWSABLE \
    -d "http://domain.name:optional_port"

Ручная проверка

Начиная с Android 12, вы можете вручную вызвать проверку домена для приложения, установленного на устройстве. Вы можете выполнить этот процесс независимо от того, предназначено ли ваше приложение для Android 12.

Установить подключение к Интернету

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

Поддержка обновленного процесса проверки домена

Если ваше приложение предназначено для Android 12 или более поздней версии, система автоматически использует обновленный процесс проверки домена.

В противном случае вы можете вручную включить обновленный процесс проверки. Для этого выполните следующую команду в окне терминала:

adb shell am compat enable 175408749 PACKAGE_NAME

Сброс состояния ссылок на приложения Android на устройстве

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

adb shell pm set-app-links --package PACKAGE_NAME 0 all

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

Запустите процесс проверки домена

После сброса состояния ссылок на приложения Android на устройстве вы можете выполнить саму проверку. Для этого выполните следующую команду в окне терминала:

adb shell pm verify-app-links --re-verify PACKAGE_NAME

Просмотрите результаты проверки

Дав агенту проверки некоторое время выполнить свои запросы, просмотрите результаты проверки. Для этого выполните следующую команду:

adb shell pm get-app-links PACKAGE_NAME

Вывод этой команды аналогичен следующему:

com.example.pkg:
    ID: 01234567-89ab-cdef-0123-456789abcdef
    Signatures: [***]
    Domain verification state:
      example.com: verified
      sub.example.com: legacy_failure
      example.net: verified
      example.org: 1026

Домены, успешно прошедшие проверку, имеют статус проверки домена « verified . Любое другое состояние указывает на то, что проверку домена выполнить невозможно. В частности, состояние none указывает на то, что агент проверки, возможно, еще не завершил процесс проверки.

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

none
Для этого домена ничего не зарегистрировано. Подождите еще несколько минут, пока агент проверки завершит запросы, связанные с проверкой домена, а затем снова запустите процесс проверки домена .
verified
Домен успешно подтвержден для декларирующего приложения.
approved
Домен был утвержден принудительно, обычно путем выполнения команды оболочки.
denied
Домен был принудительно запрещен, обычно путем выполнения команды оболочки.
migrated
Система сохранила результат предыдущего процесса, в котором использовалась проверка устаревшего домена.
restored
Домен был одобрен после того, как пользователь выполнил восстановление данных. Предполагается, что домен был ранее подтвержден.
legacy_failure
Домен был отклонен устаревшим верификатором. Конкретная причина сбоя неизвестна.
system_configured
Домен был одобрен автоматически конфигурацией устройства.
Код ошибки 1024 или выше.

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

Дважды проверьте, установлено ли сетевое соединение , и снова запустите процесс проверки домена .

Попросите пользователя связать ваше приложение с доменом.

Еще один способ получить одобрение вашего приложения для домена — попросить пользователя связать ваше приложение с этим доменом.

Проверьте, одобрено ли ваше приложение для домена

Прежде чем предлагать пользователю запрос, проверьте, является ли ваше приложение обработчиком по умолчанию для доменов, которые вы определяете в элементах <intent-filter> . Вы можете запросить состояние утверждения одним из следующих методов:

  • API DomainVerificationManager (во время выполнения).
  • Программа командной строки (во время тестирования).

Менеджер проверки домена

В следующем фрагменте кода показано, как использовать API DomainVerificationManager :

Котлин

val context: Context = TODO("Your activity or fragment's Context")
val manager = context.getSystemService(DomainVerificationManager::class.java)
val userState = manager.getDomainVerificationUserState(context.packageName)

// Domains that have passed Android App Links verification.
val verifiedDomains = userState?.hostToStateMap
    ?.filterValues { it == DomainVerificationUserState.DOMAIN_STATE_VERIFIED }

// Domains that haven't passed Android App Links verification but that the user
// has associated with an app.
val selectedDomains = userState?.hostToStateMap
    ?.filterValues { it == DomainVerificationUserState.DOMAIN_STATE_SELECTED }

// All other domains.
val unapprovedDomains = userState?.hostToStateMap
    ?.filterValues { it == DomainVerificationUserState.DOMAIN_STATE_NONE }

Ява

Context context = TODO("Your activity or fragment's Context");
DomainVerificationManager manager =
        context.getSystemService(DomainVerificationManager.class);
DomainVerificationUserState userState =
        manager.getDomainVerificationUserState(context.getPackageName());

Map<String, Integer> hostToStateMap = userState.getHostToStateMap();
List<String> verifiedDomains = new ArrayList<>();
List<String> selectedDomains = new ArrayList<>();
List<String> unapprovedDomains = new ArrayList<>();
for (String key : hostToStateMap.keySet()) {
    Integer stateValue = hostToStateMap.get(key);
    if (stateValue == DomainVerificationUserState.DOMAIN_STATE_VERIFIED) {
        // Domain has passed Android App Links verification.
        verifiedDomains.add(key);
    } else if (stateValue == DomainVerificationUserState.DOMAIN_STATE_SELECTED) {
        // Domain hasn't passed Android App Links verification, but the user has
        // associated it with an app.
        selectedDomains.add(key);
    } else {
        // All other domains.
        unapprovedDomains.add(key);
    }
}

Программа командной строки

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

adb shell pm get-app-links --user cur PACKAGE_NAME

В следующем примере вывода, несмотря на то, что приложение не прошло проверку для домена «example.org», пользователь 0 вручную одобрил приложение в системных настройках, и никакой другой пакет для этого домена не проверен.

com.example.pkg:
ID: ***
Signatures: [***]
Domain verification state:
  example.com: verified
  example.net: verified
  example.org: 1026
User 0:
  Verification link handling allowed: true
  Selection state:
    Enabled:
      example.org
    Disabled:
      example.com
      example.net

Вы также можете использовать команды оболочки для имитации процесса, в котором пользователь выбирает, какое приложение связано с данным доменом. Полное объяснение этих команд доступно в выводе adb shell pm .

Укажите контекст для запроса

Прежде чем сделать этот запрос на утверждение домена, предоставьте пользователю некоторый контекст. Например, вы можете показать им заставку, диалоговое окно или аналогичный элемент пользовательского интерфейса, который объясняет пользователю, почему ваше приложение должно быть обработчиком по умолчанию для определенного домена.

Сделать запрос

После того, как пользователь поймет, что ваше приложение просит его сделать, отправьте запрос. Для этого вызовите намерение, которое включает в себя действие намерения ACTION_APP_OPEN_BY_DEFAULT_SETTINGS и package: com.example.pkg для целевого приложения, как показано в следующем фрагменте кода:

Котлин

val context: Context = TODO("Your activity or fragment's Context")
val intent = Intent(Settings.ACTION_APP_OPEN_BY_DEFAULT_SETTINGS,
    Uri.parse("package:${context.packageName}"))
context.startActivity(intent)

Ява

Context context = TODO("Your activity or fragment's Context");
Intent intent = new Intent(Settings.ACTION_APP_OPEN_BY_DEFAULT_SETTINGS,
    Uri.parse("package:" + context.getPackageName()));
context.startActivity(intent);

При вызове намерения пользователи видят экран настроек под названием «Открыть по умолчанию» . Этот экран содержит переключатель « Открыть поддерживаемые ссылки» , как показано на рисунке 1.

Когда пользователь включает параметр «Открывать поддерживаемые ссылки» , в разделе « Ссылки» появляется набор флажков для открытия в этом приложении . Отсюда пользователи могут выбирать домены, которые они хотят связать с вашим приложением. Они также могут выбрать «Добавить ссылку» , чтобы добавить домены, как показано на рисунке 2. Когда пользователи позже выберут любую ссылку в добавляемых ими доменах, она автоматически откроется в вашем приложении.

Когда переключатель включен, раздел внизу содержит флажки, а также кнопку «Добавить ссылку».
Рисунок 1. Экран настроек системы, на котором пользователи могут выбирать, какие ссылки открываются в вашем приложении по умолчанию.
Каждый флажок представляет домен, который вы можете добавить. Кнопки диалогового окна: «Отмена» и «Добавить».
Рисунок 2. Диалоговое окно, в котором пользователи могут выбрать дополнительные домены для связи с вашим приложением.

Откройте в своем приложении домены, которые ваше приложение не может проверить.

Основная функция вашего приложения может заключаться в открытии ссылок от имени третьего лица без возможности проверки обслуживаемых доменов. В этом случае объясните пользователям, что в тот момент, когда они выбирают веб-ссылку, они не могут выбирать между собственным приложением и вашим (сторонним) приложением. Пользователям необходимо вручную связать домены со сторонним приложением.

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

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

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

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

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

При тестировании вам следует подтвердить список связанных хостов, которые система должна проверить для вашего приложения. Составьте список всех 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://domain.name:optional_port&
   relation=delegate_permission/common.handle_all_urls

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

adb shell dumpsys package domain-preferred-apps

Или следующее делает то же самое:

adb shell dumpsys package d

Примечание. Обязательно подождите не менее 20 секунд после установки приложения, чтобы система могла завершить процесс проверки.

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

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 о настройках связи приложений пользователя. Это значение не указывает, прошла ли проверка успешно.

Примечание. Если пользователь меняет настройки ссылки на приложение до завершения проверки, вы можете увидеть ложное срабатывание успешной проверки, даже если проверка не удалась. Однако этот сбой проверки не имеет значения, если пользователь явно разрешил приложению открывать поддерживаемые ссылки без запроса. Это связано с тем, что предпочтения пользователя имеют приоритет над программной проверкой (или ее отсутствием). В результате ссылка ведет прямо в ваше приложение, без отображения диалогового окна, как если бы проверка прошла успешно.

Тестовый пример

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

<application>

    <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, проверьте наличие следующих распространенных ошибок. В этом разделе example.com используется в качестве доменного имени-заполнителя; при выполнении этих проверок замените example.com фактическим доменным именем вашего сервера.

Неправильно настроен фильтр намерений.
Проверьте, включаете ли вы URL-адрес, которым не владеет ваше приложение, в элемент <intent-filter> .
Неправильная конфигурация сервера

Проверьте конфигурацию JSON вашего сервера и убедитесь, что значение SHA правильное.

Также проверьте этот example.com. (с завершающей точкой) отображает тот же контент, что и example.com .

Перенаправления на стороне сервера

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

  • http://example.com на https://example.com
  • с example.com на www.example.com

Такое поведение защищает безопасность вашего приложения.

Надежность сервера

Проверьте, может ли ваш сервер подключаться к вашим клиентским приложениям.

Непроверяемые ссылки

В целях тестирования вы можете намеренно добавлять непроверяемые ссылки. Имейте в виду, что в Android 11 и более ранних версиях эти ссылки приводят к тому, что система не проверяет все ссылки на приложения Android для вашего приложения.

Неверная подпись в assetslinks.json

Убедитесь, что ваша подпись правильна и соответствует подписи, используемой для подписи вашего приложения. К частым ошибкам относятся:

  • Подписание приложения с помощью сертификата отладки и наличие только подписи выпуска в assetlinks.json .
  • Наличие подписи в нижнем регистре в assetlinks.json . Подпись должна быть в верхнем регистре.
  • Если вы используете подпись приложений Play, убедитесь, что вы используете подпись, которую Google использует для подписи каждого из ваших выпусков. Вы можете проверить эти данные, включая полный фрагмент JSON, следуя инструкциям по объявлению ассоциаций веб-сайтов .
,

Ссылка на приложение Android — это особый тип глубокой ссылки, который позволяет URL-адресам вашего веб-сайта немедленно открывать соответствующий контент в вашем приложении Android, не требуя от пользователя выбора приложения. Ссылки на приложения Android используют API ссылок на цифровые активы, чтобы убедиться в том, что ваше приложение одобрено веб-сайтом, и автоматически открывать ссылки для этого домена. Если система успешно подтвердит, что вы являетесь владельцем URL-адресов, она автоматически перенаправит эти URL-адреса в ваше приложение.

Чтобы убедиться, что вы являетесь владельцем URL-адресов приложения и веб-сайта, выполните следующие действия:

  1. Добавьте фильтры намерений , содержащие атрибут autoVerify . Этот атрибут сигнализирует системе, что она должна проверить, принадлежит ли ваше приложение к доменам URL, используемым в ваших фильтрах намерений.

  2. Объявите связь между вашим веб-сайтом и фильтрами намерений, разместив JSON-файл ссылок на цифровые активы в следующем месте:

    https://domain.name/.well-known/assetlinks.json

Соответствующую информацию вы можете найти на следующих ресурсах:

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

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

<!-- Make sure you explicitly set android:autoVerify to "true". -->
<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" />

    <!-- If a user clicks on a shared link that uses the "http" scheme, your
         app should be able to delegate that traffic to "https". -->
    <data android:scheme="http" />
    <data android:scheme="https" />

    <!-- Include one or more domains that should be verified. -->
    <data android:host="..." />
</intent-filter>

Хотя достаточно включить autoVerify только в одно объявление <intent-filter> для каждого хоста, даже если этот хост используется в других немаркированных объявлениях, для обеспечения согласованности рекомендуется добавлять autoVerify в каждый элемент <intent-filter> . Это также гарантирует, что после удаления или рефакторинга элементов в файле манифеста ваше приложение останется связанным со всеми доменами, которые вы все еще определяете.

Процесс проверки домена требует подключения к Интернету и может занять некоторое время. Чтобы повысить эффективность процесса, система проверяет домен на наличие приложения, предназначенного для Android 12 или более поздней версии, только если этот домен находится внутри элемента <intent-filter> , который содержит точный формат, указанный в предыдущем фрагменте кода.

Поддержка связывания приложений для нескольких хостов

Система должна иметь возможность проверять хост, указанный в элементах данных фильтров намерений URL-адресов приложения, по файлам ссылок на цифровые активы, размещенным на соответствующих веб-доменах в этом фильтре намерений. Если проверка не пройдена, система по умолчанию использует стандартное поведение для разрешения намерения, как описано в разделе «Создание глубоких ссылок на контент приложения» . Однако приложение по-прежнему можно проверить как обработчик по умолчанию для любого шаблона URL-адреса, определенного в других фильтрах намерений приложения.

Примечание. В Android 11 (уровень API 30) и более ранних версиях система не проверяет ваше приложение в качестве обработчика по умолчанию, пока не найдет соответствующий файл ссылок на цифровые активы для всех хостов, которые вы определяете в манифесте.

Например, приложение со следующими фильтрами намерений пройдет проверку только для https://www.example.com , если файл assetlinks.json будет найден по адресу https://www.example.com/.well-known/assetlinks.json , но не https://www.example.net/.well-known/assetlinks.json :

<application>

  <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="http" />
      <data android:scheme="https" />
      <data android:host="www.example.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="www.example.net" />
    </intent-filter>
  </activity>

</application>

Примечание. Все элементы <data> в одном фильтре намерений объединяются вместе, чтобы учесть все варианты их объединенных атрибутов. Например, первый фильтр намерений, приведенный выше, включает элемент <data> , который объявляет только схему HTTPS. Но он объединен с другим элементом <data> , поэтому фильтр намерений поддерживает как http://www.example.com , так и https://www.example.com . Таким образом, вам необходимо создать отдельные фильтры намерений, если вы хотите определить определенные комбинации схем URI и доменов.

Поддержка связывания приложений для нескольких поддоменов

Протокол Digital Asset Links рассматривает субдомены в ваших фильтрах намерений как уникальные отдельные хосты. Поэтому, если в вашем фильтре намерений указано несколько хостов с разными поддоменами, вы должны опубликовать действительный assetlinks.json для каждого домена. Например, следующий фильтр намерений включает www.example.com и mobile.example.com в качестве принятых хостов URL-адресов намерений. Таким образом, действительный assetlinks.json должен быть опубликован как на https://www.example.com/.well-known/assetlinks.json , так и https://mobile.example.com/.well-known/assetlinks.json .

<application>
  <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>
  </activity>
</application>

Альтернативно, если вы объявляете свое имя хоста с подстановочным знаком (например, *.example.com ), вы должны опубликовать файл assetlinks.json в корневом имени хоста ( example.com ). Например, приложение со следующим фильтром намерений пройдет проверку для любого подимени example.com (например, foo.example.com ), если файл assetlinks.json опубликован по адресу https://example.com/.well-known/assetlinks.json :

<application>
  <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:host="*.example.com" />
    </intent-filter>
  </activity>
</application>

Проверьте наличие нескольких приложений, связанных с одним и тем же доменом

Если вы публикуете несколько приложений, каждое из которых связано с одним и тем же доменом, каждое из них можно успешно проверить. Однако если приложения могут разрешать один и тот же хост и путь домена, как это может быть в случае с облегченной и полной версиями приложения, только приложение, которое было установлено последним, может определять веб-намерения для этого домена.

В таком случае проверьте наличие возможных конфликтующих приложений на устройстве пользователя при условии, что у вас есть необходимая видимость пакета . Затем в своем приложении покажите настраиваемый диалог выбора, содержащий результаты вызова queryIntentActivities() . Пользователь может выбрать предпочитаемое приложение из списка подходящих приложений, который появляется в диалоговом окне.

Объявить ассоциации веб-сайтов

На вашем веб-сайте необходимо опубликовать JSON-файл ссылок на цифровые активы, чтобы указать приложения Android, связанные с веб-сайтом, и проверить намерения URL-адреса приложения. В файле JSON используются следующие поля для идентификации связанных приложений:

  • package_name : идентификатор приложения , объявленный в файле build.gradle приложения.
  • sha256_cert_fingerprints : отпечатки SHA256 сертификата подписи вашего приложения. Вы можете использовать следующую команду для создания отпечатка пальца с помощью Java keytool:
    keytool -list -v -keystore my-release-key.keystore
    
    Это поле поддерживает несколько отпечатков пальцев, которые можно использовать для поддержки различных версий вашего приложения, например отладочных и рабочих сборок.

    Если вы используете подпись приложения Play для своего приложения, то отпечаток сертификата, созданный при локальном запуске keytool , обычно не будет совпадать с отпечатком сертификата на устройствах пользователей. Вы можете проверить, используете ли вы подписывание приложений Play для своего приложения в своей учетной записи разработчика Play Console в разделе Release > Setup > App signing ; если да, то на той же странице вы также найдете правильный фрагмент JSON Digital Asset Links для вашего приложения.

В следующем примере файла assetlinks.json предоставляются права на открытие ссылок приложению Android com.example :

[{
  "relation": ["delegate_permission/common.handle_all_urls"],
  "target": {
    "namespace": "android_app",
    "package_name": "com.example",
    "sha256_cert_fingerprints":
    ["14:6D:E9:83:C5:73:06:50:D8:EE:B9:95:2F:34:FC:64:16:A0:83:42:E6:1D:BE:A8:8A:04:96:B2:3F:CF:44:E5"]
  }
}]

Связывание веб-сайта с несколькими приложениями

Веб-сайт может объявлять ассоциации с несколькими приложениями в одном файле assetlinks.json . В следующем листинге файлов показан пример файла инструкций, который объявляет связь с двумя приложениями отдельно и находится по адресу https://www.example.com/.well-known/assetlinks.json :

[{
  "relation": ["delegate_permission/common.handle_all_urls"],
  "target": {
    "namespace": "android_app",
    "package_name": "com.example.puppies.app",
    "sha256_cert_fingerprints":
    ["14:6D:E9:83:C5:73:06:50:D8:EE:B9:95:2F:34:FC:64:16:A0:83:42:E6:1D:BE:A8:8A:04:96:B2:3F:CF:44:E5"]
  }
  },
  {
  "relation": ["delegate_permission/common.handle_all_urls"],
  "target": {
    "namespace": "android_app",
    "package_name": "com.example.monkeys.app",
    "sha256_cert_fingerprints":
    ["14:6D:E9:83:C5:73:06:50:D8:EE:B9:95:2F:34:FC:64:16:A0:83:42:E6:1D:BE:A8:8A:04:96:B2:3F:CF:44:E5"]
  }
}]

Разные приложения могут обрабатывать ссылки на разные ресурсы на одном веб-хосте. Например, приложение1 может объявить фильтр намерений для https://example.com/articles , а приложение2 может объявить фильтр намерений для https://example.com/videos .

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

Связывание нескольких веб-сайтов с одним приложением

Несколько веб-сайтов могут объявлять ассоциации с одним и тем же приложением в своих соответствующих файлах assetlinks.json . В следующих листингах файлов показан пример объявления ассоциации example.com и example.net с app1. В первом листинге показана связь example.com с app1:

https://www.example.com/.well-known/assetlinks.json

[{
  "relation": ["delegate_permission/common.handle_all_urls"],
  "target": {
    "namespace": "android_app",
    "package_name": "com.mycompany.app1",
    "sha256_cert_fingerprints":
    ["14:6D:E9:83:C5:73:06:50:D8:EE:B9:95:2F:34:FC:64:16:A0:83:42:E6:1D:BE:A8:8A:04:96:B2:3F:CF:44:E5"]
  }
}]

Следующий листинг показывает связь example.net с app1. Отличается только место, где размещаются эти файлы ( .com и .net ):

https://www.example.net/.well-known/assetlinks.json

[{
  "relation": ["delegate_permission/common.handle_all_urls"],
  "target": {
    "namespace": "android_app",
    "package_name": "com.mycompany.app1",
    "sha256_cert_fingerprints":
    ["14:6D:E9:83:C5:73:06:50:D8:EE:B9:95:2F:34:FC:64:16:A0:83:42:E6:1D:BE:A8:8A:04:96:B2:3F:CF:44:E5"]
  }
}]

Публикация файла проверки JSON

Вы должны опубликовать файл проверки JSON по следующему адресу:

https://domain.name/.well-known/assetlinks.json

Убедитесь в следующем:

  • Файл assetlinks.json обслуживается с типом контента application/json .
  • Файл assetlinks.json должен быть доступен через соединение HTTPS, независимо от того, объявляют ли фильтры намерений вашего приложения HTTPS в качестве схемы данных.
  • Файл assetlinks.json должен быть доступен без каких-либо перенаправлений (без перенаправлений 301 или 302).
  • Если ссылки вашего приложения поддерживают несколько доменов хоста, вам необходимо опубликовать файл assetlinks.json в каждом домене. См. раздел Поддержка связывания приложений для нескольких хостов .
  • Не публикуйте свое приложение с URL-адресами разработки и тестирования в файле манифеста, которые могут быть недоступны для общественности (например, с URL-адресами, доступными только через VPN). Обходной путь в таких случаях — настроить варианты сборки для создания другого файла манифеста для сборок разработки.

Проверка ссылок на приложения Android

Если android:autoVerify="true" присутствует хотя бы в одном из фильтров намерений вашего приложения, установка вашего приложения на устройство под управлением Android 6.0 (уровень API 23) или выше приводит к тому, что система автоматически проверяет хосты, связанные с URL-адресами в фильтры намерений вашего приложения. В Android 12 и более поздних версиях вы также можете запустить процесс проверки вручную, чтобы проверить логику проверки.

Автоматическая проверка

Автоматическая проверка системы включает в себя следующее:

  1. Система проверяет все фильтры намерений, которые включают любое из следующего:
    • Действие: android.intent.action.VIEW
    • Категории: android.intent.category.BROWSABLE и android.intent.category.DEFAULT
    • Схема данных: http или https
  2. Для каждого уникального имени хоста, найденного в приведенных выше фильтрах намерений, Android запрашивает на соответствующих веб-сайтах файл ссылок на цифровые активы по адресу https:// hostname /.well-known/assetlinks.json .

После того как вы подтвердили список веб-сайтов, которые будут связаны с вашим приложением, и подтвердили, что размещенный файл JSON действителен, установите приложение на свое устройство. Подождите не менее 20 секунд, пока процесс асинхронной проверки завершится. Используйте следующую команду, чтобы проверить, проверила ли система ваше приложение и установила ли правильную политику обработки ссылок:

adb shell am start -a android.intent.action.VIEW \
    -c android.intent.category.BROWSABLE \
    -d "http://domain.name:optional_port"

Ручная проверка

Начиная с Android 12, вы можете вручную вызвать проверку домена для приложения, установленного на устройстве. Вы можете выполнить этот процесс независимо от того, предназначено ли ваше приложение для Android 12.

Установить подключение к Интернету

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

Поддержка обновленного процесса проверки домена

Если ваше приложение предназначено для Android 12 или более поздней версии, система автоматически использует обновленный процесс проверки домена.

В противном случае вы можете вручную включить обновленный процесс проверки. Для этого выполните следующую команду в окне терминала:

adb shell am compat enable 175408749 PACKAGE_NAME

Сброс состояния ссылок на приложения Android на устройстве

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

adb shell pm set-app-links --package PACKAGE_NAME 0 all

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

Запустите процесс проверки домена

После сброса состояния ссылок на приложения Android на устройстве вы можете выполнить саму проверку. Для этого выполните следующую команду в окне терминала:

adb shell pm verify-app-links --re-verify PACKAGE_NAME

Просмотрите результаты проверки

Дав агенту проверки некоторое время выполнить свои запросы, просмотрите результаты проверки. Для этого выполните следующую команду:

adb shell pm get-app-links PACKAGE_NAME

Вывод этой команды аналогичен следующему:

com.example.pkg:
    ID: 01234567-89ab-cdef-0123-456789abcdef
    Signatures: [***]
    Domain verification state:
      example.com: verified
      sub.example.com: legacy_failure
      example.net: verified
      example.org: 1026

Домены, успешно прошедшие проверку, имеют статус проверки домена « verified . Любое другое состояние указывает на то, что проверку домена выполнить невозможно. В частности, состояние none указывает на то, что агент проверки, возможно, еще не завершил процесс проверки.

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

none
Для этого домена ничего не зарегистрировано. Подождите еще несколько минут, пока агент проверки завершит запросы, связанные с проверкой домена, а затем снова запустите процесс проверки домена .
verified
Домен успешно подтвержден для декларирующего приложения.
approved
Домен был утвержден принудительно, обычно путем выполнения команды оболочки.
denied
Домен был принудительно запрещен, обычно путем выполнения команды оболочки.
migrated
Система сохранила результат предыдущего процесса, в котором использовалась проверка устаревшего домена.
restored
Домен был одобрен после того, как пользователь выполнил восстановление данных. Предполагается, что домен был ранее подтвержден.
legacy_failure
Домен был отклонен устаревшим верификатором. Конкретная причина сбоя неизвестна.
system_configured
Домен был одобрен автоматически конфигурацией устройства.
Код ошибки 1024 или выше.

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

Дважды проверьте, установлено ли сетевое соединение , и снова запустите процесс проверки домена .

Попросите пользователя связать ваше приложение с доменом.

Еще один способ получить одобрение вашего приложения для домена — попросить пользователя связать ваше приложение с этим доменом.

Проверьте, одобрено ли ваше приложение для домена

Прежде чем предлагать пользователю запрос, проверьте, является ли ваше приложение обработчиком по умолчанию для доменов, которые вы определяете в элементах <intent-filter> . Вы можете запросить состояние утверждения одним из следующих методов:

  • API DomainVerificationManager (во время выполнения).
  • Программа командной строки (во время тестирования).

Менеджер проверки домена

В следующем фрагменте кода показано, как использовать API DomainVerificationManager :

Котлин

val context: Context = TODO("Your activity or fragment's Context")
val manager = context.getSystemService(DomainVerificationManager::class.java)
val userState = manager.getDomainVerificationUserState(context.packageName)

// Domains that have passed Android App Links verification.
val verifiedDomains = userState?.hostToStateMap
    ?.filterValues { it == DomainVerificationUserState.DOMAIN_STATE_VERIFIED }

// Domains that haven't passed Android App Links verification but that the user
// has associated with an app.
val selectedDomains = userState?.hostToStateMap
    ?.filterValues { it == DomainVerificationUserState.DOMAIN_STATE_SELECTED }

// All other domains.
val unapprovedDomains = userState?.hostToStateMap
    ?.filterValues { it == DomainVerificationUserState.DOMAIN_STATE_NONE }

Ява

Context context = TODO("Your activity or fragment's Context");
DomainVerificationManager manager =
        context.getSystemService(DomainVerificationManager.class);
DomainVerificationUserState userState =
        manager.getDomainVerificationUserState(context.getPackageName());

Map<String, Integer> hostToStateMap = userState.getHostToStateMap();
List<String> verifiedDomains = new ArrayList<>();
List<String> selectedDomains = new ArrayList<>();
List<String> unapprovedDomains = new ArrayList<>();
for (String key : hostToStateMap.keySet()) {
    Integer stateValue = hostToStateMap.get(key);
    if (stateValue == DomainVerificationUserState.DOMAIN_STATE_VERIFIED) {
        // Domain has passed Android App Links verification.
        verifiedDomains.add(key);
    } else if (stateValue == DomainVerificationUserState.DOMAIN_STATE_SELECTED) {
        // Domain hasn't passed Android App Links verification, but the user has
        // associated it with an app.
        selectedDomains.add(key);
    } else {
        // All other domains.
        unapprovedDomains.add(key);
    }
}

Программа командной строки

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

adb shell pm get-app-links --user cur PACKAGE_NAME

В следующем примере вывода, несмотря на то, что приложение не прошло проверку для домена «example.org», пользователь 0 вручную одобрил приложение в системных настройках, и никакой другой пакет для этого домена не проверен.

com.example.pkg:
ID: ***
Signatures: [***]
Domain verification state:
  example.com: verified
  example.net: verified
  example.org: 1026
User 0:
  Verification link handling allowed: true
  Selection state:
    Enabled:
      example.org
    Disabled:
      example.com
      example.net

Вы также можете использовать команды оболочки для имитации процесса, в котором пользователь выбирает, какое приложение связано с данным доменом. Полное объяснение этих команд доступно в выводе adb shell pm .

Укажите контекст для запроса

Прежде чем сделать этот запрос на утверждение домена, предоставьте пользователю некоторый контекст. Например, вы можете показать им заставку, диалоговое окно или аналогичный элемент пользовательского интерфейса, который объясняет пользователю, почему ваше приложение должно быть обработчиком по умолчанию для определенного домена.

Сделать запрос

После того, как пользователь поймет, что ваше приложение просит его сделать, отправьте запрос. Для этого вызовите намерение, которое включает в себя действие намерения ACTION_APP_OPEN_BY_DEFAULT_SETTINGS и package: com.example.pkg для целевого приложения, как показано в следующем фрагменте кода:

Котлин

val context: Context = TODO("Your activity or fragment's Context")
val intent = Intent(Settings.ACTION_APP_OPEN_BY_DEFAULT_SETTINGS,
    Uri.parse("package:${context.packageName}"))
context.startActivity(intent)

Ява

Context context = TODO("Your activity or fragment's Context");
Intent intent = new Intent(Settings.ACTION_APP_OPEN_BY_DEFAULT_SETTINGS,
    Uri.parse("package:" + context.getPackageName()));
context.startActivity(intent);

При вызове намерения пользователи видят экран настроек под названием «Открыть по умолчанию» . Этот экран содержит переключатель « Открыть поддерживаемые ссылки» , как показано на рисунке 1.

Когда пользователь включает параметр «Открывать поддерживаемые ссылки» , в разделе « Ссылки» появляется набор флажков для открытия в этом приложении . Отсюда пользователи могут выбирать домены, которые они хотят связать с вашим приложением. Они также могут выбрать «Добавить ссылку» , чтобы добавить домены, как показано на рисунке 2. Когда пользователи позже выберут любую ссылку в добавляемых ими доменах, она автоматически откроется в вашем приложении.

Когда переключатель включен, раздел внизу содержит флажки, а также кнопку «Добавить ссылку».
Рисунок 1. Экран настроек системы, на котором пользователи могут выбирать, какие ссылки открываются в вашем приложении по умолчанию.
Каждый флажок представляет домен, который вы можете добавить. Кнопки диалогового окна: «Отмена» и «Добавить».
Рисунок 2. Диалоговое окно, в котором пользователи могут выбрать дополнительные домены для связи с вашим приложением.

Откройте в своем приложении домены, которые ваше приложение не может проверить.

Основная функция вашего приложения может заключаться в открытии ссылок от имени третьего лица без возможности проверки обслуживаемых доменов. В этом случае объясните пользователям, что в тот момент, когда они выбирают веб-ссылку, они не могут выбирать между собственным приложением и вашим (сторонним) приложением. Пользователям необходимо вручную связать домены со сторонним приложением.

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

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

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

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

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

При тестировании вам следует подтвердить список связанных хостов, которые система должна проверить для вашего приложения. Составьте список всех 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://domain.name:optional_port&
   relation=delegate_permission/common.handle_all_urls

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

adb shell dumpsys package domain-preferred-apps

Или следующее делает то же самое:

adb shell dumpsys package d

Примечание. Обязательно подождите не менее 20 секунд после установки приложения, чтобы система могла завершить процесс проверки.

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

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 о настройках связи приложений пользователя. Это значение не указывает, прошла ли проверка успешно.

Примечание. Если пользователь меняет настройки ссылки на приложение до завершения проверки, вы можете увидеть ложное срабатывание успешной проверки, даже если проверка не удалась. Однако этот сбой проверки не имеет значения, если пользователь явно разрешил приложению открывать поддерживаемые ссылки без запроса. Это связано с тем, что предпочтения пользователя имеют приоритет над программной проверкой (или ее отсутствием). В результате ссылка ведет прямо в ваше приложение, без отображения диалогового окна, как если бы проверка прошла успешно.

Тестовый пример

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

<application>

    <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, проверьте наличие следующих распространенных ошибок. В этом разделе example.com используется в качестве доменного имени-заполнителя; при выполнении этих проверок замените example.com фактическим доменным именем вашего сервера.

Неправильно настроен фильтр намерений.
Проверьте, включаете ли вы URL-адрес, которым не владеет ваше приложение, в элемент <intent-filter> .
Неправильная конфигурация сервера

Проверьте конфигурацию JSON вашего сервера и убедитесь, что значение SHA правильное.

Также проверьте этот example.com. (с завершающей точкой) отображает тот же контент, что и example.com .

Перенаправления на стороне сервера

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

  • http://example.com на https://example.com
  • с example.com на www.example.com

Такое поведение защищает безопасность вашего приложения.

Надежность сервера

Проверьте, может ли ваш сервер подключаться к вашим клиентским приложениям.

Непроверяемые ссылки

В целях тестирования вы можете намеренно добавлять непроверяемые ссылки. Имейте в виду, что в Android 11 и более ранних версиях эти ссылки приводят к тому, что система не проверяет все ссылки на приложения Android для вашего приложения.

Неверная подпись в assetslinks.json

Убедитесь, что ваша подпись правильна и соответствует подписи, используемой для подписи вашего приложения. К частым ошибкам относятся:

  • Подписание приложения с помощью сертификата отладки и наличие только подписи выпуска в assetlinks.json .
  • Наличие подписи в нижнем регистре в assetlinks.json . Подпись должна быть в верхнем регистре.
  • Если вы используете подпись приложений Play, убедитесь, что вы используете подпись, которую Google использует для подписи каждого из ваших выпусков. Вы можете проверить эти данные, включая полный фрагмент JSON, следуя инструкциям по объявлению ассоциаций веб-сайтов .