使用者通常會想使用表情符號、貼圖和其他富有豐富資訊的方式與他人交流 內容。在舊版 Android 中,螢幕鍵盤 (也稱為 輸入法編輯器 IME:只能傳送萬國碼 (Unicode) 表情符號給應用程式。為了提供多媒體內容, 無法在其他應用程式中使用的應用程式專屬 API,或採用以下解決方法: 使用簡易分享動作傳送圖片 或剪貼簿
![顯示支援圖片搜尋功能的鍵盤的圖片](https://developer.android.com/static/images/guide/topics/text/image-keyboard-sample.png?hl=zh-tw)
從 Android 7.1 (API 級別 25) 開始,Android SDK 包含「修訂」 Content API,可讓輸入法編輯器傳送圖片及其他 直接將多媒體內容整合至應用程式的文字編輯器這個 API 也可在 自修訂版本 25.0.0 起。使用支援服務 程式庫,因為包含簡化實作的輔助方法。
有了這個 API,您就能建構可接受來自任何 Google 多媒體內容的訊息應用程式 以及能將多媒體內容傳送至任何應用程式的鍵盤。Google 鍵盤 以及「訊息供應商」等應用程式 Google 在 Android 7.1 中支援 Commit Content API,如圖 1 所示。
本文說明如何在 IME 和 IME 中實作 Commit Content API 應用程式。
運作方式
鍵盤圖片插入功能需要透過輸入法編輯器和應用程式啟用。 以下序列會說明圖片插入程序中的每個步驟:
使用者輕觸
EditText
時, 編輯器會將自己接受的 MIME 內容類型清單傳送至編輯器EditorInfo.contentMimeTypes
。IME 會讀取支援的類型清單,並在編輯器可接受的螢幕鍵盤中顯示內容。
使用者選取圖片時,IME 會呼叫
commitContent()
敬上 然後傳送InputContentInfo
。 加入編輯器commitContent()
呼叫類似於commitText()
呼叫,但適用於多媒體內容。InputContentInfo
包含的 URI 會指明內容 供應商。
這項程序如圖 2 所示:
![圖片:從應用程式到輸入法編輯器,再返回應用程式。](https://developer.android.com/static/images/guide/topics/text/image-keyboard-diagram.png?hl=zh-tw)
為應用程式新增圖片支援
如要接受來自 IME 的多媒體內容,應用程式必須告知輸入法編輯器
接受並指定系統接收內容時執行的回呼方法。
以下範例說明如何建立可接受 PNG 的 EditText
圖片:
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
是輸入法編輯器和 接收其輸入內容的應用程式。通話
super.onCreateInputConnection()
敬上 會保留內建行為 (傳送和接收文字) 可讓您取得InputConnection
的參照。setContentMimeTypes()
敬上 將支援的 MIME 類型清單新增至EditorInfo
。致電setContentMimeTypes()
前super.onCreateInputConnection()
。每當 IME 提交內容時,系統就會執行
callback
。方法onCommitContent()
敬上 包含InputContentInfoCompat
, ,其中包含內容 URI- 如果應用程式在 API 級別 25 中執行,可要求及發布權限
或以上版本
INPUT_CONTENT_GRANT_READ_URI_PERMISSION
敬上 旗標是由 IME 設定否則,您已可存取相關內容 URI,因為是由輸入法編輯器授予或內容供應器 不會限制存取詳情請參閱將圖片支援新增至 IME。
- 如果應用程式在 API 級別 25 中執行,可要求及發布權限
或以上版本
createWrapper()
敬上 會納入InputConnection
、修改的EditorInfo
和回呼 並傳回新的InputConnection
以下是建議做法:
不支援多媒體內容的編輯器無法呼叫
setContentMimeTypes()
,而他離開了EditorInfo.contentMimeTypes
設定 至null
。如果
InputContentInfo
中指定的 MIME 類型,編輯器會忽略內容 不符合他們接受的任何類型多媒體內容不會影響文字位置,也不會受文字位置影響 。編輯器在處理內容時可忽略遊標位置。
在編輯器中的
OnCommitContentListener.onCommitContent()
方法時,您可以透過非同步方式傳回true
,即使 再載入內容文字可在提交前於輸入法編輯器中編輯 就會立即提交相關內容如要讓使用者編輯或刪除 自行實作相關邏輯
如要測試應用程式,請確認裝置或模擬器有可傳送的鍵盤 多媒體內容您可以在 Android 7.1 以上版本中使用 Google 鍵盤。
為 IME 新增圖片支援
想傳送多媒體內容的 IME 給應用程式,就必須實作 Commit 內容 API,如以下範例所示:
- 覆寫
onStartInput()
或onStartInputView()
,並讀取目標中支援的內容類型清單。 編輯。以下程式碼片段說明如何檢查目標編輯器是否接受 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 的存取權。方法有以下兩種:
在 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()
,但您可以自行實作, 即可滿足自己的需求
如要測試輸入法編輯器,請確認裝置或模擬器有可接收的應用程式 多媒體內容你可以在 Android 7.1 以上版本中使用 Google Messenger 應用程式。