EditTextGIF插入GIF时Bundle opts始终为null的解决方法
问题描述
基于第三方表情键盘库AXEmojiEditText实现了支持插入GIF的EditTextGIF,插入GIF时不再提示“不允许插入GIF”,但回调中接收的Bundle opts始终为null,无论选择哪个GIF都是如此。
相关代码如下:
设置回调的代码
editText.setKeyBoardInputCallbackListener(new EditTextGIF.KeyBoardInputCallbackListener() { @Override public void onCommitContent(InputContentInfoCompat inputContentInfo, int flags, Bundle opts) { // you will get your gif/png/jpg here in opts bundle Log.d(TAG, "Opts: "+opts); } });
布局中的EditTextGIF
<com.myapp.EditTextGIF android:id="@+id/editText" android:layout_width="match_parent" android:layout_height="wrap_content" android:inputType="textCapSentences|textMultiLine" android:textColor="@color/textcolor" android:background="@null" android:maxLength="@integer/max_chat_message_length" android:hint="@string/type_a_message" />
EditTextGIF类代码
public class EditTextGIF extends AXEmojiEditText { private KeyBoardInputCallbackListener keyBoardInputCallbackListener; public EditTextGIF(Context context) { super(context); } public EditTextGIF(Context context, AttributeSet attrs) { super(context, attrs); } @Override public InputConnection onCreateInputConnection(EditorInfo editorInfo) { final InputConnection ic = super.onCreateInputConnection(editorInfo); EditorInfoCompat.setContentMimeTypes(editorInfo, new String [] {"image/gif"}); final InputConnectionCompat.OnCommitContentListener callback = new InputConnectionCompat.OnCommitContentListener() { @Override public boolean onCommitContent(InputContentInfoCompat inputContentInfo, int flags, Bundle opts) { Logg.dr("Opts: " + 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. if (keyBoardInputCallbackListener != null) { keyBoardInputCallbackListener.onCommitContent(inputContentInfo, flags, opts); } return true; // return true if succeeded } }; return InputConnectionCompat.createWrapper(ic, editorInfo, callback); } public interface KeyBoardInputCallbackListener { void onCommitContent(InputContentInfoCompat inputContentInfo, int flags, Bundle opts); } public void setKeyBoardInputCallbackListener(KeyBoardInputCallbackListener keyBoardInputCallbackListener) { this.keyBoardInputCallbackListener = keyBoardInputCallbackListener; } }
解决方案
Bundle opts为null是常见场景——多数输入法并不会通过opts传递内容,核心的GIF资源信息其实封装在InputContentInfoCompat对象里,你可以通过以下方式处理:
直接从
InputContentInfoCompat获取GIF的URI
替换原本依赖opts的逻辑,改用inputContentInfo.getContentUri()获取资源路径:@Override public void onCommitContent(InputContentInfoCompat inputContentInfo, int flags, Bundle opts) { Uri gifUri = inputContentInfo.getContentUri(); if (gifUri != null) { Log.d(TAG, "GIF URI: " + gifUri); // 通过ContentResolver读取GIF文件 try (InputStream inputStream = getContentResolver().openInputStream(gifUri)) { // 这里实现GIF的显示、上传等逻辑 } catch (IOException e) { e.printStackTrace(); } } }完善权限管理
原代码的权限请求逻辑没问题,但使用完URI后要主动释放权限,避免资源泄漏:if (BuildCompat.isAtLeastNMR1() && (flags & InputConnectionCompat.INPUT_CONTENT_GRANT_READ_URI_PERMISSION) != 0) { try { inputContentInfo.requestPermission(); // 处理完GIF后释放权限 inputContentInfo.releasePermission(); } catch (Exception e) { return false; } }扩展支持更多图片类型(可选)
如果需要支持PNG/JPG等格式,修改EditorInfoCompat.setContentMimeTypes的参数即可:EditorInfoCompat.setContentMimeTypes(editorInfo, new String[] {"image/gif", "image/png", "image/jpeg"});
内容的提问来源于stack exchange,提问作者lukasniessen
相关产品推荐
相关产品推荐

