圖片鍵盤支援

使用者通常會想使用表情符號、貼圖和其他富有豐富資訊的方式與他人交流 內容。在舊版 Android 中,螢幕鍵盤 (也稱為 輸入法編輯器 IME:只能傳送萬國碼 (Unicode) 表情符號給應用程式。為了提供多媒體內容, 無法在其他應用程式中使用的應用程式專屬 API,或採用以下解決方法: 使用簡易分享動作傳送圖片 或剪貼簿

顯示支援圖片搜尋功能的鍵盤的圖片
圖 1. 圖片鍵盤支援範例。

從 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 應用程式。

運作方式

鍵盤圖片插入功能需要透過輸入法編輯器和應用程式啟用。 以下序列會說明圖片插入程序中的每個步驟:

  1. 使用者輕觸 EditText 時, 編輯器會將自己接受的 MIME 內容類型清單傳送至編輯器 EditorInfo.contentMimeTypes

  2. IME 會讀取支援的類型清單,並在編輯器可接受的螢幕鍵盤中顯示內容。

  3. 使用者選取圖片時,IME 會呼叫 commitContent()敬上 然後傳送 InputContentInfo。 加入編輯器commitContent() 呼叫類似於 commitText() 呼叫,但適用於多媒體內容。InputContentInfo 包含的 URI 會指明內容 供應商

這項程序如圖 2 所示:

圖片:從應用程式到輸入法編輯器,再返回應用程式。
圖 2. 從 IME 到應用程式流程。

為應用程式新增圖片支援

如要接受來自 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;
    }
};

以下將進一步說明:

以下是建議做法:

  • 不支援多媒體內容的編輯器無法呼叫 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:exportedfalse。請改為透過設定 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 應用程式。