เมื่อใช้ฟีเจอร์การลิงก์แอป คุณควรทดสอบฟังก์ชันการลิงก์เพื่อให้แน่ใจว่าระบบสามารถเชื่อมโยงแอปกับเว็บไซต์และจัดการคำขอ URL ได้ตามที่คุณต้องการ
หากต้องการทดสอบไฟล์คำสั่งที่มีอยู่ คุณสามารถใช้เครื่องมือสร้างรายการคำสั่ง และทดสอบ
ส่วนต่อไปนี้อธิบายวิธีทดสอบการยืนยัน App Link ด้วยตนเอง หรือคุณจะทดสอบการยืนยันจากเครื่องมือ Play Deep Links หรือผู้ช่วย App Link ของ Android Studio ก็ได้
ยืนยันรายการโฮสต์ที่จะยืนยัน
เมื่อทดสอบ คุณควรยืนยันรายการโฮสต์ที่เชื่อมโยงซึ่งระบบควรยืนยันสำหรับแอปของคุณ สร้างรายการ URL ทั้งหมดซึ่งตัวกรอง Intent ที่เกี่ยวข้องมีแอตทริบิวต์และองค์ประกอบต่อไปนี้
- แอตทริบิวต์
android:schemeที่มีค่าเป็นhttpหรือhttps - แอตทริบิวต์
android:hostที่มีรูปแบบ URL ของโดเมน - องค์ประกอบการดำเนินการ
android.intent.action.VIEW - องค์ประกอบหมวดหมู่
android.intent.category.BROWSABLE
ใช้รายการนี้เพื่อตรวจสอบว่ามีไฟล์ JSON ของลิงก์เนื้อหาดิจิทัล (Digital Asset Links) ในโฮสต์และโดเมนย่อยแต่ละรายการ
ยืนยันไฟล์ลิงก์เนื้อหาดิจิทัล (Digital Asset Links)
สำหรับเว็บไซต์แต่ละแห่ง ให้ใช้ Digital Asset Links API เพื่อยืนยันว่าไฟล์ JSON ของลิงก์เนื้อหาดิจิทัล (Digital Asset Links) ได้รับการโฮสต์และกำหนดไว้อย่างถูกต้อง
https://digitalassetlinks.googleapis.com/v1/statements:list?
source.web.site=https://<var>domain.name</var>:<var>optional_port</var>&
relation=delegate_permission/common.handle_all_urls
สำหรับ App Link แบบไดนามิก คุณยังตรวจสอบส่วนขยายความสัมพันธ์ได้ด้วย
https://digitalassetlinks.googleapis.com/v1/statements:list?source.web.site=https://www.example.com&relation=delegate_permission/common.handle_all_urls&return_relation_extensions=true
ตรวจสอบนโยบายลิงก์
คุณสามารถตรวจสอบการตั้งค่าระบบปัจจุบันสำหรับการจัดการลิงก์ได้ในกระบวนการทดสอบ ใช้คำสั่งต่อไปนี้เพื่อรับรายการนโยบายการจัดการลิงก์ที่มีอยู่สำหรับแอปทั้งหมดในอุปกรณ์ที่เชื่อมต่อ
adb shell dumpsys package domain-preferred-apps
คำสั่งต่อไปนี้จะทำหน้าที่เดียวกัน
adb shell dumpsys package d
คำสั่งจะแสดงรายการผู้ใช้หรือโปรไฟล์แต่ละรายการที่กำหนดไว้ในอุปกรณ์ โดยมีส่วนหัวในรูปแบบต่อไปนี้
App linkages for user 0:
หลังจากส่วนหัวนี้ เอาต์พุตจะใช้รูปแบบต่อไปนี้เพื่อแสดงการตั้งค่าการจัดการลิงก์สำหรับผู้ใช้รายนั้น
Package: com.android.vending
Domains: play.google.com market.android.com
Status: always : 200000002
รายการนี้จะระบุแอปที่เชื่อมโยงกับโดเมนใดสำหรับผู้ใช้รายนั้น
Package- ระบุแอปตามชื่อแพ็กเกจตามที่ประกาศไว้ใน ไฟล์ ManifestDomains- แสดงรายการโฮสต์ทั้งหมดที่แอปนี้จัดการลิงก์เว็บ โดยใช้ช่องว่างเป็นตัวคั่นStatus- แสดงการตั้งค่าการจัดการลิงก์ปัจจุบันสำหรับแอปนี้ แอปที่ ผ่านการยืนยันและไฟล์ Manifest มีandroid:autoVerify="true"จะแสดงสถานะเป็นalwaysตัวเลขฐานสิบหกหลังจากสถานะนี้เกี่ยวข้องกับบันทึกของระบบ Android เกี่ยวกับค่ากำหนดการลิงก์แอปของผู้ใช้ ค่านี้ไม่ได้ระบุว่าการยืนยันสำเร็จหรือไม่
ตัวอย่างการทดสอบ
การยืนยัน App Link จะสำเร็จได้ก็ต่อเมื่อระบบสามารถยืนยันแอปของคุณกับเว็บไซต์แต่ละแห่งที่คุณระบุไว้ในตัวกรอง Intent ที่เป็นไปตามเกณฑ์สำหรับ App Link ตัวอย่างต่อไปนี้แสดงการกำหนดค่าไฟล์ Manifest ที่มีการกำหนด App Link หลายรายการ
<activity android:name="MainActivity">
<intent-filter android:autoVerify="true">
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.DEFAULT" />
<category android:name="android.intent.category.BROWSABLE" />
<data android:scheme="https" />
<data android:scheme="https" />
<data android:host="www.example.com" />
<data android:host="mobile.example.com" />
</intent-filter>
<intent-filter>
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.BROWSABLE" />
<data android:scheme="https" />
<data android:host="www.example2.com" />
</intent-filter>
</activity>
<activity android:name="SecondActivity">
<intent-filter>
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.DEFAULT" />
<category android:name="android.intent.category.BROWSABLE" />
<data android:scheme="https" />
<data android:host="account.example.com" />
</intent-filter>
</activity>
<activity android:name="ThirdActivity">
<intent-filter>
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.DEFAULT" />
<data android:scheme="https" />
<data android:host="map.example.com" />
</intent-filter>
<intent-filter>
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.BROWSABLE" />
<data android:scheme="market" />
<data android:host="example.com" />
</intent-filter>
</activity>
</application>
รายการโฮสต์ที่แพลตฟอร์มจะพยายามยืนยันจากไฟล์ Manifest ข้างต้นมีดังนี้
www.example.com
mobile.example.com
www.example2.com
account.example.com
รายการโฮสต์ที่แพลตฟอร์มจะไม่พยายามยืนยันจากไฟล์ Manifest ข้างต้นมีดังนี้
map.example.com (it does not have android.intent.category.BROWSABLE)
market://example.com (it does not have either an "http" or "https" scheme)
ดูข้อมูลเพิ่มเติมเกี่ยวกับรายการคำสั่งได้ที่ การสร้างรายการคำสั่ง
วิเคราะห์การแก้ปัญหาลิงก์ด้วยแฟล็ก debug-link
ตั้งแต่ Android 17 เป็นต้นไป คุณสามารถใช้แฟล็ก --debug-link กับคำสั่ง Activity Manager (am start) เพื่อวิเคราะห์วิธีที่ระบบแก้ปัญหา URL ที่เฉพาะเจาะจง เครื่องมือนี้จะแสดงรายละเอียดของแอปที่ตรงกับ Intent พร้อมด้วยกฎเฉพาะจากไฟล์ Manifest ของแอปและไฟล์ assetlinks.json (สำหรับ App Link แบบไดนามิก) ที่ได้รับการประเมินระหว่างการแก้ปัญหา
หากต้องการทดสอบการแก้ปัญหาลิงก์สำหรับ URL ที่เฉพาะเจาะจง ให้เรียกใช้คำสั่งต่อไปนี้ในหน้าต่างเทอร์มินัล
adb shell am start --debug-link -a android.intent.action.VIEW -d "https://xyz.com/foo"
เอาต์พุตการวิเคราะห์จะพิมพ์ใต้ส่วนหัว App Link Resolution Debug และมีส่วนต่อไปนี้เพื่อช่วยให้คุณเข้าใจกระบวนการแก้ปัญหา
- รายละเอียดเป้าหมาย: ระบุแอปที่ตรงกันแต่ละแอปตามชื่อแพ็กเกจและกิจกรรมเป้าหมาย
- การจับคู่ตัวกรอง Intent (
AndroidManifest.xml): แสดงแอตทริบิวต์แบบคงที่ ในตัวกรอง Intent ของไฟล์ Manifest (เช่นscheme,host,path,pathPrefixหรือpathPattern) ที่ตรงกับ URI - การยืนยัน App Link: แสดงสถานะการยืนยันโดเมนปัจจุบัน (เช่น
STATE_SUCCESS) - App Link แบบไดนามิก: หากแอปใช้กฎการจับคู่ App Link แบบไดนามิกในไฟล์
assetlinks.jsonส่วนนี้จะแสดงรายการกฎทุกข้อที่ได้รับการประเมินกับ URI กฎแต่ละข้อจะระบุตัวกรอง URI ที่ตรงกัน (เช่น คำนำหน้าหรือรูปแบบเส้นทาง) และช่องallowดังนี้allow = 0: กฎอนุญาต/รวม (allow: true) หากกฎนี้ตรงกัน ระบบจะอนุญาตให้แอปเปิด URIallow = 1: กฎบล็อก/ยกเว้น (allow: false/exclude: true) หากกฎนี้ตรงกัน ระบบจะป้องกันไม่ให้แอปเปิด URI- หมายเหตุ: สตริงตัวกรองที่ว่างเปล่า (
filter =) จะระบุคำนำหน้าเส้นทางที่ว่างเปล่าซึ่งตรงกับเส้นทางทั้งหมดภายใต้โดเมน (ทำหน้าที่เป็นไวลด์การ์ดหรือตัวกรองแบบครอบคลุม)
ตัวอย่างเอาต์พุตการแก้ไขข้อบกพร่อง
พิจารณาแอป (com.example.xyzapp) ที่เชื่อมโยงกับโดเมน https://xyz.com ซึ่งกำหนดกฎแบบไดนามิกในไฟล์ assetlinks.json เพื่อยกเว้น /foo* ขณะที่อนุญาตเส้นทางอื่นๆ ทั้งหมด
[
{
"relation": [
"delegate_permission/common.handle_all_urls"
],
"target": {
"namespace": "android_app",
"package_name": "com.example.xyzapp",
"sha256_cert_fingerprints": ["..."]
},
"relation_extensions": {
"delegate_permission/common.handle_all_urls": {
"dynamic_app_link_components": [
{"/": "/foo*", "exclude": true},
{"/": "*"}
]
}
}
}
]
เมื่อวิเคราะห์ URL https://xyz.com/foo โดยใช้ --debug-link
adb shell am start --debug-link -a android.intent.action.VIEW -d "https://xyz.com/foo"
คำสั่งจะแสดงรายละเอียดการวิเคราะห์ต่อไปนี้
--- App Link Resolution Debug ---
URI: https://xyz.com/foo
Resolution: Ambiguous (Multiple apps or Browser fallback)
This usually happens when multiple apps can handle the link and no default is set.
All Matching Candidates:
Target:
Package: com.example.xyzapp
Activity: com.example.xyzapp.MainActivity
Intent Filter Match (AndroidManifest.xml)
Scheme: 'https' matched android:scheme="https"
Host: 'xyz.com' matched android:host="xyz.com"
App Link Verification:
Verification status: STATE_SUCCESS
Dynamic App Links:
-> Matched Rule 0: UriRelativeFilterGroup { allow = 1, uri_filters = {UriRelativeFilter { uriPart = PATH, patternType = PREFIX, filter = /foo }}, }
-> Matched Rule 1: UriRelativeFilterGroup { allow = 0, uri_filters = {UriRelativeFilter { uriPart = PATH, patternType = PREFIX, filter = }}, }
Target:
Package: org.chromium.webview_shell
Activity: org.chromium.webview_shell.WebViewBrowserActivity
Intent Filter Match (AndroidManifest.xml)
Scheme: 'https' matched android:scheme="https"
---------------------------------
Starting: Intent { act=android.intent.action.VIEW dat=https://xyz.com/foo }
ในตัวอย่างนี้ ระบบได้ประเมินกฎ App Link แบบไดนามิก 2 ข้อจาก assetlinks.json ดังนี้
- กฎ 0 (
allow = 1,filter = /foo): สร้างจาก{"/": "/foo*", "exclude": true}ซึ่งเป็นกฎการยกเว้น (allow: false) ที่บล็อก URL ที่ขึ้นต้นด้วยคำนำหน้าเส้นทาง/foo - กฎ 1 (
allow = 0,filter =): สร้างจาก{"/": "*"}, ซึ่งเป็น กฎการรวม (allow: true) ที่มีคำนำหน้าเส้นทางที่ว่างเปล่า (filter =) ซึ่งตรงกับเส้นทางทั้งหมดภายใต้xyz.com(ตัวกรองแบบครอบคลุม)
วิธีที่การแก้ปัญหาทำงานในสถานการณ์นี้
- ทั้งกฎ 0 และกฎ 1 ตรงกับ URL
https://xyz.com/foo - ระบบจะประเมินกฎ App Link แบบไดนามิกตามลำดับจากบนลงล่าง (กฎแรกที่ตรงกันจะเป็นกฎที่ใช้)
- เนื่องจากกฎ 0 ปรากฏเป็นกฎแรกในรายการคำสั่งและเป็นกฎการยกเว้น (
allow = 1) กฎนี้จึงมีความสำคัญเหนือกว่ากฎการอนุญาตทั่วไป (กฎ 1) - ดังนั้น ระบบจึงยกเว้นแอปจากการจัดการ
https://xyz.com/fooซึ่งทำให้ระบบกลับไปใช้เบราว์เซอร์หรือแสดงกล่องโต้ตอบที่มีคำอธิบาย