ยืนยัน Android App Link

Android App Link เป็น Deep Link ประเภทพิเศษที่ช่วยให้ URL ของเว็บไซต์เปิดเนื้อหาที่เกี่ยวข้องในแอป Android ได้ทันทีโดยไม่ต้องให้ผู้ใช้เลือกแอป Android App Link ใช้ Digital Asset Links API เพื่อสร้างการเชื่อถือว่าเว็บไซต์ได้อนุมัติแอปของคุณให้เปิดลิงก์สำหรับโดเมนนั้นโดยอัตโนมัติ หากระบบยืนยันว่าคุณเป็นเจ้าของ URL ดังกล่าวเรียบร้อยแล้ว ระบบจะกำหนดเส้นทาง Intent ของ URL เหล่านั้นไปยังแอปของคุณโดยอัตโนมัติ

หากต้องการยืนยันว่าคุณเป็นเจ้าของทั้งแอปและ URL ของเว็บไซต์ ให้ทําตามขั้นตอนต่อไปนี้

  1. เพิ่มตัวกรอง Intent ที่มีแอตทริบิวต์ autoVerify แอตทริบิวต์นี้จะส่งสัญญาณให้ระบบทราบว่าควรยืนยันหรือไม่ว่าแอปของคุณเป็นของโดเมน URL ที่ใช้ในการกรอง Intent

  2. ประกาศการเชื่อมโยงระหว่างเว็บไซต์กับตัวกรอง Intent โดยโฮสต์ไฟล์ JSON ของลิงก์เนื้อหาดิจิทัล (Digital Asset Links) ในตำแหน่งต่อไปนี้

    https://domain.name/.well-known/assetlinks.json

ดูข้อมูลที่เกี่ยวข้องได้ในแหล่งข้อมูลต่อไปนี้

เพิ่มตัวกรอง Intent สําหรับการตรวจสอบ App Link

หากต้องการเปิดใช้การยืนยันการจัดการลิงก์สําหรับแอป ให้เพิ่มตัวกรอง Intent ที่ตรงกับรูปแบบต่อไปนี้

<!-- Make sure you explicitly set android:autoVerify to "true". -->
<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" />

    <!-- If a user clicks on a shared link that uses the "http" scheme, your
         app should be able to delegate that traffic to "https". -->
    <!-- Do not include other schemes. -->
    <data android:scheme="http" />
    <data android:scheme="https" />

    <!-- Include one or more domains that should be verified. -->
    <data android:host="..." />
</intent-filter>

แม้ว่าการใส่ autoVerify ไว้ในประกาศ <intent-filter> รายการเดียวสำหรับแต่ละโฮสต์ก็เพียงพอแล้ว แม้ว่าจะมีการใช้โฮสต์นั้นในประกาศอื่นๆ ที่ไม่ได้ทำเครื่องหมายไว้ก็ตาม แต่เราขอแนะนำให้คุณเพิ่ม autoVerify ลงในองค์ประกอบ <intent-filter> แต่ละรายการเพื่อความสอดคล้อง วิธีนี้ยังช่วยให้มั่นใจได้ว่าหลังจากนำองค์ประกอบในไฟล์ Manifest ออกหรือปรับโครงสร้างแล้ว แอปจะยังคงเชื่อมโยงกับโดเมนทั้งหมดที่คุณยังคงกำหนดไว้

ขั้นตอนการยืนยันโดเมนต้องใช้การเชื่อมต่ออินเทอร์เน็ตและอาจใช้เวลาสักครู่จึงจะเสร็จสมบูรณ์ ระบบจะยืนยันโดเมนสําหรับแอปที่กําหนดเป้าหมายเป็น Android 12 ขึ้นไปก็ต่อเมื่อโดเมนนั้นอยู่ภายในองค์ประกอบ <intent-filter> ที่มีรูปแบบที่ตรงกันทุกประการกับที่ระบุไว้ในข้อมูลโค้ดก่อนหน้าเท่านั้น เพื่อช่วยเพิ่มประสิทธิภาพของกระบวนการ เช่น รูปแบบอื่นนอกเหนือจาก "http" และ "https" เช่น <data android:scheme="custom" /> จะป้องกันไม่ให้ <intent-filter> ทริกเกอร์การยืนยันโดเมน

การรองรับการลิงก์แอปสำหรับหลายโฮสต์

ระบบต้องยืนยันโฮสต์ที่ระบุไว้ในองค์ประกอบข้อมูลของตัวกรอง Intent ของ URL ของแอปกับไฟล์ Digital Asset Links ที่โฮสต์ในโดเมนเว็บที่เกี่ยวข้องในตัวกรอง Intent นั้น หากการยืนยันไม่สำเร็จ ระบบจะกลับไปใช้ลักษณะการทำงานมาตรฐานเพื่อแก้ไขความตั้งใจตามที่อธิบายไว้ในสร้าง Deep Link ไปยังเนื้อหาแอป อย่างไรก็ตาม แอปจะยังคงได้รับการยืนยันเป็นตัวจัดการเริ่มต้นสำหรับรูปแบบ URL ที่กำหนดไว้ในตัวกรอง Intent อื่นๆ ของแอป

หมายเหตุ: ใน Android 11 (API ระดับ 30) และต่ำกว่า ระบบจะไม่ยืนยันแอปของคุณว่าเป็นตัวแฮนเดิลเริ่มต้น เว้นแต่ว่าจะพบไฟล์ลิงก์เนื้อหาดิจิทัล (Digital Asset Links) ที่ตรงกันสำหรับโฮสต์ทั้งหมดที่คุณกำหนดไว้ในไฟล์ Manifest

ตัวอย่างเช่น แอปที่มีตัวกรอง Intent ต่อไปนี้จะผ่านการยืนยันสำหรับ https://www.example.com เท่านั้น หากพบไฟล์ assetlinks.json ที่ https://www.example.com/.well-known/assetlinks.json แต่ไม่เห็นที่ https://www.example.net/.well-known/assetlinks.json

<application>

  <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="http" />
      <data android:scheme="https" />
      <data android:host="www.example.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="www.example.net" />
    </intent-filter>
  </activity>

</application>

หมายเหตุ: ระบบจะผสานองค์ประกอบ <data> ทั้งหมดในตัวกรอง Intent เดียวกันเข้าด้วยกันเพื่อพิจารณารูปแบบทั้งหมดของแอตทริบิวต์ที่รวม เช่น ตัวกรอง Intent ตัวแรกด้านบนมีองค์ประกอบ <data> ที่ประกาศเฉพาะรูปแบบ HTTPS แต่รวมเข้ากับองค์ประกอบ <data> อื่นๆ เพื่อให้ตัวกรอง Intent รองรับทั้ง http://www.example.com และ https://www.example.com คุณจึงต้องสร้างตัวกรอง Intent แยกต่างหากเมื่อต้องการกำหนดชุดค่าผสมที่เฉพาะเจาะจงของรูปแบบ URI และโดเมน

การรองรับการลิงก์แอปสำหรับโดเมนย่อยหลายรายการ

โปรโตคอลลิงก์เนื้อหาดิจิทัลจะถือว่าโดเมนย่อยในตัวกรอง Intent เป็นโฮสต์ที่ไม่ซ้ำกันแยกต่างหาก ดังนั้น หากตัวกรอง Intent แสดงรายการโฮสต์หลายรายการที่มีโดเมนย่อยต่างกัน คุณต้องเผยแพร่ assetlinks.json ที่ถูกต้องในแต่ละโดเมน ตัวอย่างเช่น ตัวกรอง Intent ต่อไปนี้มี www.example.com และ mobile.example.com เป็นเจ้าภาพ URL ของ Intent ที่ยอมรับ ดังนั้น assetlinks.json ที่ถูกต้องจึงต้องเผยแพร่ทั้งในส่วน https://www.example.com/.well-known/assetlinks.json และ https://mobile.example.com/.well-known/assetlinks.json

<application>
  <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>
  </activity>
</application>

หรือหากคุณประกาศชื่อโฮสต์ด้วยไวลด์การ์ด (เช่น *.example.com) คุณจะต้องเผยแพร่ไฟล์ assetlinks.json ที่ชื่อโฮสต์รูท (example.com) ตัวอย่างเช่น แอปที่มีตัวกรอง Intent ต่อไปนี้จะผ่านการยืนยันสําหรับชื่อย่อยของ example.com (เช่น foo.example.com) ตราบใดที่ไฟล์ assetlinks.json เผยแพร่ที่ https://example.com/.well-known/assetlinks.json

<application>
  <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:host="*.example.com" />
    </intent-filter>
  </activity>
</application>

ตรวจสอบว่ามีแอปหลายแอปที่เชื่อมโยงกับโดเมนเดียวกันหรือไม่

หากคุณเผยแพร่แอปหลายแอปที่เชื่อมโยงกับโดเมนเดียวกัน แอปแต่ละแอปจะยืนยันได้สําเร็จ อย่างไรก็ตาม หากแอปสามารถแก้ไขโฮสต์และเส้นทางโดเมนเดียวกันได้ ซึ่งอาจเกิดขึ้นได้กับแอปเวอร์ชัน Lite และเวอร์ชันเต็ม จะมีเพียงแอปที่ติดตั้งล่าสุดเท่านั้นที่แก้ไข Intent ของเว็บสําหรับโดเมนนั้นได้

ในกรณีเช่นนี้ ให้ตรวจสอบแอปที่อาจขัดแย้งกันในอุปกรณ์ของผู้ใช้ โดยคุณต้องมีระดับการเข้าถึงแพ็กเกจที่จำเป็น จากนั้นแสดงกล่องโต้ตอบตัวเลือกที่กําหนดเองในแอปซึ่งมีผลการเรียกใช้ queryIntentActivities() ผู้ใช้สามารถเลือกแอปที่ต้องการจากรายการแอปที่ตรงกันซึ่งปรากฏในกล่องโต้ตอบ

ประกาศการเชื่อมโยงเว็บไซต์

คุณต้องเผยแพร่ไฟล์ JSON ของลิงก์เนื้อหาดิจิทัล (Digital Asset Links) ในเว็บไซต์เพื่อระบุแอป Android ที่เชื่อมโยงกับเว็บไซต์และยืนยันความตั้งใจของ URL ของแอป ไฟล์ JSON ใช้ฟิลด์ต่อไปนี้เพื่อระบุแอปที่เกี่ยวข้อง

  • package_name: รหัสแอปพลิเคชันที่ประกาศในไฟล์ build.gradle ของแอป
  • sha256_cert_fingerprints: ลายนิ้วมือ SHA256 ของใบรับรองการรับรองของแอป คุณสามารถใช้คําสั่งต่อไปนี้เพื่อสร้างลายนิ้วมือผ่านเครื่องมือคีย์ของ Java
    keytool -list -v -keystore my-release-key.keystore
    
    ฟิลด์นี้รองรับลายนิ้วมือหลายรายการ ซึ่งสามารถใช้เพื่อรองรับแอปเวอร์ชันต่างๆ เช่น บิลด์แก้ไขข้อบกพร่องและบิลด์เวอร์ชันที่ใช้งานจริง

    หากคุณใช้ Play App Signing สําหรับแอป ลายนิ้วมือของใบรับรองที่สร้างขึ้นโดยการเรียกใช้ keytool ในเครื่องมักจะไม่ตรงกับลายนิ้วมือในอุปกรณ์ของผู้ใช้ คุณสามารถตรวจสอบว่าคุณใช้การรับรองแอป Play สําหรับแอปของคุณหรือไม่ในบัญชีนักพัฒนาแอป Play Console ในส่วน Release > Setup > App signing หากใช้อยู่ คุณจะเห็นข้อมูลโค้ด JSON ของลิงก์เนื้อหาดิจิทัล (Digital Asset Links) ที่ถูกต้องสําหรับแอปในหน้าเดียวกันด้วย

ตัวอย่างไฟล์ assetlinks.json ต่อไปนี้ให้สิทธิ์เปิดลิงก์แก่แอป Android com.example

[{
  "relation": ["delegate_permission/common.handle_all_urls"],
  "target": {
    "namespace": "android_app",
    "package_name": "com.example",
    "sha256_cert_fingerprints":
    ["14:6D:E9:83:C5:73:06:50:D8:EE:B9:95:2F:34:FC:64:16:A0:83:42:E6:1D:BE:A8:8A:04:96:B2:3F:CF:44:E5"]
  }
}]

การเชื่อมโยงเว็บไซต์กับแอปหลายแอป

เว็บไซต์สามารถประกาศการเชื่อมโยงกับแอปหลายแอปภายในไฟล์ assetlinks.json เดียวกัน รายการไฟล์ต่อไปนี้แสดงตัวอย่างไฟล์คำสั่งที่ประกาศการเชื่อมโยงกับแอป 2 แอปแยกกัน และอยู่ใน https://www.example.com/.well-known/assetlinks.json

[{
  "relation": ["delegate_permission/common.handle_all_urls"],
  "target": {
    "namespace": "android_app",
    "package_name": "com.example.puppies.app",
    "sha256_cert_fingerprints":
    ["14:6D:E9:83:C5:73:06:50:D8:EE:B9:95:2F:34:FC:64:16:A0:83:42:E6:1D:BE:A8:8A:04:96:B2:3F:CF:44:E5"]
  }
  },
  {
  "relation": ["delegate_permission/common.handle_all_urls"],
  "target": {
    "namespace": "android_app",
    "package_name": "com.example.monkeys.app",
    "sha256_cert_fingerprints":
    ["14:6D:E9:83:C5:73:06:50:D8:EE:B9:95:2F:34:FC:64:16:A0:83:42:E6:1D:BE:A8:8A:04:96:B2:3F:CF:44:E5"]
  }
}]

แอปต่างๆ อาจจัดการลิงก์สำหรับทรัพยากรที่แตกต่างกันภายใต้เว็บโฮสต์เดียวกัน ตัวอย่างเช่น แอป 1 อาจประกาศตัวกรอง Intent สําหรับ https://example.com/articles และแอป 2 อาจประกาศตัวกรอง Intent สําหรับ https://example.com/videos

หมายเหตุ: แอปหลายแอปที่เชื่อมโยงกับโดเมนอาจลงนามด้วยใบรับรองเดียวกันหรือใบรับรองที่แตกต่างกัน

การเชื่อมโยงเว็บไซต์หลายแห่งกับแอปเดียว

เว็บไซต์หลายแห่งสามารถประกาศการเชื่อมโยงกับแอปเดียวกันในไฟล์ assetlinks.json ที่เกี่ยวข้อง รายการไฟล์ต่อไปนี้แสดงตัวอย่างวิธีประกาศการเชื่อมโยง example.com และ example.net กับ app1 ข้อมูลแรกแสดงการเชื่อมโยง example.com กับ app1

https://www.example.com/.well-known/assetlinks.json

[{
  "relation": ["delegate_permission/common.handle_all_urls"],
  "target": {
    "namespace": "android_app",
    "package_name": "com.mycompany.app1",
    "sha256_cert_fingerprints":
    ["14:6D:E9:83:C5:73:06:50:D8:EE:B9:95:2F:34:FC:64:16:A0:83:42:E6:1D:BE:A8:8A:04:96:B2:3F:CF:44:E5"]
  }
}]

รายการถัดไปแสดงการเชื่อมโยง example.net กับ app1 มีเพียงตำแหน่งที่โฮสต์ไฟล์เหล่านี้เท่านั้นที่แตกต่างกัน (.com และ .net)

https://www.example.net/.well-known/assetlinks.json

[{
  "relation": ["delegate_permission/common.handle_all_urls"],
  "target": {
    "namespace": "android_app",
    "package_name": "com.mycompany.app1",
    "sha256_cert_fingerprints":
    ["14:6D:E9:83:C5:73:06:50:D8:EE:B9:95:2F:34:FC:64:16:A0:83:42:E6:1D:BE:A8:8A:04:96:B2:3F:CF:44:E5"]
  }
}]

การเผยแพร่ไฟล์การยืนยัน JSON

คุณต้องเผยแพร่ไฟล์การยืนยัน JSON ในตำแหน่งต่อไปนี้

https://domain.name/.well-known/assetlinks.json

โปรดตรวจสอบสิ่งต่อไปนี้

  • ระบบจะแสดงไฟล์ assetlinks.json ด้วยประเภทเนื้อหา application/json
  • ไฟล์ assetlinks.json ต้องเข้าถึงได้ผ่านการเชื่อมต่อ HTTPS ไม่ว่าตัวกรอง Intent ของแอปจะประกาศว่า HTTPS เป็นรูปแบบข้อมูลหรือไม่ก็ตาม
  • ไฟล์ assetlinks.json ต้องเข้าถึงได้โดยไม่ต้องเปลี่ยนเส้นทาง (ไม่มีการเปลี่ยนเส้นทาง 301 หรือ 302)
  • หากลิงก์แอปรองรับโดเมนโฮสต์หลายโดเมน คุณต้องเผยแพร่ไฟล์ assetlinks.json ในแต่ละโดเมน ดูหัวข้อการรองรับการลิงก์แอปสําหรับโฮสต์หลายราย
  • อย่าเผยแพร่แอปด้วย URL สําหรับนักพัฒนาซอฟต์แวร์/การทดสอบในไฟล์ Manifest ที่สาธารณะอาจเข้าถึงไม่ได้ (เช่น URL ที่เข้าถึงได้ผ่าน VPN เท่านั้น) วิธีแก้ปัญหาในกรณีเช่นนี้คือการกำหนดค่าตัวแปรของบิวด์เพื่อสร้างไฟล์ Manifest อื่นสำหรับบิวด์ของนักพัฒนาซอฟต์แวร์

การยืนยัน Android App Link

เมื่อ android:autoVerify="true" อยู่ในตัวกรอง Intent ของแอปอย่างน้อย 1 รายการ การติดตั้งแอปในอุปกรณ์ที่ใช้ Android 6.0 (API ระดับ 23) ขึ้นไปจะทำให้ระบบยืนยันโฮสต์ที่เชื่อมโยงกับ URL ในตัวกรอง Intent ของแอปโดยอัตโนมัติ ใน Android 12 ขึ้นไป คุณสามารถเรียกใช้กระบวนการยืนยันด้วยตนเองเพื่อทดสอบตรรกะการยืนยันได้ด้วย

การยืนยันอัตโนมัติ

การยืนยันอัตโนมัติของระบบเกี่ยวข้องกับการดำเนินการต่อไปนี้

  1. ระบบจะตรวจสอบตัวกรอง Intent ทั้งหมดที่มีรายการต่อไปนี้
    • การดำเนินการ: android.intent.action.VIEW
    • หมวดหมู่: android.intent.category.BROWSABLE และ android.intent.category.DEFAULT
    • สคีมาข้อมูล: http หรือ https
  2. สําหรับชื่อโฮสต์ที่ไม่ซ้ำกันแต่ละรายการที่พบในตัวกรอง Intent ข้างต้น Android จะค้นหาเว็บไซต์ที่เกี่ยวข้องสําหรับไฟล์ Digital Asset Links ที่ https://hostname/.well-known/assetlinks.json

หลังจากยืนยันรายการเว็บไซต์ที่จะเชื่อมโยงกับแอป และยืนยันว่าไฟล์ JSON ที่โฮสต์ถูกต้องแล้ว ให้ติดตั้งแอปในอุปกรณ์ รออย่างน้อย 20 วินาทีเพื่อให้กระบวนการยืนยันแบบไม่พร้อมกันเสร็จสมบูรณ์ ใช้คําสั่งต่อไปนี้เพื่อตรวจสอบว่าระบบยืนยันแอปและตั้งค่านโยบายการจัดการลิงก์ที่ถูกต้องหรือไม่

adb shell am start -a android.intent.action.VIEW \
    -c android.intent.category.BROWSABLE \
    -d "http://domain.name:optional_port"

การยืนยันโดยเจ้าหน้าที่

ตั้งแต่ Android 12 เป็นต้นไป คุณสามารถเรียกใช้การยืนยันโดเมนของแอปที่ติดตั้งในอุปกรณ์ด้วยตนเองได้ คุณทําขั้นตอนนี้ได้ไม่ว่าแอปจะกําหนดเป้าหมายเป็น Android 12 หรือไม่ก็ตาม

เชื่อมต่ออินเทอร์เน็ต

อุปกรณ์ทดสอบต้องเชื่อมต่ออินเทอร์เน็ตจึงจะทำการยืนยันโดเมนได้

รองรับกระบวนการยืนยันโดเมนที่อัปเดตแล้ว

หากแอปกำหนดเป้าหมายเป็น Android 12 ขึ้นไป ระบบจะใช้กระบวนการยืนยันโดเมนที่อัปเดตแล้วโดยอัตโนมัติ

หรือจะเปิดใช้กระบวนการยืนยันที่อัปเดตด้วยตนเองก็ได้ ซึ่งทำได้โดยการเรียกใช้คำสั่งต่อไปนี้ในหน้าต่างเทอร์มินัล

adb shell am compat enable 175408749 PACKAGE_NAME

รีเซ็ตสถานะของ App Link ของ Android ในอุปกรณ์

ก่อนที่จะเรียกใช้การยืนยันโดเมนในอุปกรณ์ด้วยตนเอง คุณต้องรีเซ็ตสถานะของ App Link ของ Android ในอุปกรณ์ทดสอบ ซึ่งทำได้โดยการเรียกใช้คำสั่งต่อไปนี้ในหน้าต่างเทอร์มินัล

adb shell pm set-app-links --package PACKAGE_NAME 0 all

คำสั่งนี้จะตั้งค่าอุปกรณ์ให้อยู่ในสถานะเดียวกับก่อนที่จะมีการเลือกแอปเริ่มต้นสำหรับโดเมนใดก็ตาม

เริ่มกระบวนการยืนยันโดเมน

หลังจากรีเซ็ตสถานะของ Android App Link ในอุปกรณ์แล้ว คุณจะทำการยืนยันด้วยตนเองได้ ซึ่งทำได้โดยการเรียกใช้คำสั่งต่อไปนี้ในหน้าต่างเทอร์มินัล

adb shell pm verify-app-links --re-verify PACKAGE_NAME

ตรวจสอบผลการยืนยัน

หลังจากให้เวลาตัวแทนการยืนยันดำเนินการตามคำขอจนเสร็จสิ้นแล้ว ให้ตรวจสอบผลการยืนยัน หากต้องการดำเนินการดังกล่าว ให้เรียกใช้คำสั่งต่อไปนี้

adb shell pm get-app-links PACKAGE_NAME

เอาต์พุตของคําสั่งนี้จะคล้ายกับตัวอย่างต่อไปนี้

com.example.pkg:
    ID: 01234567-89ab-cdef-0123-456789abcdef
    Signatures: [***]
    Domain verification state:
      example.com: verified
      sub.example.com: legacy_failure
      example.net: verified
      example.org: 1026

โดเมนที่ผ่านการยืนยันเรียบร้อยแล้วจะมีสถานะการยืนยันโดเมนเป็น verified สถานะอื่นๆ บ่งบอกว่ายืนยันโดเมนไม่ได้ โดยเฉพาะอย่างยิ่ง สถานะ none บ่งบอกว่าตัวแทนการยืนยันอาจยังไม่ได้ดำเนินการยืนยันให้เสร็จสมบูรณ์

รายการต่อไปนี้แสดงค่าที่เป็นไปได้ซึ่งการยืนยันโดเมนจะแสดงผลสำหรับโดเมนหนึ่งๆ

none
ไม่มีการบันทึกข้อมูลสำหรับโดเมนนี้ โปรดรออีก 2-3 นาทีเพื่อให้ตัวแทนการยืนยันดำเนินการตามคำขอที่เกี่ยวข้องกับการยืนยันโดเมนให้เสร็จสิ้น จากนั้นเรียกใช้กระบวนการยืนยันโดเมนอีกครั้ง
verified
โดเมนได้รับการยืนยันสําหรับแอปที่ประกาศเรียบร้อยแล้ว
approved
โดเมนได้รับการอนุมัติแบบบังคับ ซึ่งโดยปกติแล้วจะเป็นการดำเนินการตามคำสั่งเชลล์
denied
โดเมนถูกปฏิเสธโดยบังคับ ซึ่งมักจะเกิดจากการเรียกใช้คำสั่งเชลล์
migrated
ระบบเก็บรักษาผลลัพธ์ของกระบวนการก่อนหน้านี้ที่ใช้การยืนยันโดเมนเดิม
restored
โดเมนได้รับอนุมัติหลังจากผู้ใช้กู้คืนข้อมูลแล้ว ระบบจะถือว่าโดเมนได้รับการยืนยันแล้วก่อนหน้านี้
legacy_failure
โปรแกรมยืนยันแบบเดิมปฏิเสธโดเมน ไม่ทราบสาเหตุที่แน่ชัดของความล้มเหลว
system_configured
โดเมนได้รับอนุมัติโดยอัตโนมัติจากการกําหนดค่าอุปกรณ์
รหัสข้อผิดพลาด 1024 ขึ้นไป

รหัสข้อผิดพลาดที่กำหนดเองสำหรับโปรแกรมตรวจสอบของอุปกรณ์

ตรวจสอบอีกครั้งว่าคุณได้สร้างการเชื่อมต่อเครือข่ายแล้ว และเรียกใช้กระบวนการยืนยันโดเมนอีกครั้ง

ขอให้ผู้ใช้เชื่อมโยงแอปกับโดเมน

อีกวิธีหนึ่งที่จะทำให้แอปได้รับอนุมัติสำหรับโดเมนคือการขอให้ผู้ใช้เชื่อมโยงแอปของคุณกับโดเมนนั้น

ตรวจสอบว่าแอปได้รับอนุมัติสำหรับโดเมนแล้วหรือยัง

ก่อนแจ้งให้ผู้ใช้ทราบ ให้ตรวจสอบว่าแอปของคุณเป็นตัวแฮนเดิลเริ่มต้นสำหรับโดเมนที่คุณกำหนดไว้ในองค์ประกอบ <intent-filter> หรือไม่ คุณสามารถค้นหาสถานะการอนุมัติได้โดยใช้วิธีใดวิธีหนึ่งต่อไปนี้

  • DomainVerificationManager API (ขณะรันไทม์)
  • โปรแกรมบรรทัดคำสั่ง (ระหว่างการทดสอบ)

DomainVerificationManager

ข้อมูลโค้ดต่อไปนี้แสดงวิธีใช้ DomainVerificationManager API

Kotlin

val context: Context = TODO("Your activity or fragment's Context")
val manager = context.getSystemService(DomainVerificationManager::class.java)
val userState = manager.getDomainVerificationUserState(context.packageName)

// Domains that have passed Android App Links verification.
val verifiedDomains = userState?.hostToStateMap
    ?.filterValues { it == DomainVerificationUserState.DOMAIN_STATE_VERIFIED }

// Domains that haven't passed Android App Links verification but that the user
// has associated with an app.
val selectedDomains = userState?.hostToStateMap
    ?.filterValues { it == DomainVerificationUserState.DOMAIN_STATE_SELECTED }

// All other domains.
val unapprovedDomains = userState?.hostToStateMap
    ?.filterValues { it == DomainVerificationUserState.DOMAIN_STATE_NONE }

Java

Context context = TODO("Your activity or fragment's Context");
DomainVerificationManager manager =
        context.getSystemService(DomainVerificationManager.class);
DomainVerificationUserState userState =
        manager.getDomainVerificationUserState(context.getPackageName());

Map<String, Integer> hostToStateMap = userState.getHostToStateMap();
List<String> verifiedDomains = new ArrayList<>();
List<String> selectedDomains = new ArrayList<>();
List<String> unapprovedDomains = new ArrayList<>();
for (String key : hostToStateMap.keySet()) {
    Integer stateValue = hostToStateMap.get(key);
    if (stateValue == DomainVerificationUserState.DOMAIN_STATE_VERIFIED) {
        // Domain has passed Android App Links verification.
        verifiedDomains.add(key);
    } else if (stateValue == DomainVerificationUserState.DOMAIN_STATE_SELECTED) {
        // Domain hasn't passed Android App Links verification, but the user has
        // associated it with an app.
        selectedDomains.add(key);
    } else {
        // All other domains.
        unapprovedDomains.add(key);
    }
}

โปรแกรมบรรทัดคำสั่ง

เมื่อทดสอบแอประหว่างการพัฒนา คุณสามารถเรียกใช้คําสั่งต่อไปนี้เพื่อค้นหาสถานะการยืนยันของโดเมนที่องค์กรของคุณเป็นเจ้าของ

adb shell pm get-app-links --user cur PACKAGE_NAME

ในตัวอย่างเอาต์พุตต่อไปนี้ แม้ว่าแอปจะยืนยันโดเมน "example.org" ไม่ได้ แต่ผู้ใช้ 0 ได้อนุมัติแอปด้วยตนเองในการตั้งค่าระบบ และไม่มีแพ็กเกจอื่นได้รับการยืนยันสำหรับโดเมนนั้น

com.example.pkg:
ID: ***
Signatures: [***]
Domain verification state:
  example.com: verified
  example.net: verified
  example.org: 1026
User 0:
  Verification link handling allowed: true
  Selection state:
    Enabled:
      example.org
    Disabled:
      example.com
      example.net

นอกจากนี้ คุณยังใช้คำสั่งเชลล์เพื่อจำลองกระบวนการที่ผู้ใช้เลือกแอปที่เชื่อมโยงกับโดเมนหนึ่งๆ ได้ด้วย ดูคําอธิบายคําสั่งเหล่านี้ได้แบบเต็มจากเอาต์พุตของ adb shell pm

ระบุบริบทสําหรับคําขอ

ก่อนส่งคำขออนุมัติโดเมนนี้ โปรดระบุบริบทบางอย่างสำหรับผู้ใช้ เช่น คุณอาจแสดงหน้าจอแนะนำ กล่องโต้ตอบ หรือองค์ประกอบ UI ที่คล้ายกันซึ่งอธิบายให้ผู้ใช้ทราบว่าเหตุใดแอปของคุณจึงควรเป็นตัวแฮนเดิลเริ่มต้นสำหรับโดเมนหนึ่งๆ

ส่งคำขอ

หลังจากผู้ใช้เข้าใจสิ่งที่แอปขอให้ทำแล้ว ให้ส่งคำขอ โดยเรียกใช้ Intent ที่มีการดำเนินการของ Intent ACTION_APP_OPEN_BY_DEFAULT_SETTINGS และสตริงข้อมูลที่ตรงกัน package:com.example.pkg สำหรับแอปเป้าหมาย ดังที่แสดงในข้อมูลโค้ดต่อไปนี้

Kotlin

val context: Context = TODO("Your activity or fragment's Context")
val intent = Intent(Settings.ACTION_APP_OPEN_BY_DEFAULT_SETTINGS,
    Uri.parse("package:${context.packageName}"))
context.startActivity(intent)

Java

Context context = TODO("Your activity or fragment's Context");
Intent intent = new Intent(Settings.ACTION_APP_OPEN_BY_DEFAULT_SETTINGS,
    Uri.parse("package:" + context.getPackageName()));
context.startActivity(intent);

เมื่อเรียกใช้ Intent ผู้ใช้จะเห็นหน้าจอการตั้งค่าชื่อเปิดโดยค่าเริ่มต้น หน้าจอนี้มีปุ่มตัวเลือกชื่อเปิดลิงก์ที่รองรับดังที่แสดงในรูปที่ 1

เมื่อผู้ใช้เปิดเปิดลิงก์ที่รองรับ ชุดช่องทําเครื่องหมายจะปรากฏขึ้นในส่วนที่ชื่อลิงก์ที่จะเปิดในแอปนี้ จากตรงนี้ ผู้ใช้สามารถเลือกโดเมนที่ต้องการเชื่อมโยงกับแอปได้ นอกจากนี้ ยังเลือกเพิ่มลิงก์เพื่อเพิ่มโดเมนได้ด้วย ดังที่แสดงในรูปที่ 2 เมื่อผู้ใช้เลือกลิงก์ใดก็ได้ภายในโดเมนที่เพิ่มไว้ภายหลัง ลิงก์นั้นจะเปิดในแอปโดยอัตโนมัติ

เมื่อเปิดใช้ปุ่มตัวเลือก ส่วนที่อยู่ใกล้กับด้านล่างจะมีช่องทําเครื่องหมายและปุ่ม &quot;เพิ่มลิงก์&quot;
รูปที่ 1 หน้าจอการตั้งค่าระบบที่ผู้ใช้สามารถเลือกได้ว่าจะให้ลิงก์ใดเปิดในแอปโดยค่าเริ่มต้น
ช่องทําเครื่องหมายแต่ละช่องแสดงโดเมนที่คุณสามารถเพิ่ม ปุ่มของกล่องโต้ตอบคือ &quot;ยกเลิก&quot; และ &quot;เพิ่ม&quot;
รูปที่ 2 กล่องโต้ตอบที่ผู้ใช้สามารถเลือกโดเมนเพิ่มเติมเพื่อเชื่อมโยงกับแอปของคุณ

โดเมนที่เปิดในแอปซึ่งแอปของคุณยืนยันไม่ได้

ฟังก์ชันหลักของแอปอาจเป็นการเปิดลิงก์ในฐานะบุคคลที่สาม โดยไม่สามารถยืนยันโดเมนที่จัดการได้ ในกรณีนี้ โปรดอธิบายให้ผู้ใช้ทราบว่าเมื่อเลือกเว็บลิงก์ ผู้ใช้จะเลือกระหว่างแอปของบุคคลที่หนึ่งกับแอป (บุคคลที่สาม) ของคุณไม่ได้ ผู้ใช้ต้องเชื่อมโยงโดเมนกับแอปของบุคคลที่สามด้วยตนเอง

นอกจากนี้ ให้พิจารณาแสดงกล่องโต้ตอบหรือกิจกรรม Trampoline ที่อนุญาตให้ผู้ใช้เปิดลิงก์ในแอปของบุคคลที่หนึ่งได้หากต้องการ โดยทำหน้าที่เป็นพร็อกซี ก่อนตั้งค่ากล่องโต้ตอบหรือกิจกรรม Trampoline ให้ตั้งค่าแอปให้มีระดับการเข้าถึงแพ็กเกจในแอปของบุคคลที่หนึ่งซึ่งตรงกับตัวกรอง Intent ของเว็บของแอป

ทดสอบลิงก์แอป

เมื่อใช้ฟีเจอร์การลิงก์แอป คุณควรทดสอบฟังก์ชันการลิงก์เพื่อให้แน่ใจว่าระบบจะเชื่อมโยงแอปกับเว็บไซต์และจัดการคำขอ URL ได้ตามที่คุณคาดไว้

หากต้องการทดสอบไฟล์ใบแจ้งยอดที่มีอยู่ คุณสามารถใช้เครื่องมือ เครื่องมือสร้างและทดสอบรายการใบแจ้งยอด

ยืนยันรายการโฮสต์ที่จะยืนยัน

เมื่อทดสอบ คุณควรยืนยันรายการโฮสต์ที่เชื่อมโยงซึ่งระบบควรยืนยันสําหรับแอปของคุณ จัดทำรายการ URL ทั้งหมดที่ตัวกรอง Intent ที่เกี่ยวข้องมีแอตทริบิวต์และองค์ประกอบต่อไปนี้

  • แอตทริบิวต์ android:scheme ที่มีค่าเป็น http หรือ https
  • แอตทริบิวต์ android:host ที่มีรูปแบบ URL ของโดเมน
  • องค์ประกอบการดําเนินการ android.intent.action.VIEW
  • องค์ประกอบหมวดหมู่ android.intent.category.BROWSABLE

ใช้รายการนี้เพื่อตรวจสอบว่ามีไฟล์ JSON ของลิงก์เนื้อหาดิจิทัล (Digital Asset Links) ในโฮสต์ที่มีชื่อและโดเมนย่อยแต่ละรายการ

ยืนยันไฟล์ลิงก์เนื้อหาดิจิทัล

สําหรับแต่ละเว็บไซต์ ให้ใช้ Digital Asset Links API เพื่อยืนยันว่าไฟล์ JSON ของลิงก์เนื้อหาดิจิทัล (Digital Asset Links) ได้รับการโฮสต์และกำหนดอย่างถูกต้อง ดังนี้

https://digitalassetlinks.googleapis.com/v1/statements:list?
   source.web.site=https://domain.name:optional_port&
   relation=delegate_permission/common.handle_all_urls

คุณสามารถตรวจสอบการตั้งค่าระบบปัจจุบันเพื่อดูการจัดการลิงก์ได้ในระหว่างกระบวนการทดสอบ ใช้คำสั่งต่อไปนี้เพื่อดูรายการนโยบายการจัดการลิงก์ที่มีอยู่สำหรับแอปทั้งหมดในอุปกรณ์ที่เชื่อมต่อ

adb shell dumpsys package domain-preferred-apps

หรือจะใช้คำสั่งต่อไปนี้ก็ได้

adb shell dumpsys package d

หมายเหตุ: โปรดรออย่างน้อย 20 วินาทีหลังจากติดตั้งแอปเพื่อให้ระบบดำเนินการยืนยันให้เสร็จสมบูรณ์

คำสั่งนี้จะแสดงรายการผู้ใช้หรือโปรไฟล์แต่ละรายการที่กําหนดไว้ในอุปกรณ์ โดยจะมีส่วนหัวอยู่ก่อนในรูปแบบต่อไปนี้

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 ตัวเลขฐาน 16 หลังสถานะนี้เกี่ยวข้องกับระเบียนค่ากําหนดการลิงก์แอปของผู้ใช้ในระบบ Android ค่านี้ไม่ได้ระบุว่าการยืนยันสำเร็จหรือไม่

หมายเหตุ: หากผู้ใช้เปลี่ยนการตั้งค่าการลิงก์แอปสําหรับแอปก่อนที่จะยืนยันให้เสร็จสมบูรณ์ คุณอาจเห็นการยืนยันที่สำเร็จแต่เป็นการยืนยันที่ไม่ถูกต้อง แม้ว่าการยืนยันจะล้มเหลวก็ตาม อย่างไรก็ตาม การยืนยันที่ไม่สําเร็จนี้จะไม่ส่งผลใดๆ หากผู้ใช้เปิดใช้แอปให้เปิดลิงก์ที่รองรับได้โดยไม่ถาม เนื่องจากค่ากําหนดของผู้ใช้จะมีความสําคัญเหนือกว่าการยืนยันแบบเป็นโปรแกรม (หรือไม่มีการยืนยัน) ด้วยเหตุนี้ ลิงก์จึงไปยังแอปของคุณโดยตรงโดยไม่ต้องแสดงกล่องโต้ตอบ เหมือนกับว่าการยืนยันสำเร็จ

ตัวอย่างการทดสอบ

ระบบต้องยืนยันแอปของคุณกับเว็บไซต์แต่ละแห่งที่คุณระบุในตัวกรอง Intent ที่ตรงตามเกณฑ์สําหรับลิงก์แอปได้ เพื่อให้การยืนยันลิงก์แอปสําเร็จ ตัวอย่างต่อไปนี้แสดงการกำหนดค่าไฟล์ Manifest ที่มีการกำหนดลิงก์แอปหลายรายการ

<application>

    <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)

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

แก้ไขข้อผิดพลาดที่พบบ่อยในการติดตั้งใช้งาน

หากยืนยัน App Link ของ Android ไม่ได้ ให้ตรวจสอบข้อผิดพลาดที่พบได้ทั่วไปต่อไปนี้ ส่วนนี้ใช้ example.com เป็นชื่อโดเมนตัวยึดตําแหน่ง เมื่อทำการตรวจสอบเหล่านี้ ให้แทนที่ example.com ด้วยชื่อโดเมนจริงของเซิร์ฟเวอร์

การตั้งค่าตัวกรอง Intent ไม่ถูกต้อง
ตรวจสอบว่าคุณไม่ได้ใส่ URL ที่แอปไม่ได้เป็นเจ้าของไว้ในองค์ประกอบ <intent-filter>
การกำหนดค่าเซิร์ฟเวอร์ไม่ถูกต้อง

ตรวจสอบการกําหนดค่า JSON ของเซิร์ฟเวอร์ และตรวจสอบว่าค่า SHA ถูกต้อง

นอกจากนี้ ให้ตรวจสอบว่า example.com. (ที่มีเครื่องหมายจุดตามหลัง) แสดงเนื้อหาเดียวกันกับ example.com

การเปลี่ยนเส้นทางฝั่งเซิร์ฟเวอร์

ระบบจะไม่ยืนยัน Android App Link ใดๆ ในแอปของคุณหากคุณตั้งค่าการเปลี่ยนเส้นทาง เช่น

  • http://example.com ถึง https://example.com
  • example.com ถึง www.example.com

ลักษณะการทํางานนี้ช่วยปกป้องความปลอดภัยของแอป

ความเสถียรของเซิร์ฟเวอร์

ตรวจสอบว่าเซิร์ฟเวอร์เชื่อมต่อกับแอปไคลเอ็นต์ได้หรือไม่

ลิงก์ที่ยืนยันไม่ได้

คุณอาจจงใจเพิ่มลิงก์ที่ยืนยันไม่ได้เพื่อวัตถุประสงค์ในการทดสอบ โปรดทราบว่าใน Android 11 และต่ำกว่า ลิงก์เหล่านี้จะทำให้ระบบไม่ยืนยัน App Link ของ Android ทั้งหมดสําหรับแอปของคุณ

ลายเซ็นใน assetlinks.json ไม่ถูกต้อง

ตรวจสอบว่าลายเซ็นถูกต้องและตรงกับลายเซ็นที่ใช้ลงนามในใบสมัครของคุณ ข้อผิดพลาดที่พบบ่อย ได้แก่

  • การเซ็นแอปด้วยใบรับรองแก้ไขข้อบกพร่องและมีเพียงลายเซ็นรุ่นใน assetlinks.json
  • มีลายเซ็นที่เป็นตัวพิมพ์เล็กใน assetlinks.json ลายเซ็นควรเป็นตัวพิมพ์ใหญ่
  • หากคุณใช้ Play App Signing โปรดตรวจสอบว่าคุณใช้ลายเซ็นที่ Google ใช้ในการรับรองรุ่นของคุณแต่ละรุ่น คุณสามารถยืนยันรายละเอียดเหล่านี้ รวมถึงข้อมูลโค้ด JSON ที่สมบูรณ์ได้โดยทําตามวิธีการเกี่ยวกับการประกาศการเชื่อมโยงเว็บไซต์