ทดสอบ App Link

เมื่อใช้ฟีเจอร์การลิงก์แอป คุณควรทดสอบฟังก์ชันการลิงก์เพื่อให้แน่ใจว่าระบบสามารถเชื่อมโยงแอปกับเว็บไซต์และจัดการคำขอ 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>&amp;
   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 - ระบุแอปตามชื่อแพ็กเกจตามที่ประกาศไว้ใน ไฟล์ Manifest
  • Domains - แสดงรายการโฮสต์ทั้งหมดที่แอปนี้จัดการลิงก์เว็บ โดยใช้ช่องว่างเป็นตัวคั่น
  • 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)

ดูข้อมูลเพิ่มเติมเกี่ยวกับรายการคำสั่งได้ที่ การสร้างรายการคำสั่ง

ตั้งแต่ 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) หากกฎนี้ตรงกัน ระบบจะอนุญาตให้แอปเปิด URI
    • allow = 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 (ตัวกรองแบบครอบคลุม)

วิธีที่การแก้ปัญหาทำงานในสถานการณ์นี้

  1. ทั้งกฎ 0 และกฎ 1 ตรงกับ URL https://xyz.com/foo
  2. ระบบจะประเมินกฎ App Link แบบไดนามิกตามลำดับจากบนลงล่าง (กฎแรกที่ตรงกันจะเป็นกฎที่ใช้)
  3. เนื่องจากกฎ 0 ปรากฏเป็นกฎแรกในรายการคำสั่งและเป็นกฎการยกเว้น (allow = 1) กฎนี้จึงมีความสำคัญเหนือกว่ากฎการอนุญาตทั่วไป (กฎ 1)
  4. ดังนั้น ระบบจึงยกเว้นแอปจากการจัดการ https://xyz.com/foo ซึ่งทำให้ระบบกลับไปใช้เบราว์เซอร์หรือแสดงกล่องโต้ตอบที่มีคำอธิบาย