Gboard:在EditText上启用GIF插入

GGW*_*GWP 12 android android-edittext gboard

我在我的应用程序中使用谷歌的Gboard,当我从键盘应用程序输入GIF到我的EditText它然后显示一个吐司

"文本字段不支持从键盘插入GIF"

我已经搜索了这一千次而无法找到结果

任何帮助,将不胜感激.

Mal*_*una 15

图像键盘支持

Users often want to communicate with emojis, stickers, and other kinds of rich
content. In previous versions of Android, soft keyboards (also known as input
method editors or IMEs) could send only unicode emoji to apps. For rich
content, apps had to either build app-specific APIs that couldn't be used in
other apps or use workaround like sending images through Easy Share Action or the
clipboard.

这个怎么运作

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

当用户点击EditText时,编辑器会发送它在EditorInfo.contentMimeTypes中接受的MIME内容类型列表.

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

当用户选择图像时,IME调用commitContent()并将InputContentInfo发送到编辑器.commitContent()调用类似于commitText()调用,但是对于丰富的内容.InputContentInfo包含标识内容提供者中的内容的URI.然后,您的应用可以请求权限并从URI中读取内容.

To accept rich content from IMEs, apps must tell IMEs what content types it 
accepts and specify a callbackup method that is executed when content is
received. The following example demonstrates how to create an EditText that
accept PNG images:
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);
    }
};
Run Code Online (Sandbox Code Playgroud)

这是完整文档参考

https://developer.android.com/guide/topics/text/image-keyboard.html#how_it_works

为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
    }
}
Run Code Online (Sandbox Code Playgroud)

当用户选择图像时,向应用程序提交内容.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);
}
Run Code Online (Sandbox Code Playgroud)

这是完整文档

https://developer.android.com/guide/topics/text/image-keyboard.html#adding_image_support_to_imes


kar*_*.io 6

我从某处找到下面的解决方案。希望它能对大家有所帮助。

import android.content.Context;
import android.os.Bundle;
import android.support.v13.view.inputmethod.EditorInfoCompat;
import android.support.v13.view.inputmethod.InputConnectionCompat;
import android.support.v13.view.inputmethod.InputContentInfoCompat;
import android.support.v4.os.BuildCompat;
import android.util.AttributeSet;
import android.view.inputmethod.EditorInfo;
import android.view.inputmethod.InputConnection;


public class MyEditText extends android.support.v7.widget.AppCompatEditText {

    private String[] imgTypeString;
    private KeyBoardInputCallbackListener keyBoardInputCallbackListener;

    public MyEditText(Context context) {
        super(context);
        initView();
    }

    public MyEditText(Context context, AttributeSet attrs) {
        super(context, attrs);
        initView();
    }

    private void initView() {
        imgTypeString = new String[]{"image/png",
                "image/gif",
                "image/jpeg",
                "image/webp"};
    }

    @Override
    public InputConnection onCreateInputConnection(EditorInfo outAttrs) {
        final InputConnection ic = super.onCreateInputConnection(outAttrs);
        EditorInfoCompat.setContentMimeTypes(outAttrs,
                imgTypeString);
        return InputConnectionCompat.createWrapper(ic, outAttrs, callback);
    }


    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
                        }
                    }
                    boolean supported = false;
                    for (final String mimeType : imgTypeString) {
                        if (inputContentInfo.getDescription().hasMimeType(mimeType)) {
                            supported = true;
                            break;
                        }
                    }
                    if (!supported) {
                        return false;
                    }

                    if (keyBoardInputCallbackListener != null) {
                        keyBoardInputCallbackListener.onCommitContent(inputContentInfo, flags, opts);
                    }
                    return true;  // return true if succeeded
                }
            };

    public interface KeyBoardInputCallbackListener {
        void onCommitContent(InputContentInfoCompat inputContentInfo,
                             int flags, Bundle opts);
    }

    public void setKeyBoardInputCallbackListener(KeyBoardInputCallbackListener keyBoardInputCallbackListener) {
        this.keyBoardInputCallbackListener = keyBoardInputCallbackListener;
    }

    public String[] getImgTypeString() {
        return imgTypeString;
    }

    public void setImgTypeString(String[] imgTypeString) {
        this.imgTypeString = imgTypeString;
    }
}
Run Code Online (Sandbox Code Playgroud)