ตั้งแต่เวอร์ชัน 1.2.0 เป็นต้นไป Navigation 3 รองรับการทำ Deep Link ไปยังปลายทางในแอปโดยใช้คลาส DeepLinkRequest และ DeepLinkMatcher
หากต้องการรองรับ Deep Link ในแอป ให้ทำตามขั้นตอนต่อไปนี้
- กำหนดตัวกรอง Intent ใน
AndroidManifest.xmlเพื่อระบุ URI ที่แอปของคุณจัดการได้ - สร้างอินสแตนซ์
DeepLinkMatcherรายการเพื่อแมปคำขอขาเข้ากับคีย์การนำทาง - จับคู่คำขอที่เข้ามาในเมธอด
onCreateหรือonNewIntentของกิจกรรม และอัปเดต Back Stack ตามความเหมาะสม
สร้าง DeepLinkRequest
DeepLinkRequest แสดงถึง Deep Link ขาเข้า ซึ่งประกอบด้วย DeepLinkUri และ RequestExtras (ไม่บังคับ) ที่มีข้อมูลเพิ่มเติม เช่น การดำเนินการตาม Intent หรือประเภท 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 รายการ
หากต้องการจัดเก็บข้อมูลเพิ่มเติมที่เกี่ยวข้องกับ Deep Link ให้ใช้คลาส RequestExtras ไลบรารีมีอินเทอร์เฟซ RequestExtrasKey และ DSL requestExtras เพื่อให้การกำหนดและสร้างอินสแตนซ์ของข้อมูลเพิ่มเติมมีความปลอดภัยในการกำหนดประเภท
นอกจากนี้ ไลบรารียังมีคีย์เพิ่มเติม 2 รายการและตัวช่วยที่เกี่ยวข้อง ดังนี้
MimeTypeExtrasKey: ใช้เพื่อจัดเก็บประเภท MIMEStringActionExtrasKey(Android เท่านั้น): ใช้เพื่อจัดเก็บการดำเนินการของIntentString
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ของ Intent - หากไม่เป็นค่า Null ระบบจะตั้งค่าประเภท MIME และส่วนเสริมของการดำเนินการจากช่อง Intent ที่เกี่ยวข้อง
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 ขาเข้ากับคีย์การนำทางที่เพิ่มลงใน Back Stack ของแอปได้ Navigation 3 มี Matcher ในตัว 3 รายการ ได้แก่ UriDeepLinkMatcher สำหรับการจับคู่ URI ตามรูปแบบ, StaticKeyDeepLinkMatcher สำหรับลิงก์พื้นฐาน และ BackStackMatcher สำหรับการสร้าง Back Stack สังเคราะห์ นอกจากนี้ ไลบรารียังรองรับตัวจับคู่ที่กำหนดเองสำหรับกรณีการใช้งานที่ตัวจับคู่ในตัวไม่ครอบคลุม
ดูข้อมูลเพิ่มเติมได้ที่สร้าง DeepLinkMatchers
เพิ่มตัวกรอง Intent
หากต้องการเปิดใช้ Deep Link เพื่อเริ่มกิจกรรม คุณต้องกำหนดองค์ประกอบ <intent-filter> ที่ตรงกันใน AndroidManifest.xml ของแอป ดูข้อมูลเพิ่มเติมได้ที่เพิ่มตัวกรอง Intent สำหรับลิงก์ขาเข้า
จับคู่คำขอที่เข้ามา
หลังจากสร้างอินสแตนซ์ DeepLinkMatcher แล้ว คุณจะจับคู่คำขอที่เข้ามาในกิจกรรมได้
หากต้องการจับคู่คำขอที่เข้ามา ให้ทำตามขั้นตอนต่อไปนี้
- สร้างอินสแตนซ์
DeepLinkMatcherของคุณ - เปรียบเทียบอินสแตนซ์
DeepLinkMatcherทั้งหมด ไม่ว่าจะระบุอย่างชัดเจนหรือใช้การเชื่อมโยงหลายรายการ - สร้าง
DeepLinkRequestจากIntentที่เข้ามา - จับคู่คำขอกับตัวจับคู่ทั้งหมดและค้นหารายการที่ตรงกันที่สุด
- สร้าง Back Stack จากผลการจับคู่
// 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) } } }