ตอบสนอง Use Case ทั่วไปในขณะที่มีระดับการเข้าถึงแพ็กเกจที่จำกัด

เอกสารนี้แสดงกรณีการใช้งานทั่วไปหลายรายการที่แอปโต้ตอบกับแอปอื่นๆ แต่ละส่วนมีคำแนะนำเกี่ยวกับวิธีทำให้แอปทำงานได้โดยมีระดับการเข้าถึงแพ็กเกจแบบจำกัด ซึ่งคุณควรพิจารณาหากแอปกำหนดเป้าหมายเป็น Android 11 (API ระดับ 30) ขึ้นไป

เมื่อแอปที่กำหนดเป้าหมายเป็น Android 11 ขึ้นไปใช้ Intent เพื่อเริ่มกิจกรรมในแอปอื่น วิธีที่ใช้ได้ผลที่สุดคือเรียกใช้ Intent และจัดการข้อยกเว้น ActivityNotFoundException หากไม่มีแอปใดพร้อมใช้งาน

หากส่วนหนึ่งของแอปขึ้นอยู่กับการทราบว่าการเรียกใช้ startActivity() จะสำเร็จหรือไม่ เช่น การแสดง UI ให้เพิ่มองค์ประกอบลงในองค์ประกอบ ของไฟล์ Manifest ของแอป โดยปกติแล้วจะเป็นองค์ประกอบ

เปิด URL

ส่วนนี้จะอธิบายวิธีต่างๆ ในการเปิด URL ในแอปที่กำหนดเป้าหมายเป็น Android 11 ขึ้นไป

เปิด URL ในเบราว์เซอร์หรือแอปอื่น

หากต้องการเปิด URL ให้ใช้ Intent ที่มีการดำเนินการของ Intent ACTION_VIEW ตามที่อธิบายไว้ในคู่มือการโหลด URL ของเว็บ หลังจากเรียก startActivity() โดยใช้ Intent นี้ สิ่งใดสิ่งหนึ่งต่อไปนี้จะเกิดขึ้น

  • URL จะเปิดในแอปเว็บเบราว์เซอร์
  • URL จะเปิดในแอปที่รองรับ URL เป็น Deep Link
  • กล่องโต้ตอบที่มีคำอธิบายจะปรากฏขึ้น ซึ่งช่วยให้ผู้ใช้เลือกแอปที่จะเปิด URL ได้
  • ActivityNotFoundException เกิดขึ้นเนื่องจากไม่มีการติดตั้งแอปในอุปกรณ์ที่เปิด URL ได้ (ซึ่งผิดปกติ)

    เราขอแนะนําให้แอปของคุณจับและจัดการ ActivityNotFoundException หากเกิดขึ้น

เนื่องจากเมธอด startActivity() ไม่จำเป็นต้องใช้ระดับการเข้าถึงแพ็กเกจเพื่อเริ่มกิจกรรมของแอปพลิเคชันอื่น คุณจึงไม่ต้องเพิ่มองค์ประกอบ ลงในไฟล์ Manifest ของแอปหรือทำการเปลี่ยนแปลงใดๆ กับองค์ประกอบ ที่มีอยู่ การดำเนินการนี้ใช้ได้กับทั้ง Intent ที่ไม่ชัดแจ้งและชัดแจ้งที่เปิด URL

ตรวจสอบว่าเบราว์เซอร์พร้อมใช้งานหรือไม่

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



   android:name="android.intent.action.VIEW" />
   android:name="android.intent.category.BROWSABLE" />
   android:scheme="https" />

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

เปิด URL ในแท็บที่กำหนดเอง

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

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



   android:name="android.support.customtabs.action.CustomTabsService" />

อนุญาตให้แอปที่ไม่ใช่เบราว์เซอร์จัดการ URL

แม้ว่าแอปจะเปิด URL ได้โดยใช้แท็บที่กำหนดเอง แต่เราขอแนะนำให้คุณอนุญาตให้แอปที่ไม่ใช่เบราว์เซอร์เปิด URL หากเป็นไปได้ หากต้องการระบุความสามารถนี้ในแอป ให้ลองเรียกใช้ startActivity() โดยใช้ Intent ที่ตั้งค่า Flag ของ Intent FLAG_ACTIVITY_REQUIRE_NON_BROWSER หากระบบแสดง ActivityNotFoundException แอปของคุณก็จะเปิด URL ในแท็บที่กำหนดเองได้

หาก Intent มี Flag นี้ การเรียก startActivity() จะทําให้ระบบแสดง ActivityNotFoundException เมื่อเงื่อนไขข้อใดข้อหนึ่งต่อไปนี้เกิดขึ้น

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

ข้อมูลโค้ดต่อไปนี้แสดงวิธีอัปเดตตรรกะเพื่อใช้FLAG_ACTIVITY_REQUIRE_NON_BROWSER Flag ของ Intent

Kotlin

try {
    val intent = Intent(ACTION_VIEW, Uri.parse(url)).apply {
        // The URL should either launch directly in a non-browser app (if it's
        // the default) or in the disambiguation dialog.
        addCategory(CATEGORY_BROWSABLE)
        flags = FLAG_ACTIVITY_NEW_TASK or FLAG_ACTIVITY_REQUIRE_NON_BROWSER
    }
    startActivity(intent)
} catch (e: ActivityNotFoundException) {
    // Only browser apps are available, or a browser is the default.
    // So you can open the URL directly in your app, for example in a
    // Custom Tab.
    openInCustomTabs(url)
}

Java

try {
    Intent intent = new Intent(ACTION_VIEW, Uri.parse(url));
    // The URL should either launch directly in a non-browser app (if it's the
    // default) or in the disambiguation dialog.
    intent.addCategory(CATEGORY_BROWSABLE);
    intent.setFlags(FLAG_ACTIVITY_NEW_TASK | FLAG_ACTIVITY_REQUIRE_NON_BROWSER);
    startActivity(intent);
} catch (ActivityNotFoundException e) {
    // Only browser apps are available, or a browser is the default.
    // So you can open the URL directly in your app, for example in a
    // Custom Tab.
    openInCustomTabs(url);
}

หลีกเลี่ยงกล่องโต้ตอบการชี้แจง

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

หาก Intent มี Flag นี้ การเรียกใช้ startActivity() จะทําให้ระบบแสดง ActivityNotFoundException เมื่อการเรียกใช้ควรจะแสดงกล่องโต้ตอบการแยกแยะให้กับผู้ใช้

หาก Intent มีทั้ง Flag นี้และ Flag ของ Intent FLAG_ACTIVITY_REQUIRE_NON_BROWSER การเรียก startActivity() จะทําให้ระบบแสดง ActivityNotFoundException เมื่อเกิดเงื่อนไขอย่างใดอย่างหนึ่งต่อไปนี้

  • การเรียกใช้จะเปิดแอปเบราว์เซอร์โดยตรง
  • การเรียกใช้จะแสดงกล่องโต้ตอบการแยกแยะให้กับผู้ใช้

ข้อมูลโค้ดต่อไปนี้แสดงวิธีใช้ Flag FLAG_ACTIVITY_REQUIRE_NON_BROWSER และ FLAG_ACTIVITY_REQUIRE_DEFAULT ร่วมกัน

Kotlin

val url = URL_TO_LOAD
try {
    // For this intent to be invoked, the system must directly launch a
    // non-browser app.
    val intent = Intent(ACTION_VIEW, Uri.parse(url)).apply {
        addCategory(CATEGORY_BROWSABLE)
        flags = FLAG_ACTIVITY_NEW_TASK or FLAG_ACTIVITY_REQUIRE_NON_BROWSER or
                FLAG_ACTIVITY_REQUIRE_DEFAULT
    }
    startActivity(intent)
} catch (e: ActivityNotFoundException) {
    // This code executes in one of the following cases:
    // 1. Only browser apps can handle the intent.
    // 2. The user has set a browser app as the default app.
    // 3. The user hasn't set any app as the default for handling this URL.
    openInCustomTabs(url)
}

Java

String url = URL_TO_LOAD;
try {
    // For this intent to be invoked, the system must directly launch a
    // non-browser app.
    Intent intent = new Intent(ACTION_VIEW, Uri.parse(url));
    intent.addCategory(CATEGORY_BROWSABLE);
    intent.setFlags(FLAG_ACTIVITY_NEW_TASK | FLAG_ACTIVITY_REQUIRE_NON_BROWSER |
            FLAG_ACTIVITY_REQUIRE_DEFAULT);
    startActivity(intent);
} catch (ActivityNotFoundException e) {
    // This code executes in one of the following cases:
    // 1. Only browser apps can handle the intent.
    // 2. The user has set a browser app as the default app.
    // 3. The user hasn't set any app as the default for handling this URL.
    openInCustomTabs(url);
}

เปิดไฟล์

หากแอปจัดการไฟล์หรือไฟล์แนบ เช่น ตรวจสอบว่าอุปกรณ์เปิดไฟล์หนึ่งๆ ได้หรือไม่ วิธีง่ายที่สุดคือพยายามเริ่มกิจกรรมที่จัดการไฟล์ได้ โดยให้ใช้ Intent ที่มีการดำเนินการของ Intent ACTION_VIEW และ URI ที่แสดงไฟล์ที่เฉพาะเจาะจง หากไม่มีแอปใดในอุปกรณ์ แอปของคุณจะรับ ActivityNotFoundException ได้ ในตรรกะการจัดการข้อยกเว้น คุณสามารถแสดงข้อผิดพลาดหรือพยายามจัดการไฟล์ด้วยตนเอง

หากแอปต้องทราบล่วงหน้าว่าแอปอื่นเปิดไฟล์หนึ่งๆ ได้หรือไม่ ให้ใส่องค์ประกอบ ในสนิปตโค้ดต่อไปนี้เป็นส่วนหนึ่งขององค์ประกอบ ในไฟล์ Manifest ใส่ประเภทไฟล์หากคุณทราบอยู่แล้วว่าไฟล์เป็นประเภทใด ณ เวลาคอมไพล์



   android:name="android.intent.action.VIEW" />
  
   android:mimeType="application/pdf" />

จากนั้นคุณสามารถตรวจสอบว่าแอปพร้อมใช้งานหรือไม่โดยเรียกใช้ resolveActivity() พร้อมกับ Intent

ให้สิทธิ์เข้าถึง URI

หมายเหตุ: การประกาศสิทธิ์การเข้าถึง URI ตามที่อธิบายในส่วนนี้เป็นสิ่งจําเป็นสําหรับแอปที่กําหนดเป้าหมายเป็น Android 11 (API ระดับ 30) ขึ้นไป และแนะนําสําหรับแอปทั้งหมด ไม่ว่า SDK เป้าหมายจะเป็นเวอร์ชันใดและส่งออกผู้ให้บริการเนื้อหาหรือไม่ก็ตาม

สําหรับแอปที่กำหนดเป้าหมายเป็น Android 11 ขึ้นไปเพื่อเข้าถึง URI ของเนื้อหา Intent ของแอปต้องประกาศสิทธิ์เข้าถึง URI โดยการตั้งค่า Flag ของ Intent ต่อไปนี้อย่างน้อย 1 รายการ หรือทั้ง 2 รายการ FLAG_GRANT_READ_URI_PERMISSION และ FLAG_GRANT_WRITE_URI_PERMISSION

ใน Android 11 ขึ้นไป สิทธิ์การเข้าถึง URI จะให้ความสามารถต่อไปนี้แก่แอปที่ได้รับ Intent

  • อ่านจากหรือเขียนลงในข้อมูลที่ URI ของเนื้อหาแสดง โดยขึ้นอยู่กับสิทธิ์ URI ที่ระบุ
  • ดูข้อมูลแอปที่มีผู้ให้บริการเนื้อหาที่ตรงกับหน่วยงาน URI แอปที่มีผู้ให้บริการเนื้อหาอาจแตกต่างจากแอปที่ส่ง Intent

ข้อมูลโค้ดต่อไปนี้แสดงวิธีเพิ่ม Flag Intent สิทธิ์ URI เพื่อให้แอปอื่นที่กำหนดเป้าหมายเป็น Android 11 ขึ้นไปดูข้อมูลใน URI เนื้อหาได้

Kotlin

val shareIntent = Intent(Intent.ACTION_VIEW).apply {
    flags = Intent.FLAG_GRANT_READ_URI_PERMISSION
    data = CONTENT_URI_TO_SHARE_WITH_OTHER_APP
}

Java

Intent shareIntent = new Intent(Intent.ACTION_VIEW);
shareIntent.setFlags(FLAG_GRANT_READ_URI_PERMISSION);
shareIntent.setData(CONTENT_URI_TO_SHARE_WITH_OTHER_APP);

เชื่อมต่อกับบริการ

หากแอปต้องโต้ตอบกับบริการที่แสดงโดยอัตโนมัติไม่ได้ คุณสามารถประกาศการดำเนินการ Intent ที่เหมาะสมภายในองค์ประกอบ ส่วนต่อไปนี้จะแสดงตัวอย่างการใช้บริการที่เข้าถึงได้ทั่วไป

เชื่อมต่อกับเครื่องมือการอ่านออกเสียงข้อความ

หากแอปของคุณโต้ตอบกับเครื่องมืออ่านออกเสียงข้อความ (TTS) ให้ใส่องค์ประกอบ ต่อไปนี้เป็นส่วนหนึ่งขององค์ประกอบ ในไฟล์ Manifest



   android:name="android.intent.action.TTS_SERVICE" />

เชื่อมต่อกับบริการการรู้จำคำพูด

หากแอปของคุณโต้ตอบกับบริการจดจำคำพูด ให้ใส่องค์ประกอบ ต่อไปนี้เป็นส่วนหนึ่งขององค์ประกอบ ในไฟล์ Manifest



   android:name="android.speech.RecognitionService" />

เชื่อมต่อกับบริการเบราว์เซอร์สื่อ

หากแอปของคุณเป็นแอปเบราว์เซอร์สื่อไคลเอ็นต์ ให้ใส่องค์ประกอบ ต่อไปนี้เป็นส่วนหนึ่งขององค์ประกอบ ในไฟล์ Manifest



   android:name="android.media.browse.MediaBrowserService" />

ระบุฟังก์ชันการทำงานที่กำหนดเอง

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

ค้นหาแอป SMS

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



   android:name="android.intent.action.SENDTO"/>
   android:scheme="smsto" android:host="*" />

สร้างชีตการแชร์ที่กำหนดเอง

ใช้ชีตที่ระบบมีให้ทุกครั้งที่เป็นไปได้ หรือจะใส่องค์ประกอบ ต่อไปนี้เป็นส่วนหนึ่งขององค์ประกอบ ในไฟล์ Manifest ก็ได้



   android:name="android.intent.action.SEND" />
  
   android:mimeType="image/jpeg" />

กระบวนการสร้างชีตการแชร์ในตรรกะของแอป เช่น การเรียกใช้ queryIntentActivities() จะไม่มีการเปลี่ยนแปลงเมื่อเทียบกับ Android เวอร์ชันที่เก่ากว่า Android 11

แสดงการดำเนินการการเลือกข้อความที่กำหนดเอง

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



   android:name="android.intent.action.PROCESS_TEXT" />
   android:mimeType="text/plain" />

แสดงแถวข้อมูลที่กำหนดเองสำหรับรายชื่อติดต่อ

แอปสามารถเพิ่มแถวข้อมูลที่กำหนดเองลงในผู้ให้บริการรายชื่อติดต่อ แอปรายชื่อติดต่อต้องทําสิ่งต่อไปนี้ได้จึงจะแสดงข้อมูลที่กําหนดเองนี้ได้

  1. อ่านไฟล์ contacts.xml จากแอปอื่นๆ
  2. โหลดไอคอนที่สอดคล้องกับประเภท MIME ที่กําหนดเอง

หากแอปเป็นแอปรายชื่อติดต่อ ให้ใส่องค์ประกอบ ต่อไปนี้เป็นส่วนหนึ่งขององค์ประกอบ ในไฟล์ Manifest




   android:name="android.accounts.AccountAuthenticator" />



   android:name="android.intent.action.VIEW" />
   android:scheme="content" android:host="com.android.contacts"
        android:mimeType="vnd.android.cursor.item/*" />