รับเนื้อหาอย่างละเอียด

รูปที่ 1 API แบบรวมเป็นศูนย์รวมในการจัดการ เนื้อหาที่เข้ามาใหม่โดยไม่คำนึงถึงกลไก UI เฉพาะ เช่น การวาง จากการสัมผัสและ กดเมนูค้างไว้หรือใช้ลากและวาง

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

คุณสามารถแนบอินเทอร์เฟซ เช่น OnReceiveContentListener ลงในคอมโพเนนต์ UI และรับ Callback เมื่อมีการแทรกเนื้อหาผ่าน Google Analytics Callback จะเป็นที่เดียวที่โค้ดให้คุณจัดการ รับเนื้อหาทั้งหมด ตั้งแต่ข้อความธรรมดาและข้อความที่จัดรูปแบบ ไปจนถึงมาร์กอัป รูปภาพ วิดีโอ ไฟล์เสียง และอื่นๆ

สำหรับความเข้ากันได้แบบย้อนหลังกับ Android เวอร์ชันก่อนหน้า API นี้ยัง มีให้บริการใน AndroidX ราคาเริ่มต้นที่ Core 1.7 และ Appcompat 1.4 ที่เราขอแนะนำให้คุณใช้เมื่อใช้ฟังก์ชันนี้

ภาพรวม

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

วันที่ รูปภาพแสดงการดำเนินการต่างๆ และ API ที่เกี่ยวข้องเพื่อติดตั้งใช้งาน
รูปที่ 2 ก่อนหน้านี้ แอปใช้ API ที่แตกต่างกันสำหรับ UI แต่ละรายการ ในการแทรกเนื้อหา

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

วันที่ รูปภาพแสดง API แบบรวมแบบง่าย
รูปที่ 3 API แบบรวมช่วยให้คุณใช้งาน API ที่รองรับกลไก UI ทั้งหมด

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

การใช้งาน

API คืออินเทอร์เฟซ Listener ที่มีเมธอดเดียว OnReceiveContentListener หากต้องการรองรับแพลตฟอร์ม Android เวอร์ชันเก่า เราขอแนะนําให้ใช้ การจับคู่ OnReceiveContentListener ในไลบรารี AndroidX Core

ในการใช้ API ให้ใช้ Listener โดยการระบุประเภทเนื้อหาของคุณ สามารถจัดการสิ่งเหล่านี้ได้:

Kotlin

object MyReceiver : OnReceiveContentListener {
    val MIME_TYPES = arrayOf("image/*", "video/*")
    
    // ...
    
    override fun onReceiveContent(view: View, payload: ContentInfoCompat): ContentInfoCompat? {
        TODO("Not yet implemented")
    }
}

Java

public class MyReceiver implements OnReceiveContentListener {
     public static final String[] MIME_TYPES = new String[] {"image/*", "video/*"};
     // ...
}

หลังจากระบุประเภท MIME เนื้อหาทั้งหมดที่แอปของคุณรองรับแล้ว ให้ใช้ ผู้ฟังที่เหลือ:

Kotlin

class MyReceiver : OnReceiveContentListener {
    override fun onReceiveContent(view: View, contentInfo: ContentInfoCompat): ContentInfoCompat {
        val split = contentInfo.partition { item: ClipData.Item -> item.uri != null }
        val uriContent = split.first
        val remaining = split.second
        if (uriContent != null) {
            // App-specific logic to handle the URI(s) in uriContent.
        }
        // Return anything that your app didn't handle. This preserves the
        // default platform behavior for text and anything else that you aren't
        // implementing custom handling for.
        return remaining
    }

    companion object {
        val MIME_TYPES = arrayOf("image/*", "video/*")
    }
}

Java

 public class MyReceiver implements OnReceiveContentListener {
     public static final String[] MIME_TYPES = new String[] {"image/*", "video/*"};

     @Override
     public ContentInfoCompat onReceiveContent(View view, ContentInfoCompat contentInfo) {
         Pair<ContentInfoCompat, ContentInfoCompat> split = contentInfo.partition(
                 item -> item.getUri() != null);
         ContentInfo uriContent = split.first;
         ContentInfo remaining = split.second;
         if (uriContent != null) {
             // App-specific logic to handle the URI(s) in uriContent.
         }
         // Return anything that your app didn't handle. This preserves the
         // default platform behavior for text and anything else that you aren't
         // implementing custom handling for.
         return remaining;
     }
 }

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

หลังจากใช้งาน Listener แล้ว ให้ตั้งค่าในองค์ประกอบ UI ที่เหมาะสมใน แอปของคุณ

Kotlin

class MyActivity : Activity() {
    public override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        // ...
        val myInput = findViewById(R.id.my_input)
        ViewCompat.setOnReceiveContentListener(myInput, MyReceiver.MIME_TYPES, MyReceiver())
    }
}

Java

public class MyActivity extends Activity {
     @Override
     public void onCreate(Bundle savedInstanceState) {
         // ...

         AppCompatEditText myInput = findViewById(R.id.my_input);
         ViewCompat.setOnReceiveContentListener(myInput, MyReceiver.MIME_TYPES, new MyReceiver());
     }
}

สิทธิ์ URI

แพลตฟอร์มจะให้สิทธิ์อ่านและถอนสิทธิ์อ่านโดยอัตโนมัติสำหรับ URI เนื้อหาในไฟล์ เพย์โหลดที่ส่งไปยัง OnReceiveContentListener

โดยปกติแล้ว แอปจะประมวลผล URI เนื้อหาในบริการหรือกิจกรรม สำหรับ การประมวลผลเป็นเวลานาน ใช้ WorkManager เมื่อคุณใช้ ขยายสิทธิ์ไปยังบริการหรือกิจกรรมเป้าหมายโดยการส่ง เนื้อหาที่ใช้ Intent.setClipData และการตั้งค่าการตั้งค่าสถานะ FLAG_GRANT_READ_URI_PERMISSION

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

มุมมองที่กำหนดเอง

หากแอปใช้คลาสย่อย View ที่กำหนดเอง โปรดตรวจสอบว่า ไม่ถูกข้าม OnReceiveContentListener

หากชั้นเรียน View ลบล้าง onCreateInputConnection ให้ใช้ Jetpack API InputConnectionCompat.createWrapper เพื่อกำหนดค่า InputConnection

หากชั้นเรียน View ลบล้าง onTextContextMenuItem ให้มอบสิทธิ์ให้กับ Super เมื่อรายการในเมนู R.id.paste หรือ R.id.pasteAsPlainText

การเปรียบเทียบกับ API รูปภาพแป้นพิมพ์

คุณอาจมองว่า OnReceiveContentListener API เป็นเวอร์ชันถัดไปของ API รูปภาพแป้นพิมพ์อยู่แล้ว แบบรวมนี้ API สนับสนุนฟังก์ชันการทำงานของ API รูปภาพแป้นพิมพ์เช่นเดียวกับ ฟีเจอร์เพิ่มเติม ความเข้ากันได้ของอุปกรณ์และฟีเจอร์จะแตกต่างกันไปขึ้นอยู่กับ ไม่ว่าคุณจะใช้ไลบรารี Jetpack หรือ API เนทีฟจาก Android SDK

ตาราง 1 ฟีเจอร์และระดับ API ที่รองรับสำหรับ Jetpack
การดำเนินการหรือฟีเจอร์ รองรับโดย API รูปภาพแป้นพิมพ์ รองรับโดย API แบบรวม
แทรกจากแป้นพิมพ์ มี (API ระดับ 13 ขึ้นไป) ใช่ (API ระดับ 13 และสูงกว่า)
แทรกโดยใช้การวางจากการแตะและ เมนูการระงับ ไม่ ใช่
แทรกโดยใช้การลากและวาง ไม่ ใช่ (API ระดับ 24 ขึ้นไป)
ตาราง 2 ฟีเจอร์และระดับ API ที่รองรับสำหรับโฆษณาเนทีฟ API
การดำเนินการหรือฟีเจอร์ รองรับโดย API รูปภาพแป้นพิมพ์ รองรับโดย API แบบรวม
แทรกจากแป้นพิมพ์ มี (API ระดับ 25 ขึ้นไป) ใช่ (Android 12 ขึ้นไป)
แทรกโดยใช้การวางจากการแตะและ เมนูการระงับ ไม่
แทรกโดยใช้การลากและวาง ไม่