ตั้งแต่เวอร์ชัน 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: ใช้เพื่อจัดเก็บStringประเภท MIMEActionExtrasKey(Android เท่านั้น): ใช้เพื่อจัดเก็บการดำเนินการของIntent'sString.
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 สังเคราะห์ นอกจากนี้ ไลบรารียัง
รองรับ Matcher ที่กำหนดเองสำหรับกรณีการใช้งานที่ Matcher ในตัวไม่ครอบคลุม
ดูข้อมูลเพิ่มเติมได้ที่สร้าง DeepLinkMatchers
เพิ่มตัวกรอง Intent
หากต้องการเปิดใช้ Deep Link เพื่อเริ่มกิจกรรม คุณต้องกำหนดองค์ประกอบที่ตรงกัน
<intent-filter> ใน AndroidManifest.xml ของแอป ดูข้อมูลเพิ่มเติมได้ที่
เพิ่มตัวกรอง Intent สำหรับลิงก์ขาเข้า
จับคู่คำขอขาเข้า
หลังจากที่คุณสร้างอินสแตนซ์ DeepLinkMatcher แล้ว คุณจะจับคู่คำขอขาเข้า
ในกิจกรรมได้
หากต้องการจับคู่คำขอขาเข้า ให้ทำตามขั้นตอนต่อไปนี้
- สร้างอินสแตนซ์
DeepLinkMatcher - รวบรวม อินสแตนซ์
DeepLinkMatcherทั้งหมด ไม่ว่าจะโดยชัดแจ้งหรือ โดยใช้ Multibindings - สร้าง
DeepLinkRequestจากIntentขาเข้า - จับคู่ คำขอกับ Matcher ทั้งหมดและค้นหารายการที่ตรงกันมากที่สุด
- สร้าง 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) } } }