ผู้ใช้มักต้องการสื่อสารโดยใช้อีโมจิ สติกเกอร์ และรูปหลากหลายประเภทอื่นๆ เนื้อหา ใน Android เวอร์ชันก่อนหน้า แป้นพิมพ์เสมือนหรือที่เรียกว่า เครื่องมือแก้ไขวิธีการป้อนข้อมูล หรือ IME - ส่งได้เฉพาะอีโมจิแบบ Unicode ไปยังแอป แอปที่สร้างขึ้นสำหรับเนื้อหาอย่างละเอียด API เฉพาะแอปที่ไม่สามารถใช้ในแอปอื่นหรือใช้วิธีแก้ปัญหาเบื้องต้น เช่น การส่งรูปภาพผ่านการดำเนินการแชร์อย่างง่าย หรือคลิปบอร์ด
![รูปภาพแสดงแป้นพิมพ์ที่รองรับการค้นหารูปภาพ](https://developer.android.com/static/images/guide/topics/text/image-keyboard-sample.png?hl=th)
สำหรับ Android SDK ใน Android 7.1 (API ระดับ 25) เป็นต้นไปจะมีสัญญาผูกมัด Content API ซึ่งเป็นวิธีสากลสำหรับ IME ในการส่งรูปภาพและ ข้อมูลอย่างละเอียดไปยังเครื่องมือแก้ไขข้อความในแอปโดยตรง API ยังพร้อมใช้งานใน ไลบรารีการสนับสนุน v13 ณ การแก้ไข 25.0.0 เราขอแนะนำให้ใช้การสนับสนุน ไลบรารีเนื่องจากมีเมธอด Helper ที่ทำให้การใช้งานง่ายขึ้น
คุณสามารถใช้ API นี้สร้างแอปรับส่งข้อความที่ยอมรับข้อมูลอย่างละเอียดจาก แป้นพิมพ์ตลอดจนแป้นพิมพ์ที่สามารถส่งเนื้อหาแบบสมบูรณ์ไปยังแอปพลิเคชันใดก็ได้ แป้นพิมพ์ และแอปอย่าง Messages โดย Google รองรับ Commit Content API ใน Android 7.1 ดังที่แสดงในรูปที่ 1
เอกสารนี้แสดงวิธีใช้ Commit Content API ทั้งใน IME และ แอป
วิธีการทำงาน
การแทรกรูปภาพแป้นพิมพ์ต้องมีการมีส่วนร่วมจาก IME และแอป ลำดับต่อไปนี้จะอธิบายแต่ละขั้นตอนในกระบวนการแทรกรูปภาพ
เมื่อผู้ใช้แตะ
EditText
เครื่องมือแก้ไขจะส่งรายการประเภทเนื้อหา MIME ที่ยอมรับEditorInfo.contentMimeTypes
IME จะอ่านรายการประเภทที่สนับสนุนและแสดงเนื้อหาในตัวเลือก แป้นพิมพ์ที่โปรแกรมแก้ไขสามารถยอมรับได้
เมื่อผู้ใช้เลือกรูปภาพ หมายเลข IME จะเรียกใช้
commitContent()
และส่งInputContentInfo
กับเอดิเตอร์เท่านั้น การเรียกcommitContent()
คล้ายกับการเรียกcommitText()
แต่ใช้เรียกเนื้อหาอย่างละเอียดInputContentInfo
มี URI ที่ ระบุเนื้อหาในเนื้อหา เป็นผู้ให้บริการคลาวด์
กระบวนการนี้แสดงอยู่ในรูปที่ 2
![รูปภาพแสดงลำดับจากแอปพลิเคชันไปยัง IME และกลับไปที่แอปพลิเคชัน](https://developer.android.com/static/images/guide/topics/text/image-keyboard-diagram.png?hl=th)
เพิ่มการรองรับรูปภาพในแอป
ในการยอมรับข้อมูลอย่างละเอียดจาก IME แอปจะต้องบอก IME ว่าเนื้อหาประเภทใด
ยอมรับและระบุเมธอด Callback ที่จะทำงานเมื่อได้รับเนื้อหา
ตัวอย่างต่อไปนี้แสดงวิธีการสร้าง EditText
ที่ยอมรับ PNG
รูปภาพ:
Kotlin
var editText: EditText = object : EditText(this) { override fun onCreateInputConnection(outAttrs: EditorInfo): InputConnection { var ic = super.onCreateInputConnection(outAttrs) EditorInfoCompat.setContentMimeTypes(outAttrs, arrayOf("image/png")) val mimeTypes = ViewCompat.getOnReceiveContentMimeTypes(this) if (mimeTypes != null) { EditorInfoCompat.setContentMimeTypes(outAttrs, mimeTypes) ic = InputConnectionCompat.createWrapper(this, ic, outAttrs) } return ic } }
Java
EditText editText = new EditText(this) { @Override public InputConnection onCreateInputConnection(EditorInfo outAttrs) { InputConnection ic = super.onCreateInputConnection(outAttrs); EditorInfoCompat.setContentMimeTypes(outAttrs, new String[]{"image/png"}); String[] mimeTypes = ViewCompat.getOnReceiveContentMimeTypes(this); if (mimeTypes != null) { EditorInfoCompat.setContentMimeTypes(outAttrs, mimeTypes); ic = InputConnectionCompat.createWrapper(this, ic, outAttrs); } return ic; } };
ต่อไปนี้เป็นคำอธิบายเพิ่มเติม
ตัวอย่างนี้ใช้ไลบรารีการสนับสนุน จึงมีการอ้างอิงไปที่
android.support.v13.view.inputmethod
แทนที่จะเป็นandroid.view.inputmethod
ตัวอย่างนี้สร้าง
EditText
และลบล้างonCreateInputConnection(EditorInfo)
เพื่อแก้ไขInputConnection
InputConnection
คือช่องทางการสื่อสารระหว่าง IME กับ ที่กำลังรับอินพุตการโทร
super.onCreateInputConnection()
จะรักษาลักษณะการทำงานในตัว เช่น การส่งและรับข้อความ และ มีการอ้างอิงถึงInputConnection
setContentMimeTypes()
เพิ่มรายการประเภท MIME ที่รองรับไปยังEditorInfo
โทรsuper.onCreateInputConnection()
ก่อนsetContentMimeTypes()
callback
จะถูกเรียกใช้ทุกครั้งที่ IME คอมมิตเนื้อหา วิธีการonCommitContent()
มีการอ้างอิงถึงInputContentInfoCompat
, ที่มี URI ของเนื้อหา- ขอและปล่อยสิทธิ์หากแอปของคุณทำงานใน API ระดับ 25
หรือสูงกว่า และ
INPUT_CONTENT_GRANT_READ_URI_PERMISSION
ซึ่ง IME จะเป็นผู้กำหนดธง ไม่เช่นนั้น คุณจะมีสิทธิ์เข้าถึงเนื้อหาอยู่แล้ว URI เนื่องจากได้มาจาก IME หรือเนื่องจากผู้ให้บริการเนื้อหา ไม่ได้จำกัดการเข้าถึง สำหรับข้อมูลเพิ่มเติม โปรดดูที่เพิ่มการสนับสนุนรูปภาพไปยัง IME
- ขอและปล่อยสิทธิ์หากแอปของคุณทำงานใน API ระดับ 25
หรือสูงกว่า และ
createWrapper()
รวมInputConnection
,EditorInfo
ที่แก้ไข และ Callback ลงในInputConnection
ใหม่และส่งคืน
แนวทางปฏิบัติที่แนะนำมีดังนี้
ผู้แก้ไขที่ไม่สนับสนุนข้อมูลอย่างละเอียดจะไม่เรียกใช้
setContentMimeTypes()
และสมาชิกออกจากการตั้งค่าEditorInfo.contentMimeTypes
แล้ว ไปยังnull
เอดิเตอร์จะไม่สนใจเนื้อหาหากประเภท MIME ที่ระบุไว้ใน
InputContentInfo
ไม่ตรงกับประเภทใดๆ ที่พวกเขายอมรับข้อมูลอย่างละเอียดไม่มีผลกระทบและไม่ได้รับผลกระทบจากตำแหน่งของข้อความ เคอร์เซอร์ เอดิเตอร์จะเพิกเฉยต่อตำแหน่งเคอร์เซอร์เมื่อทำงานกับเนื้อหาได้
ใน
OnCommitContentListener.onCommitContent()
คุณสามารถแสดงผลtrue
แบบไม่พร้อมกันแม้ ก่อนที่จะโหลดเนื้อหาแตกต่างจากข้อความ ซึ่งแก้ไขได้ใน IME ก่อนที่จะเริ่มต้น เนื้อหานั้นจะตกลงทันที หากต้องการให้ผู้ใช้แก้ไขหรือลบ ให้ใช้ตรรกะด้วยตนเอง
ในการทดสอบแอป โปรดตรวจสอบว่าอุปกรณ์หรือโปรแกรมจำลองมีแป้นพิมพ์ที่ส่ง ข้อมูลอย่างละเอียด คุณสามารถใช้แป้นพิมพ์ของ Google ใน Android 7.1 ขึ้นไป
เพิ่มการรองรับอิมเมจไปยัง IME
IME ที่ต้องการส่ง Rich Content ไปยังแอปต้องใช้ Commit Content API ตามที่แสดงในตัวอย่างต่อไปนี้
- ลบล้าง
onStartInput()
หรือonStartInputView()
และอ่านรายการประเภทเนื้อหาที่รองรับจากเป้าหมาย Editor ข้อมูลโค้ดต่อไปนี้จะแสดงวิธีตรวจสอบว่าเป้าหมาย โปรแกรมแก้ไขยอมรับรูปภาพ GIF
Kotlin
override fun onStartInputView(editorInfo: EditorInfo, restarting: Boolean) { val mimeTypes: Array<String> = EditorInfoCompat.getContentMimeTypes(editorInfo) val gifSupported: Boolean = mimeTypes.any { ClipDescription.compareMimeTypes(it, "image/gif") } if (gifSupported) { // The target editor supports GIFs. Enable the corresponding content. } else { // The target editor doesn't support GIFs. Disable the corresponding // content. } }
Java
@Override public void onStartInputView(EditorInfo info, boolean restarting) { String[] mimeTypes = EditorInfoCompat.getContentMimeTypes(editorInfo); boolean gifSupported = false; for (String mimeType : mimeTypes) { if (ClipDescription.compareMimeTypes(mimeType, "image/gif")) { gifSupported = true; } } if (gifSupported) { // The target editor supports GIFs. Enable the corresponding content. } else { // The target editor doesn't support GIFs. Disable the corresponding // content. } }
- ส่งเนื้อหาไปยังแอปเมื่อผู้ใช้เลือกรูปภาพ หลีกเลี่ยงการโทร
commitContent()
เมื่อมีการเขียนข้อความขึ้น เนื่องจาก อาจทำให้เครื่องมือแก้ไขเสียโฟกัสได้ ข้อมูลโค้ดต่อไปนี้จะแสดงวิธีการ เพื่อคอมมิตรูปภาพ GIF
Kotlin
// Commits a GIF image. // @param contentUri = Content URI of the GIF image to be sent. // @param imageDescription = Description of the GIF image to be sent. fun commitGifImage(contentUri: Uri, imageDescription: String) { val inputContentInfo = InputContentInfoCompat( contentUri, ClipDescription(imageDescription, arrayOf("image/gif")), null ) val inputConnection = currentInputConnection val editorInfo = currentInputEditorInfo var flags = 0 if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N_MR1) { flags = flags or InputConnectionCompat.INPUT_CONTENT_GRANT_READ_URI_PERMISSION } InputConnectionCompat.commitContent(inputConnection, editorInfo, inputContentInfo, flags, null) }
Java
// Commits a GIF image. // @param contentUri = Content URI of the GIF image to be sent. // @param imageDescription = Description of the GIF image to be sent. public static void commitGifImage(Uri contentUri, String imageDescription) { InputContentInfoCompat inputContentInfo = new InputContentInfoCompat( contentUri, new ClipDescription(imageDescription, new String[]{"image/gif"}), null ); InputConnection inputConnection = getCurrentInputConnection(); EditorInfo editorInfo = getCurrentInputEditorInfo(); Int flags = 0; if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N_MR1) { flags |= InputConnectionCompat.INPUT_CONTENT_GRANT_READ_URI_PERMISSION; } InputConnectionCompat.commitContent( inputConnection, editorInfo, inputContentInfo, flags, null); }
ในฐานะผู้เขียน IME คุณมักจะต้องใช้ผู้ให้บริการเนื้อหาของตนเองเพื่อ
ตอบสนองต่อคำขอ URI เนื้อหา ข้อยกเว้นคือในกรณีที่ IME ของคุณรองรับเนื้อหา
จากผู้ให้บริการเนื้อหาที่มีอยู่ เช่น
MediaStore
สำหรับข้อมูลเกี่ยวกับ
ผู้ให้บริการเนื้อหาก่อสร้าง โปรดดูเนื้อหา
ผู้ให้บริการและไฟล์
ของผู้ให้บริการโดยตรง
หากคุณกำลังสร้างผู้ให้บริการเนื้อหาของคุณเอง ขอแนะนำว่าอย่าส่งออก
ตามการตั้งค่า
android:exported
ถึง
false
ให้เปิดใช้การให้สิทธิ์ในผู้ให้บริการโดยการตั้งค่าแทน
android:grantUriPermission
ไปยัง true
จากนั้น IME สามารถให้สิทธิ์เข้าถึง URI เนื้อหาเมื่อ
เนื้อหาต้องมีการยืนยัน ซึ่งทำได้ 2 วิธีดังนี้
ใน Android 7.1 (API ระดับ 25) ขึ้นไป เมื่อโทรหา
commitContent()
ให้ตั้งพารามิเตอร์แฟล็กเป็นINPUT_CONTENT_GRANT_READ_URI_PERMISSION
จากนั้นออบเจ็กต์InputContentInfo
ที่แอปได้รับจะขอและ ปล่อยสิทธิ์การอ่านชั่วคราวโดยการเรียกใช้requestPermission()
และreleasePermission()
ใน Android 7.0 (API ระดับ 24) และต่ำกว่า ไม่สนใจ
INPUT_CONTENT_GRANT_READ_URI_PERMISSION
แล้ว โปรดให้สิทธิ์ด้วยตนเอง สิทธิ์ในเนื้อหา วิธีหนึ่งที่ทำได้คือgrantUriPermission()
แต่คุณสามารถใช้กลไกของตนเองซึ่ง เป็นไปตามข้อกำหนดของคุณเอง
ในการทดสอบ IME โปรดตรวจสอบว่าอุปกรณ์หรือโปรแกรมจำลองมีแอปที่รับ ข้อมูลอย่างละเอียด คุณสามารถใช้แอป Google Messenger ได้ใน Android 7.1 ขึ้นไป