وصفة معرّف الموارد المنتظم (URI) الثابت للرابط العميق

يوضّح هذا المثال كيفية إنشاء رابط لصفحة في التطبيق باستخدام معرّف موارد موحّد ثابت.

مكوّنات إعداد مسبق

تحتوي الوصفة على نشاطَين:

  1. StaticUriDeepLinkActivity لإنشاء Intent وبدء تشغيله باستخدام معرّف الموارد المنتظم (URI) للرابط لصفحة في التطبيق
  2. ‫MainActivity هو النشاط المستهدف للرابط لصفحة في التطبيق، ويمثّل تطبيقًا يمكن للمستخدمين إنشاء رابط لصفحة فيه.
  1. يحدّد مصدر الرابط لصفحة في التطبيق (StaticUriDeepLinkActivity) معرّف الموارد المنتظم (URI) وينشئ Intent للربط العميق.
  2. يحدّد التطبيق (MainActivity) مفتاح تنقّل (HomeKey). للإشارة إلى أنّ HomeKey يتيح الربط بصفحات في التطبيق، يحدّد التطبيق UriDeepLinkMatcher باستخدام أداة التسلسل HomeKey بالإضافة إلى نمط معرّف الموارد المنتظم الذي يتيحه HomeKey.
  3. تنشئ الدالة MainActivity onCreate مثيلاً من DeepLinkRequest باستخدام الغرض وتطابقه مع UriDeepLinkMatcher للحصول على MatchResult. إذا كانت قيمة MatchResult غير فارغة، سينتقل التطبيق إلى المفتاح الذي تعرضه النتيجة. وفي ما عدا ذلك، لن يكون الرابط لصفحة معيّنة في التطبيق متاحًا وسينتقِل التطبيق إلى شاشة Fallback.
package com.example.nav3recipes.deeplink.handlerequests.staticuri

import android.content.Intent
import android.os.Bundle
import androidx.activity.ComponentActivity
import androidx.activity.compose.setContent
import androidx.core.net.toUri
import androidx.lifecycle.compose.dropUnlessResumed
import com.example.nav3recipes.common.deeplink.EntryScreen
import com.example.nav3recipes.common.deeplink.PaddedButton
import com.example.nav3recipes.common.deeplink.TextContent
import com.example.nav3recipes.deeplink.handlerequests.uriarguments.ui.PATH_BASE
import com.example.nav3recipes.ui.setEdgeToEdgeConfig

const val HOME_URI = "$PATH_BASE/home"

class StaticUriDeepLinkActivity : ComponentActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        setEdgeToEdgeConfig()
        super.onCreate(savedInstanceState)

        setContent {
            EntryScreen("Deep link url:") {
                TextContent(HOME_URI)
                PaddedButton("Deeplink Away!", onClick = dropUnlessResumed {
                    val intent = Intent(
                        this@StaticUriDeepLinkActivity,
                        MainActivity::class.java
                    )
                    // the uri to deep link with
                    intent.data = HOME_URI.toUri()
                    startActivity(intent)
                })
            }
        }
    }
}
package com.example.nav3recipes.deeplink.handlerequests.staticuri

import android.os.Bundle
import androidx.activity.ComponentActivity
import androidx.activity.compose.setContent
import androidx.navigation3.runtime.NavBackStack
import androidx.navigation3.runtime.NavKey
import androidx.navigation3.runtime.entryProvider
import androidx.navigation3.runtime.rememberNavBackStack
import androidx.navigation3.ui.NavDisplay
import com.example.nav3recipes.common.deeplink.EntryScreen
import com.example.nav3recipes.common.deeplink.TextContent
import com.example.nav3recipes.deeplink.handlerequests.uriarguments.HomeKey
import com.example.nav3recipes.deeplink.handlerequests.uriarguments.NavRecipeKey
import androidx.navigation3.runtime.deeplink.DeepLinkRequest
import androidx.navigation3.runtime.deeplink.DeepLinkUri
import androidx.navigation3.runtime.deeplink.UriDeepLinkMatcher
import androidx.navigation3.runtime.deeplink.invoke
import com.example.nav3recipes.ui.setEdgeToEdgeConfig
import kotlinx.serialization.Serializable
import kotlinx.serialization.serializer


@Serializable
internal object FallbackKey: NavRecipeKey {
    override val name: String = "Fallback Key"
}

class MainActivity : ComponentActivity() {

    override fun onCreate(savedInstanceState: Bundle?) {
        setEdgeToEdgeConfig()
        super.onCreate(savedInstanceState)

        // create a DeepLinkRequest with the intent
        val request = DeepLinkRequest(intent)

        // try to match DeepLinkRequest to a DeepLinkMatcher
        val matchResult = HOME_MATCHER.match(request)
        val key = matchResult?.key ?: FallbackKey

        /**
         * Then pass starting key to backstack
         */
        setContent {
            val backStack: NavBackStack<NavKey> = rememberNavBackStack(key)
            NavDisplay(
                backStack = backStack,
                onBack = { backStack.removeLastOrNull() },
                entryProvider = entryProvider {
                    entry<HomeKey> { key ->
                        EntryScreen(key.name) {
                            TextContent("Deep linked to Home")
                        }
                    }
                    entry<FallbackKey> { key ->
                        EntryScreen("${key.name} ") {
                            TextContent(
                                "Failed to deep link - DeepLinkRequest " +
                                    "did not match with any DeepLinkMatcher"
                            )
                        }
                    }

                }
            )
        }
    }
}

/**
 * Each matcher is associated with a navigation key that supports this deep link.
 *
 * A navigation key can be associated with multiple DeepLinkMatchers if it supports more than one deep link.
 */
private val HOME_MATCHER = UriDeepLinkMatcher(
    uriPattern = DeepLinkUri(HOME_URI),
    serializer = serializer<HomeKey>(),
)