原
用户经常想要与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。
图1.图像键盘支持的示例
怎么运行的
键盘图像插入需要IME和应用程序的参与。以下序列描述图像插入过程中的每个步骤:
当用户点击an时EditText,编辑器发送一个它接受的MIME内容类型列表EditorInfo.contentMimeTypes。
IME读取支持的类型列表,并在编辑器可以接受的软键盘上显示内容。
当用户选择图像时,IME会调用并发commitContent()送给 InputContentInfo 编辑器。该commitContent()呼叫与呼叫类似commitText(),但对于丰富的内容。InputContentInfo包含标识内容提供者中内容的URI 。然后,您的应用可以请求权限并从URI读取内容。
为应用程序添加图像支持
要接受来自IME的丰富内容,应用程序必须告知IME它接受哪些内容类型,并指定在收到内容时执行的回调方法。以下示例演示如何创建一个EditText接受PNG图像的方法:
EditText editText = new EditText(this) {@Overridepublic InputConnection onCreateInputConnection(EditorInfo editorInfo) {final InputConnection ic = super.onCreateInputConnection(editorInfo);EditorInfoCompat.setContentMimeTypes(editorInfo,new String [] {"image/png"});final InputConnectionCompat.OnCommitContentListener callback =new InputConnectionCompat.OnCommitContentListener() {@Overridepublic boolean onCommitContent(InputContentInfoCompat inputContentInfo,int flags, Bundle opts) {// read and display inputContentInfo asynchronouslyif (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
公众号推荐: