Начиная с версии 1.2.0 , Navigation 3 поддерживает создание прямых ссылок на элементы вашего приложения с помощью классов DeepLinkRequest и DeepLinkMatcher .
Для поддержки прямых ссылок в вашем приложении выполните следующие шаги:
- Определите фильтры намерений в файле
AndroidManifest.xml, чтобы указать, какие URI может обрабатывать ваше приложение. - Создайте экземпляры
DeepLinkMatcher, чтобы сопоставлять входящие запросы с клавишами навигации. - Сопоставляйте входящие запросы в методах
onCreateилиonNewIntentвашего Activity и соответствующим образом обновляйте стек возврата.
Создайте DeepLinkRequest
Объект DeepLinkRequest представляет собой входящую глубокую ссылку. Он содержит объект DeepLinkUri и необязательный RequestExtras с дополнительной информацией, такой как действие намерения или MIME-тип.
// Create a request with a String URI val request = DeepLinkRequest(uri = "https://www.example.com/home") // Create a request from a DeepLinkUri val deepLinkUri = DeepLinkUri("https://www.example.com/home") val requestFromUri = DeepLinkRequest(uri = deepLinkUri) // Create a request with a URI and action val requestWithAction = DeepLinkRequest( uri = "https://www.example.com/home", extras = DeepLinkRequest.actionExtra("android.intent.action.VIEW") ) // Create a request with URI, action and mimeType val requestWithMimeType = DeepLinkRequest( uri = "https://www.example.com/image", extras = requestExtras { put(DeepLinkRequest.ActionExtrasKey, "android.intent.action.VIEW") put(DeepLinkRequest.Companion.MimeTypeExtrasKey, "image/png") } )
Предоставьте дополнительные возможности DeepLinkRequest
Для хранения дополнительной информации, связанной с прямой ссылкой, используйте класс RequestExtras . Для обеспечения типобезопасности при определении и создании экземпляров дополнительных элементов библиотека предоставляет интерфейс RequestExtrasKey и DSL requestExtras .
Кроме того, библиотека предоставляет два дополнительных ключа и соответствующие вспомогательные функции:
-
MimeTypeExtrasKey: Используется для хранения MIME-типаString. -
ActionExtrasKey(только для Android): используется для храненияStringдействияIntent.
val extras: RequestExtras = requestExtras { put(DeepLinkRequest.Companion.MimeTypeExtrasKey, "application/json") put(DeepLinkRequest.ActionExtrasKey, Intent.ACTION_VIEW) } // Access typed values using the get operator val mimeType: String? = extras[DeepLinkRequest.Companion.MimeTypeExtrasKey] val action: String? = extras[DeepLinkRequest.ActionExtrasKey] // Create extras using helper functions and combine them val mimeTypeExtras: RequestExtras = DeepLinkRequest.mimeTypeExtra("application/json") val combinedExtras: RequestExtras = extras + DeepLinkRequest.actionExtra(Intent.ACTION_VIEW)
Чтобы определить собственные дополнительные параметры, реализуйте интерфейс RequestExtrasKey с типизированным обобщенным типом:
// Define a custom typed key: object CampaignIdExtrasKey : RequestExtrasKey<String> val customExtras: RequestExtras = requestExtras { put(CampaignIdExtrasKey, "123") } val campaignId: String? = customExtras[CampaignIdExtrasKey]
Также можно использовать emptyRequestExtras() для создания пустого экземпляра или комбинировать дополнительные данные с помощью операторов + ( plus ) и - ( minus ).
Создайте DeepLinkRequest из Intent
На Android можно создать DeepLinkRequest непосредственно из Intent . При таком способе создания DeepLinkRequest формируется следующим образом:
-
uriкопируется из поляdataинтента. - Если значение не равно null, тип MIME и дополнительные параметры действия задаются из соответствующих полей намерения.
- Все значения
intent.extras, не равные null, сохраняются какSavedStateвDeepLinkRequest.IntentExtrasKey. - Все дополнительные опции, указанные с помощью параметра
extras, добавляются.
object CampaignIdExtrasKey : RequestExtrasKey<String> val intent = Intent(Intent.ACTION_VIEW).apply { data = Uri.parse("https://www.example.com/item/42") type = "application/json" putExtra("user_id", "123") } val request = DeepLinkRequest( intent = intent, extras = requestExtras { put(CampaignIdExtrasKey, "spring_promo") } ) // The resulting DeepLinkRequest contains: val uri = request.uri // "https://www.example.com/item/42" val action = request.extras[DeepLinkRequest.ActionExtrasKey] // "android.intent.action.VIEW" val mimeType = request.extras[DeepLinkRequest.Companion.MimeTypeExtrasKey] // "application/json" val intentExtras: SavedState? = request.extras[DeepLinkRequest.IntentExtrasKey] val userId: String? = intentExtras?.read { getStringOrNull("user_id") } // "123" val campaignId: String? = request.extras[CampaignIdExtrasKey] // "spring_promo"
Создайте экземпляры DeepLinkMatcher
Объект DeepLinkMatcher сопоставляет входящие экземпляры DeepLinkRequest с навигационными клавишами, которые можно добавить в стек возврата вашего приложения. Navigation 3 предоставляет три встроенных сопоставителя: UriDeepLinkMatcher для сопоставления URI по шаблонам, StaticKeyDeepLinkMatcher для простых ссылок и BackStackMatcher для создания синтетических стеков возврата. Библиотека также поддерживает пользовательские сопоставители для случаев использования, не охваченных встроенными сопоставителями.
Для получения дополнительной информации см. раздел «Создание DeepLinkMatchers» .
Добавить фильтры намерений
Чтобы разрешить запуск активности по прямой ссылке, необходимо определить соответствующие элементы <intent-filter> в файле AndroidManifest.xml вашего приложения. Дополнительную информацию см. в разделе «Добавление фильтров намерений для входящих ссылок» .
Сопоставить входящий запрос
После создания экземпляров DeepLinkMatcher вы можете сопоставлять входящие запросы в своей активности.
Для сопоставления входящего запроса выполните следующие шаги:
- Создайте экземпляры
DeepLinkMatcher. - Объедините все экземпляры
DeepLinkMatcher, либо явно, либо с помощью множественных привязок . - Создайте
DeepLinkRequestна основе входящегоIntent. - Сравните запрос со всеми сопоставителями и найдите наилучшее совпадение.
- Создайте стек возврата из результата совпадения.
// 1. Instantiate your DeepLinkMatcher instances. val homeMatcher = StaticKeyDeepLinkMatcher(HomeKey, listOf(DeepLinkMatcher.actionFilter(Intent.ACTION_VIEW))) val userProfileMatcher = UriDeepLinkMatcher( DeepLinkUri("www.example.com/users/{id}"), serializer<UserProfileKey>() ).withBackStack { matchResult -> listOf(HomeKey, matchResult.key) } val telMatcher = TelDeepLinkMatcher() // 2. Collate all of your DeepLinkMatcher instances. // Note: Collating matchers with different generic types requires wildcards, // erasing the specific generic types. val deepLinkMatchers: List<DeepLinkMatcher<*, *>> = listOf( homeMatcher, userProfileMatcher, telMatcher ) class MainActivity : ComponentActivity() { override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) // ... // 3. Create a DeepLinkRequest from the incoming Intent val request = DeepLinkRequest(intent = intent) // 4. Match the request against all matchers and find the best match. // Because DeepLinkMatcher.MatchResult implements Comparable, you can // use maxOrNull() to find the best match. val matchResult = deepLinkMatchers .mapNotNull { it.match(request) } // List<DeepLinkMatcher.MatchResult<*>> .maxOrNull() // DeepLinkMatcher.MatchResult<*>? // 5. Create the back stack from the match result (or fall back to a default). val backStack: List<NavKey> = when (matchResult) { // If no match is found, use the default back stack (e.g., HomeKey) null -> listOf(HomeKey) // If a BackStackMatchResult is found, use the back stack from the result is BackStackMatchResult<*, *> -> { // Because star-projected matchers erase the key type, cast the back stack to List<NavKey>. @Suppress("UNCHECKED_CAST") matchResult.backStack as List<NavKey> } // Otherwise, use the key from the match result to make a single-item back stack else -> listOf(matchResult.key as NavKey) } } }