Как настроить открытие ссылок в Android‑приложении (deep link и custom scheme)
Deep link — это URL, который открывает конкретный экран или состояние в приложении. Чтобы ссылки открывались в приложении: добавьте правильный intent‑filter в AndroidManifest (custom scheme или https App Links), реализуйте разбор intent.data в единой точке входа и настройте fallback (редирект в браузер или на маркет).
Что такое custom scheme и App Links — когда что использовать
- 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").
Практическая настройка: манифест, парсинг, тестирование
- Пример 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>
- Пример для 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>
- Разбор 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()
- Тестирование через 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", иначе внешние вызовы не пройдут.
- Верификация 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 для внутренних вызовов.