Как настроить открытие ссылок в Android‑приложении (deep link и custom scheme)

Deep link — это URL, который открывает конкретный экран или состояние в приложении. Чтобы ссылки открывались в приложении: добавьте правильный intent‑filter в AndroidManifest (custom scheme или https App Links), реализуйте разбор intent.data в единой точке входа и настройте fallback (редирект в браузер или на маркет).

  • Custom scheme (myapp://...) — простой протокол для обмена между приложениями и внутренними переходами. Плюсы: простота, кроссплатформенность с iOS. Минусы: если приложение не установлено — ссылка не откроется; scheme можно конфликтовать с другими приложениями.
  • App Links / http(s) intent‑filter (https://your.domain/...) — единый URL работает и в браузере, и как deep link. Плюсы: SEO, реклама, fallback в браузер. Минус: без верификации возможен chooser; нужна настройка Digital Asset Links для автозапуска без выбора.

Когда использовать:

  • Только внутренняя логика/SDK: custom scheme.
  • Публичные ссылки, реклама, email, SEO: https + App Links (android:autoVerify="true").

Практическая настройка: манифест, парсинг, тестирование

  1. Пример intent‑filter для custom scheme:
<activity android:name=".DeepLinkActivity" android:exported="true">
  <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="myapp" android:host="product"/>
  </intent-filter>
</activity>
  1. Пример для https (App Links):
<activity android:name=".DeepLinkActivity" android:exported="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"/>
    <data android:scheme="https" android:host="shop.example.com" android:pathPrefix="/p"/>
  </intent-filter>
</activity>
  1. Разбор URI в Activity (Kotlin):
val uri = intent?.data
if (uri != null) {
  val segments = uri.pathSegments // ["p", "123"]
  if (segments.size >= 2 && segments[0] == "p") {
    val productId = segments[1]
    Navigator.open(ProductScreen(productId))
  }
}
finish()
  1. Тестирование через ADB: adb shell am start -W -a android.intent.action.VIEW -d "myapp://product/123" your.package.name adb shell am start -W -a android.intent.action.VIEW -d "https://shop.example.com/p/123" your.package.name

Убедитесь, что Activity с intent‑filter имеет android:exported="true", иначе внешние вызовы не пройдут.

  1. Верификация App Links: положите файл assetlinks.json в https:///.well-known/ с relation delegate_permission/common.handle_all_urls, укажите package_name и sha256_cert_fingerprints (release). После установки система установит доверие и уберёт диалог выбора.

Рекомендуемый паттерн — отдельная прозрачная DeepLinkActivity: быстро парсит URI, конвертирует в sealed‑класс (DeepLinkDestination) и передаёт навигатору — потом finish(). Это упрощает тесты и повторное использование.

Лучшие практики и обработка кейсов

  • Всегда продумывайте fallback: для custom scheme — редирект на Play Маркет или на веб‑страницу; для https — браузер автоматически откроет страницу.
  • Обрабатывайте состояние авторизации: сначала показывайте экран логина, затем перенаправляйте на целевой экран.
  • Логируйте неудачные deep link’и (неправильные пути, пустые id) для аналитики.
  • Тестируйте на реальных устройствах и разных версиях Android; проверьте поведение при нескольких приложениях, подписанных на те же хосты.

Частые ошибки

  • Не совпадают host/path между manifest и реальной ссылкой.
  • Забыт android:exported="true".
  • Несоответствие SHA‑256 отпечатка в assetlinks.json и реального релизного ключа.
  • Несколько Activity с одинаковыми intent‑filter — система выбирает не ту Activity.
  • Отсутствие fallback для неустановленного приложения.

FAQ

  • Что делать, если приложение не установлено? Для custom scheme: показывайте ссылку на Play Market или веб‑страницу через серверный редирект. Для https — браузер откроет сайт автоматически.
  • Чем отличается chooser от verified App Link? Chooser появляется, если ссылка не привязана верификацией; verified link (через assetlinks.json и android:autoVerify="true") открывается сразу в приложении.
  • Как получить SHA‑256 отпечаток? Получают из подписи APK/AAB (release‑ключа) — используйте keytool или сборочные инструменты CI.
  • Можно ли использовать один и тот же URL и для сайта, и для custom scheme? Нет: custom scheme и https — разные механики; для единого поведения используйте https App Links и при необходимости отдельный custom scheme для внутренних вызовов.