You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.17 08:30:47