【Touch&input 】图像键盘支持(20)

用户经常想要与emojis,贴纸以及其他丰富内容进行交流。在以前的Android版本中,软键盘(也称为 输入法编辑器或IME)只能将unicode表情符号发送到应用程序。对于丰富的内容,应用程序必须构建无法在其他应用程序中使用的特定于应用程序的API,或者使用通过Easy Share Action 或剪贴板发送图像的解决方法。

在Android 7.1(API等级25)中,Android SDK包含提交内容API,该API提供了一种通用方式,可让IME将图像和其他丰富内容直接发送到应用中的文本编辑器。自修订版25.0.0起,v13支持库中也提供该API。我们建议使用支持库,因为它早在Android 3.2(API Level 13)上运行于设备上,并且包含帮助程序方法以简化实施。

借助此API,您可以构建可接收来自任何键盘的丰富内容的通讯应用程序,以及可将丰富内容发送到任何应用程序的键盘。在 谷歌键盘 和应用程序,如 谷歌Messenger的 支持安卓7.1的提交内容API(见图1)。

本页面向您展示如何在IME和应用程序中实施提交内容API。
【Touch&input 】图像键盘支持(20)
图1.图像键盘支持的示例

怎么运行的


键盘图像插入需要IME和应用程序的参与。以下序列描述图像插入过程中的每个步骤:

当用户点击an时EditText,编辑器发送一个它接受的MIME内容类型列表EditorInfo.contentMimeTypes。

IME读取支持的类型列表,并在编辑器可以接受的软键盘上显示内容。

当用户选择图像时,IME会调用并发commitContent()送给 InputContentInfo 编辑器。该commitContent()呼叫与呼叫类似commitText(),但对于丰富的内容。InputContentInfo包含标识内容提供者中内容的URI 。然后,您的应用可以请求权限并从URI读取内容。
【Touch&input 】图像键盘支持(20)

为应用程序添加图像支持


要接受来自IME的丰富内容,应用程序必须告知IME它接受哪些内容类型,并指定在收到内容时执行的回调方法。以下示例演示如何创建一个EditText接受PNG图像的方法:

EditText editText = new EditText(this) {
    @Override
    public InputConnection onCreateInputConnection(EditorInfo editorInfo) {
        final InputConnection ic = super.onCreateInputConnection(editorInfo);
        EditorInfoCompat.setContentMimeTypes(editorInfo,
                new String [] {"image/png"});

        final InputConnectionCompat.OnCommitContentListener callback =
            new InputConnectionCompat.OnCommitContentListener() {
                @Override
                public boolean onCommitContent(InputContentInfoCompat inputContentInfo,
                        int flags, Bundle opts) {
                    // read and display inputContentInfo asynchronously
                    if (BuildCompat.isAtLeastNMR1() && (flags &
                        InputConnectionCompat.INPUT_CONTENT_GRANT_READ_URI_PERMISSION) != 0) {
                        try {
                            inputContentInfo.requestPermission();
                        }
                        catch (Exception e) {
                            return false; // return false if failed
                        }
                    }

                    // read and display inputContentInfo asynchronously.
                    // call inputContentInfo.releasePermission() as needed.

                    return true;  // return true if succeeded
                }
            };
        return InputConnectionCompat.createWrapper(ic, editorInfo, callback);
    }
};

有很多事情要做,所以让我们来解释一下发生了什么。

这个例子使用支持库,所以有一些引用来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 Level 25或更高版本上运行,并且该INPUT_CONTENT_GRANT_READ_URI_PERMISSION 标志由IME设置,则应该请求并释放权限。否则,您应该已经可以访问内容URI,因为它是由IME授予的,或者因为内容提供者不限制访问权限。有关更多信息,请参阅将图像支持添加到IME。
createWrapper() 将inputConnection,修改后的editorInfo和回调包装成一个新的InputConnection并返回它。

以下是一些推荐的做法:

不支持丰富的内容不应调用编辑 setContentMimeTypes() 并离开自己的EditorInfo.contentMimeTypes 一套来null。

如果指定的MIME类型InputContentInfo 与它接受的任何类型不匹配,编辑应该忽略内容 。

丰富的内容不会影响文本光标的位置,也不会受其影响。处理内容时,编辑者可以忽略光标位置。

在编辑器的 OnCommitContentListener.onCommitContent() 方法中true,即使在加载内容之前,也可以异步返回。

与提交前可在IME中编辑的文本不同,丰富的内容会立即提交。请注意,如果您想为用户提供编辑或删除内容的能力,则必须自己实施逻辑。

要测试您的应用,请确保您的设备或模拟器具有能够发送丰富内容的键盘。您可以使用Android 7.1或更高版本的Google键盘,也可以安装CommitContent IME示例。

有关完整的代码示例,请参阅CommitContent App示例

为IME添加图像支持


想要向应用发送丰富内容的IME必须实现Commit Content API,如下所示:
覆盖onStartInput()或onStartInputView()从目标编辑器读取支持的内容类型列表。以下代码片段显示了如何检查目标编辑器是否接受GIF图像。

@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 corresponding content
    } else {
        // the target editor does not support GIFs. disable corresponding content
    }
}

当用户选择图像时向内容提交内容。避免commitContent() 在有任何撰写文本时调用 ,因为这可能会导致编辑器失去焦点。以下代码片段显示了如何提交GIF图像。

/**
 * 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"}));
    InputConnection inputConnection = getCurrentInputConnection();
    EditorInfo editorInfo = getCurrentInputEditorInfo();
    Int flags = 0;
    if (android.os.Build.VERSION.SDK_INT >= 25) {
        flags |= InputConnectionCompat.INPUT_CONTENT_GRANT_READ_URI_PERMISSION;
    }
    InputConnectionCompat.commitContent(
            inputConnection, editorInfo, inputContentInfo, flags, opts);
}

作为IME作者,您很可能必须实现自己的内容提供者才能响应内容URI请求。例外情况是,如果您的IME支持来自现有内容提供商的内容MediaStore。有关构建内容提供者的信息,请参阅CommitContent IME示例, Content Provider文档和文件提供者 文档。

如果您正在构建自己的内容提供商,我们建议您不要导出它(设置 android:导出 到false)。相反,启用权限,通过设置在供应商给予 的android:grantUriPermission 来true。然后,当提交内容时,IME可以授予访问内容URI的权限。有两种方法可以做到这一点:

在Android 7.1(API Level 25)及更高版本上调用时commitContent(),请将flag参数设置为INPUT_CONTENT_GRANT_READ_URI_PERMISSION。然后,InputContentInfo 应用程序接收的对象可以通过调用requestPermission() 和请求并释放临时读取权限releasePermission()。

在Android 7.0(API级别24)及更低级别上,将INPUT_CONTENT_GRANT_READ_URI_PERMISSION 被忽略,因此您需要手动授予内容权限。一种方法是使用grantUriPermission(),但你可以实现你自己的机制来满足你自己的需求。

有关权限授予的示例,请参阅CommitContent IME示例中的doCommitContent()方法。

要测试IME,请确保您的设备或模拟器具有能够接收丰富内容的应用程序。您可以使用Android 7.1或更高版本中的Google Messenger应用程序,也可以安装 CommitContent Sample App。

有关完整的代码示例,请参阅CommitContent IME示例

Lastest Update:2018.04.24

联系我

QQ:94297366
微信打赏:https://pan.baidu.com/s/1dSBXk3eFZu3mAMkw3xu9KQ

公众号推荐:

【Touch&input 】图像键盘支持(20)

猜你喜欢

转载自blog.51cto.com/4789781/2125397
今日推荐