В Android глубокая ссылка — это ссылка, которая ведет непосредственно к определенному разделу внутри приложения.
В вашем приложении могут поддерживаться два разных типа глубоких ссылок: явные и неявные . Способ реализации глубоких ссылок зависит от типа графа XML or programmatic — используемого вашим приложением.
Создайте явную прямую ссылку
Явная глубокая ссылка — это единичный экземпляр глубокой ссылки, использующий PendingIntent для перевода пользователей в определенное место внутри вашего приложения. Например, вы можете отображать явную глубокую ссылку в виде уведомления или виджета приложения.
Когда пользователь открывает ваше приложение по явной прямой ссылке, стек задач "Назад" очищается и заменяется адресом перехода по прямой ссылке. При вложенности графов начальный адрес каждого уровня вложенности — то есть начальный адрес каждого элемента <navigation> в иерархии — также добавляется в стек. Это означает, что когда пользователь нажимает кнопку "Назад" по прямой ссылке, он возвращается вверх по стеку навигации так же, как если бы он вошел в ваше приложение с точки входа.
Программные графы
Если ваш навигационный граф определен программно (как это обычно бывает в Navigation Compose или Kotlin DSL), мы рекомендуем использовать TaskStackBuilder для создания PendingIntent для глубокой ссылки.
val id = "exampleId"
val context = LocalContext.current
val deepLinkIntent = Intent(
Intent.ACTION_VIEW,
"https://www.example.com/profile/$id".toUri(),
context,
MyActivity::class.java
)
val pendingIntent: PendingIntent? = TaskStackBuilder.create(context).run {
addNextIntentWithParentStack(deepLinkIntent)
getPendingIntent(0, PendingIntent.FLAG_UPDATE_CURRENT)
}
XML-графики
Для создания объекта PendingIntent можно использовать класс NavDeepLinkBuilder , как показано в примере ниже. Обратите внимание, что если предоставленный контекст не является Activity , конструктор использует PackageManager.getLaunchIntentForPackage() в качестве Activity по умолчанию для запуска, если таковая доступна.
Котлин
val pendingIntent = NavDeepLinkBuilder(context) .setGraph(R.navigation.nav_graph) .setDestination(R.id.android) .setArguments(args) .createPendingIntent()
Java
PendingIntent pendingIntent = new NavDeepLinkBuilder(context) .setGraph(R.navigation.nav_graph) .setDestination(R.id.android) .setArguments(args) .createPendingIntent();
По умолчанию NavDeepLinkBuilder запускает вашу явную глубокую ссылку в Activity по умолчанию, объявленной в манифесте вашего приложения. Если ваш NavHost находится в другой Activity, необходимо указать имя его компонента при создании построителя глубоких ссылок:
Котлин
val pendingIntent = NavDeepLinkBuilder(context) .setGraph(R.navigation.nav_graph) .setDestination(R.id.android) .setArguments(args) .setComponentName(DestinationActivity::class.java) .createPendingIntent()
Java
PendingIntent pendingIntent = new NavDeepLinkBuilder(context) .setGraph(R.navigation.nav_graph) .setDestination(R.id.android) .setArguments(args) .setComponentName(DestinationActivity.class) .createPendingIntent();
Если у вас есть ComponentName , вы можете передать его напрямую в построитель:
Котлин
val componentName = ... val pendingIntent = NavDeepLinkBuilder(context) .setGraph(R.navigation.nav_graph) .setDestination(R.id.android) .setArguments(args) .setComponentName(componentName) .createPendingIntent()
Java
ComponentName componentName = ...; PendingIntent pendingIntent = new NavDeepLinkBuilder(context) .setGraph(R.navigation.nav_graph) .setDestination(R.id.android) .setArguments(args) .setComponentName(componentName) .createPendingIntent();
Если у вас уже есть NavController , вы также можете создать прямую ссылку, используя NavController.createDeepLink() .
Создайте неявную глубокую ссылку.
Неявная глубокая ссылка указывает на конкретное место в приложении. Когда глубокая ссылка активируется — например, когда пользователь нажимает на ссылку — Android может открыть ваше приложение по соответствующему адресу.
Глубокие ссылки могут сопоставляться по URI, действиям намерений и MIME-типам. Для одной глубокой ссылки можно указать несколько типов соответствия, но обратите внимание, что приоритет отдается сопоставлению аргументов URI, затем действиям, а затем MIME-типу.
Программные графы
Если вы определяете граф навигации программно (используя Navigation Compose или Kotlin DSL), то глубокие ссылки определяются в коде.
Сочинить
В Navigation Compose вы можете определять глубокие ссылки как часть конструктора целевых объектов composable() с помощью параметра deepLinks . Он принимает список объектов NavDeepLink , которые можно создать с помощью функции navDeepLink() :
@Serializable
data class Profile(val id: String)
val uri = "https://www.example.com"
composable<Profile>(
deepLinks = listOf(
navDeepLink<Profile>(basePath = "$uri/profile")
)
) { backStackEntry ->
val profile: Profile = backStackEntry.toRoute()
ProfileScreen(id = profile.id)
}
Kotlin DSL
При использовании Kotlin DSL вы можете определять прямые ссылки с помощью функции-конструктора deepLink() внутри целевого блока:
@Serializable
data class Profile(val id: String)
val uri = "https://www.example.com"
fragment<ProfileFragment, Profile> {
deepLink<Profile>(basePath = "$uri/profile")
}
Добавьте фильтры намерений для программных графов.
Поскольку графы программной навигации создаются во время выполнения, компонент Navigation не может автоматически генерировать соответствующие элементы <intent-filter> в вашем AndroidManifest.xml . Вместо этого вам необходимо вручную добавить соответствующие элементы <intent-filter> .
Чтобы включить прямую ссылку, как в приведенных выше примерах, добавьте следующее внутри соответствующего элемента <activity> в вашем манифесте:
<activity …>
<intent-filter>
...
<data android:scheme="https" android:host="www.example.com" />
</intent-filter>
</activity>
XML-графики
Для создания неявной глубокой ссылки в XML-графе можно определить элемент <deepLink> непосредственно в XML-файле или использовать редактор навигации.
Вот пример прямой ссылки, содержащей URI, действие и MIME-тип:
<fragment android:id="@+id/a"
android:name="com.example.myapplication.FragmentA"
tools:layout="@layout/a">
<deepLink app:uri="www.example.com"
app:action="android.intent.action.MY_ACTION"
app:mimeType="type/subtype"/>
</fragment>
Вы также можете использовать редактор навигации для создания неявной прямой ссылки на целевой ресурс следующим образом:
- На вкладке «Дизайн» редактора навигации выберите место назначения для прямой ссылки.
- Нажмите кнопку «+» в разделе «Глубокие ссылки» на панели «Атрибуты» .
В появившемся диалоговом окне «Добавить прямую ссылку» введите информацию для вашей прямой ссылки.
Обратите внимание на следующее:
- URI без указания схемы считаются либо
http, либоhttps. Например,www.google.comсоответствует какhttp://www.google.com, так иhttps://www.google.com. - В параметрах пути в формате
{placeholder_name}соответствует одному или нескольким символам. Например,http://www.example.com/users/{id}соответствуетhttp://www.example.com/users/4. Компонент навигации пытается преобразовать значения заполнителей в соответствующие типы, сопоставляя имена заполнителей с определенными аргументами , заданными для целевой ссылки. Если аргумент с таким же именем не определен, для значения аргумента используется типStringпо умолчанию. Вы можете использовать символ подстановки .* для сопоставления 0 или более символов. - Заполнители параметров запроса можно использовать вместо параметров пути или совместно с ними. Например,
http://www.example.com/users/{id}?myarg={myarg}соответствуетhttp://www.example.com/users/4?myarg=28. - В параметрах запроса для переменных, определенных со значениями по умолчанию или допускающими значение NULL, совпадение не является обязательным. Например,
http://www.example.com/users/{id}?arg1={arg1}&arg2={arg2}соответствуетhttp://www.example.com/users/4?arg2=28илиhttp://www.example.com/users/4?arg1=7. С параметрами пути дело обстоит иначе. Например,http://www.example.com/users?arg1=7&arg2=28не соответствует указанному шаблону, поскольку не указан необходимый параметр пути. - Посторонние параметры запроса не влияют на сопоставление URI глубоких ссылок. Например,
http://www.example.com/users/{id}соответствуетhttp://www.example.com/users/4?extraneousParam=7, даже еслиextraneousParamне определен в шаблоне URI.
- URI без указания схемы считаются либо
(Необязательно) Установите флажок «Автоматическая проверка» , чтобы Google подтвердил, что вы являетесь владельцем URI. Дополнительную информацию см. в разделе «Проверка ссылок в приложениях Android» .
Нажмите «Добавить» . Значок ссылки.
Этот значок появляется над выбранным пунктом назначения, указывая на то, что этот пункт содержит прямую ссылку.Нажмите вкладку «Код» , чтобы переключиться в XML-режим. В целевую папку добавлен вложенный элемент
<deepLink>:<deepLink app:uri="https://www.google.com" />
Для включения неявной глубокой ссылки для XML-графов необходимо также внести изменения в файл manifest.xml вашего приложения. Добавьте в активность один элемент <nav-graph> , указывающий на существующий навигационный граф, как показано в следующем примере:
<?xml version="1.0" encoding="utf-8"?> <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.example.myapplication"> <application ... > <activity name=".MainActivity" ...> ... <nav-graph android:value="@navigation/nav_graph" /> ... </activity> </application> </manifest>
При сборке проекта компонент Navigation заменяет элемент <nav-graph> сгенерированными элементами <intent-filter> , соответствующими всем глубоким ссылкам в графе навигации.
Неявные глубокие ссылки и обратный стек
При запуске неявной глубокой ссылки состояние стека возврата зависит от того, был ли неявный Intent запущен с флагом Intent.FLAG_ACTIVITY_NEW_TASK :
- Если флаг установлен, стек возврата задачи очищается и заменяется целевой ссылкой. Как и в случае с явной глубокой ссылкой , при вложенности графов начальная целевая ссылка с каждого уровня вложенности — то есть начальная целевая ссылка от каждого элемента
<navigation>в иерархии — также добавляется в стек. Это означает, что когда пользователь нажимает кнопку «Назад» из целевой ссылки, он возвращается вверх по стеку навигации так же, как если бы он вошел в ваше приложение с его точки входа. - Если флаг не установлен, вы остаетесь в стеке задач предыдущего приложения, где была активирована неявная глубокая ссылка. В этом случае кнопка «Назад» возвращает вас в предыдущее приложение, а кнопка «Вверх» запускает задачу вашего приложения на иерархическом родительском пункте назначения в вашем графе навигации.
Обработка прямых ссылок
Настоятельно рекомендуется всегда использовать launchMode по умолчанию — standard при использовании Navigation. При использовании standard режима запуска Navigation автоматически обрабатывает глубокие ссылки, вызывая метод handleDeepLink() для обработки любых явных или неявных глубоких ссылок внутри Intent . Однако это не происходит автоматически, если Activity используется повторно при применении альтернативного launchMode например singleTop . В этом случае необходимо вручную вызвать handleDeepLink() в onNewIntent() , как показано в следующем примере:
Котлин
override fun onNewIntent(intent: Intent?) { super.onNewIntent(intent) navController.handleDeepLink(intent) }
Java
@Override protected void onNewIntent(Intent intent) { super.onNewIntent(intent); navController.handleDeepLink(intent); }