정적 URI 딥 링크 레시피

이 레시피에서는 정적 URI로 딥 링크하는 방법을 보여줍니다.

레시피 구성요소

레시피에는 두 가지 활동이 포함되어 있습니다.

  1. 딥 링크 URI로 인텐트를 구성하고 시작하는 StaticUriDeepLinkActivity
  2. MainActivity는 딥 링크의 타겟 활동으로, 사용자가 딥 링크할 수 있는 앱을 나타냅니다.
  1. 딥 링크 소스 (StaticUriDeepLinkActivity)는 URI를 정의하고 딥 링크할 인텐트를 만듭니다.
  2. 앱 (MainActivity)은 탐색 키 (HomeKey)를 선언합니다. HomeKey가 딥 링크를 지원함을 나타내기 위해 앱은 HomeKey 직렬 변환기와 함께 HomeKey가 지원하는 URI 패턴으로 UriDeepLinkMatcher를 선언합니다.
  3. MainActivity onCreate는 인텐트로 DeepLinkRequest를 인스턴스화하고 UriDeepLinkMatcher와 일치시켜 MatchResult를 가져옵니다. MatchResult가 null이 아니면 앱은 결과에서 반환된 키로 이동합니다. 그렇지 않으면 딥 링크가 지원되지 않으며 앱은 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>(),
)