ใน Android Deep Link คือลิงก์ที่จะนำคุณไปยังปลายทางที่เฉพาะเจาะจงภายในแอปโดยตรง
คุณรองรับ Deep Link ได้ 2 ประเภทในแอป ได้แก่ Explicit และ Implicit วิธีติดตั้งใช้งาน Deep Link จะแตกต่างกันไปตามประเภทกราฟ
ที่แอปใช้ ซึ่งอาจเป็น XML or programmatic
สร้าง Explicit Deep Link
Explicit Deep Link คือ Deep Link อินสแตนซ์เดียวที่ใช้ PendingIntentเพื่อนำผู้ใช้ไปยังตำแหน่งที่เฉพาะเจาะจงภายในแอป คุณอาจแสดง Explicit Deep Link เป็นส่วนหนึ่งของการแจ้งเตือนหรือวิดเจ็ตของแอป เป็นต้น
เมื่อผู้ใช้เปิดแอปผ่าน Explicit Deep Link ระบบจะล้าง Task Back Stack และแทนที่ด้วยปลายทางของ Deep Link เมื่อ
ซ้อนกราฟ,
ระบบจะเพิ่มปลายทางเริ่มต้นจากแต่ละระดับการซ้อน ซึ่งก็คือปลายทางเริ่มต้น
จากองค์ประกอบ <navigation> แต่ละรายการในลำดับชั้นลงในสแต็กด้วย
ซึ่งหมายความว่าเมื่อผู้ใช้กดปุ่มย้อนกลับจากปลายทางของ Deep Link ผู้ใช้จะย้อนกลับขึ้นไปตาม Navigation Stack เช่นเดียวกับที่เข้าแอปจากจุดเริ่มต้น
กราฟแบบเป็นโปรแกรม
หากคุณกำหนดกราฟการนำทางแบบเป็นโปรแกรม (ตามที่พบได้ทั่วไปใน Navigation Compose หรือ Kotlin DSL) เราขอแนะนำให้ใช้ TaskStackBuilder เพื่อสร้าง PendingIntent ของ Deep Link
val id = "exampleId"
val context = LocalContext.current
val deepLinkIntent = Intent(
Intent.ACTION_VIEW,
"https://www.example.com/profile/$id".toUri(),
context,
MyActivity::class.java
)
val pendingIntent: PendingIntent? = TaskStackBuilder.create(context).run {
addNextIntentWithParentStack(deepLinkIntent)
getPendingIntent(0, PendingIntent.FLAG_UPDATE_CURRENT)
}
กราฟ XML
คุณสามารถใช้ NavDeepLinkBuilder
คลาสเพื่อสร้าง PendingIntent,
ดังที่แสดงในตัวอย่างด้านล่าง โปรดทราบว่าหากบริบทที่ระบุไม่ใช่
Activity คอนสตรักเตอร์จะใช้
PackageManager.getLaunchIntentForPackage()
เป็นกิจกรรมเริ่มต้นที่จะเปิด หากมี
Kotlin
val pendingIntent = NavDeepLinkBuilder(context) .setGraph(R.navigation.nav_graph) .setDestination(R.id.android) .setArguments(args) .createPendingIntent()
Java
PendingIntent pendingIntent = new NavDeepLinkBuilder(context) .setGraph(R.navigation.nav_graph) .setDestination(R.id.android) .setArguments(args) .createPendingIntent();
โดยค่าเริ่มต้น NavDeepLinkBuilder จะเปิด Explicit Deep Link ใน Activity เริ่มต้นที่ประกาศไว้ในไฟล์ Manifest ของแอป หาก NavHost อยู่ในกิจกรรมอื่น คุณต้องระบุชื่อคอมโพเนนต์เมื่อสร้างตัวสร้าง Deep Link ดังนี้
Kotlin
val pendingIntent = NavDeepLinkBuilder(context) .setGraph(R.navigation.nav_graph) .setDestination(R.id.android) .setArguments(args) .setComponentName(DestinationActivity::class.java) .createPendingIntent()
Java
PendingIntent pendingIntent = new NavDeepLinkBuilder(context) .setGraph(R.navigation.nav_graph) .setDestination(R.id.android) .setArguments(args) .setComponentName(DestinationActivity.class) .createPendingIntent();
หากคุณมี ComponentName,
คุณสามารถส่งผ่านไปยังตัวสร้างได้โดยตรง ดังนี้
Kotlin
val componentName = ... val pendingIntent = NavDeepLinkBuilder(context) .setGraph(R.navigation.nav_graph) .setDestination(R.id.android) .setArguments(args) .setComponentName(componentName) .createPendingIntent()
Java
ComponentName componentName = ...; PendingIntent pendingIntent = new NavDeepLinkBuilder(context) .setGraph(R.navigation.nav_graph) .setDestination(R.id.android) .setArguments(args) .setComponentName(componentName) .createPendingIntent();
หากคุณมี NavController อยู่แล้ว
คุณยังสร้าง Deep Link ได้โดยใช้
NavController.createDeepLink()
สร้าง Implicit Deep Link
Implicit Deep Link หมายถึง ปลายทางที่เฉพาะเจาะจงในแอป เมื่อมีการเรียกใช้ Deep Link เช่น เมื่อผู้ใช้คลิกลิงก์ Android จะเปิดแอปของคุณไปยังปลายทางที่เกี่ยวข้องได้
ระบบจะจับคู่ Deep Link ตาม URI, การดำเนินการของ Intent และประเภท MIME คุณระบุประเภทการจับคู่หลายรายการสำหรับ Deep Link รายการเดียวได้ แต่โปรดทราบว่าระบบจะจัดลำดับความสำคัญของการจับคู่อาร์กิวเมนต์ URI ก่อน ตามด้วยการดำเนินการ แล้วจึงเป็นประเภท MIME
กราฟแบบเป็นโปรแกรม
หากคุณกำหนดกราฟการนำทางแบบเป็นโปรแกรม (โดยใช้ Navigation Compose หรือ Kotlin DSL) คุณจะกำหนด Deep Link ในโค้ด
Compose
ใน Navigation Compose คุณสามารถกำหนด Deep Link เป็นส่วนหนึ่งของตัวสร้างปลายทาง composable() โดยใช้พารามิเตอร์ deepLinks ซึ่งจะยอมรับรายการออบเจ็กต์
NavDeepLink ที่คุณสร้างได้โดยใช้ฟังก์ชัน
navDeepLink() ดังนี้
@Serializable
data class Profile(val id: String)
val uri = "https://www.example.com"
composable<Profile>(
deepLinks = listOf(
navDeepLink<Profile>(basePath = "$uri/profile")
)
) { backStackEntry ->
val profile: Profile = backStackEntry.toRoute()
ProfileScreen(id = profile.id)
}
Kotlin DSL
เมื่อใช้ Kotlin DSL คุณสามารถกำหนด Deep Link ได้โดยใช้ฟังก์ชันตัวสร้าง
deepLink() ภายในบล็อกปลายทาง
ดังนี้
@Serializable
data class Profile(val id: String)
val uri = "https://www.example.com"
fragment<ProfileFragment, Profile> {
deepLink<Profile>(basePath = "$uri/profile")
}
เพิ่มตัวกรอง Intent สำหรับกราฟแบบเป็นโปรแกรม
เนื่องจากระบบจะสร้างกราฟการนำทางแบบเป็นโปรแกรมในรันไทม์ คอมโพเนนต์การนำทาง
จึงไม่สามารถสร้างองค์ประกอบ <intent-filter> ที่ตรงกัน
ใน AndroidManifest.xml โดยอัตโนมัติ คุณต้องเพิ่มองค์ประกอบที่เหมาะสมด้วยตนเอง
<intent-filter>
หากต้องการเปิดใช้ Deep Link ในตัวอย่างก่อนหน้า ให้เพิ่มโค้ดต่อไปนี้ภายในองค์ประกอบที่เกี่ยวข้อง
<activity> ในไฟล์ Manifest
<activity …>
<intent-filter>
...
<data android:scheme="https" android:host="www.example.com" />
</intent-filter>
</activity>
กราฟ XML
หากต้องการสร้าง Implicit Deep Link ในกราฟที่อิงตาม XML คุณสามารถกำหนดองค์ประกอบ
<deepLink> ใน XML ได้โดยตรง หรือใช้เครื่องมือแก้ไขการนำทาง
ตัวอย่าง Deep Link ที่มี URI, การดำเนินการ และประเภท MIME
<fragment android:id="@+id/a"
android:name="com.example.myapplication.FragmentA"
tools:layout="@layout/a">
<deepLink app:uri="www.example.com"
app:action="android.intent.action.MY_ACTION"
app:mimeType="type/subtype"/>
</fragment>
นอกจากนี้ คุณยังใช้เครื่องมือแก้ไขการนำทางเพื่อสร้าง Implicit Deep Link ไปยังปลายทางได้ดังนี้
- ในแท็บดีไซน์ ของเครื่องมือแก้ไขการนำทาง ให้เลือกปลายทางสำหรับ Deep Link
- คลิก + ในส่วน Deep Link ของแผงแอตทริบิวต์
ในกล่องโต้ตอบเพิ่ม Deep Link ที่ปรากฏขึ้น ให้ป้อนข้อมูลสำหรับ Deep Link
ข้อควรทราบ
- ระบบจะถือว่า URI ที่ไม่มีรูปแบบเป็น
httpหรือhttpsเช่นwww.google.comจะตรงกับทั้งhttp://www.google.comและhttps://www.google.com - ตัวยึดตำแหน่งพารามิเตอร์เส้นทางในรูปแบบ
{placeholder_name}จะตรงกับอักขระอย่างน้อย 1 ตัว เช่นhttp://www.example.com/users/{id}จะตรงกับhttp://www.example.com/users/4คอมโพเนนต์การนำทางจะพยายาม แยกวิเคราะห์ค่าตัวยึดตำแหน่งเป็นประเภทที่เหมาะสมโดยการจับคู่ชื่อตัวยึดตำแหน่งกับ อาร์กิวเมนต์ที่กำหนดไว้สำหรับ ปลายทางของ Deep Link หากไม่มีการกำหนดอาร์กิวเมนต์ที่มีชื่อเดียวกัน ระบบจะใช้ประเภทStringเริ่มต้นสำหรับค่าอาร์กิวเมนต์ คุณสามารถใช้ไวลด์การ์ด .* เพื่อจับคู่อักขระตั้งแต่ 0 ตัวขึ้นไป - คุณสามารถใช้ตัวยึดตำแหน่งพารามิเตอร์การค้นหาแทนหรือร่วมกับพารามิเตอร์เส้นทางได้ เช่น
http://www.example.com/users/{id}?myarg={myarg}จะตรงกับhttp://www.example.com/users/4?myarg=28 - ตัวยึดตำแหน่งพารามิเตอร์การค้นหาสำหรับตัวแปรที่กำหนดด้วยค่าเริ่มต้นหรือค่าที่อนุญาตให้เป็น Null ไม่จำเป็นต้องตรงกัน เช่น
http://www.example.com/users/{id}?arg1={arg1}&arg2={arg2}จะตรงกับhttp://www.example.com/users/4?arg2=28หรือhttp://www.example.com/users/4?arg1=7แต่จะไม่เป็นเช่นนั้นกับพารามิเตอร์เส้นทาง เช่นhttp://www.example.com/users?arg1=7&arg2=28จะไม่ตรงกับรูปแบบด้านบนเนื่องจากไม่มีการระบุพารามิเตอร์เส้นทางที่จำเป็น - พารามิเตอร์การค้นหาที่ไม่เกี่ยวข้องจะไม่ส่งผลต่อการจับคู่ URI ของ Deep Link เช่น
http://www.example.com/users/{id}จะตรงกับhttp://www.example.com/users/4?extraneousParam=7แม้ว่าจะไม่ได้กำหนดextraneousParamไว้ในรูปแบบ URI ก็ตาม
- ระบบจะถือว่า URI ที่ไม่มีรูปแบบเป็น
(ไม่บังคับ) เลือกยืนยันอัตโนมัติ เพื่อกำหนดให้ Google ยืนยันว่าคุณเป็นเจ้าของ URI ดูข้อมูลเพิ่มเติมได้ที่ ยืนยัน Android App Link
คลิกเพิ่ม ไอคอนลิงก์
จะปรากฏขึ้นเหนือปลายทางที่เลือกเพื่อระบุว่าปลายทางนั้นมี
Deep Linkคลิกแท็บโค้ด เพื่อเปลี่ยนเป็นมุมมอง XML ระบบได้เพิ่มองค์ประกอบ
<deepLink>แบบซ้อนลงในปลายทางแล้ว ดังนี้<deepLink app:uri="https://www.google.com" />
หากต้องการเปิดใช้ Implicit Deep Link สำหรับกราฟที่อิงตาม XML คุณต้องเพิ่มโค้ดลงในไฟล์ manifest.xml ของแอปด้วย เพิ่มองค์ประกอบ <nav-graph>
รายการเดียวลงในกิจกรรมที่ชี้ไปยังกราฟการนำทางที่มีอยู่ ดังที่แสดง
ในตัวอย่างต่อไปนี้
<?xml version="1.0" encoding="utf-8"?> <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.example.myapplication"> <application ... > <activity name=".MainActivity" ...> ... <nav-graph android:value="@navigation/nav_graph" /> ... </activity> </application> </manifest>
เมื่อสร้างโปรเจ็กต์ คอมโพเนนต์การนำทางจะแทนที่องค์ประกอบ <nav-graph>
ด้วยองค์ประกอบ <intent-filter> ที่สร้างขึ้นเพื่อให้ตรงกับ Deep Link ทั้งหมด
ในกราฟการนำทาง
Implicit Deep Link และ Back Stack
เมื่อทริกเกอร์ Implicit Deep Link สถานะของ Back Stack จะขึ้นอยู่กับ
ว่ามีการเปิดใช้ Intent โดยนัยด้วย
Intent.FLAG_ACTIVITY_NEW_TASK
แฟล็กหรือไม่
- หากมีการตั้งค่าแฟล็ก ระบบจะล้าง Task Back Stack และแทนที่ด้วยปลายทางของ Deep Link เช่นเดียวกับ Explicit Deep Link เมื่อ
ซ้อนกราฟ
ระบบจะเพิ่มปลายทางเริ่มต้นจากแต่ละระดับการซ้อน ซึ่งก็คือปลายทางเริ่มต้นจากองค์ประกอบ
<navigation>แต่ละรายการในลำดับชั้นลงใน สแต็กด้วย ซึ่งหมายความว่าเมื่อผู้ใช้กดปุ่มย้อนกลับจากปลายทางของ Deep Link ผู้ใช้จะย้อนกลับขึ้นไปตาม Navigation Stack เช่นเดียวกับที่เข้าแอปจากจุดเริ่มต้น - หากไม่ได้ตั้งค่าแฟล็ก คุณจะยังคงอยู่ใน Task Stack ของแอปก่อนหน้าซึ่งมีการทริกเกอร์ Implicit Deep Link ในกรณีนี้ ปุ่มย้อนกลับจะนำคุณกลับไปยังแอปก่อนหน้า ส่วนปุ่มขึ้นจะเริ่ม Task ของแอปในปลายทางระดับบนสุดในลำดับชั้นภายในกราฟการนำทาง
จัดการ Deep Link
เราขอแนะนำอย่างยิ่งให้ใช้ค่าเริ่มต้น
launchMode ของ standard
เสมอเมื่อใช้การนำทาง เมื่อใช้โหมดเปิดใช้งาน standard การนำทาง จะจัดการ Deep Link โดยอัตโนมัติด้วยการเรียกใช้ handleDeepLink() เพื่อประมวลผล Explicit หรือ Implicit Deep Link ภายใน Intent อย่างไรก็ตาม การดำเนินการนี้จะไม่เกิดขึ้นโดยอัตโนมัติหากมีการนำ Activity กลับมาใช้ซ้ำเมื่อใช้ launchMode อื่น เช่น singleTop ในกรณีนี้ คุณต้องเรียกใช้ handleDeepLink() ใน onNewIntent() ด้วยตนเอง ดังที่แสดงในตัวอย่างต่อไปนี้
Kotlin
override fun onNewIntent(intent: Intent?) { super.onNewIntent(intent) navController.handleDeepLink(intent) }
Java
@Override protected void onNewIntent(Intent intent) { super.onNewIntent(intent); navController.handleDeepLink(intent); }