web-dev-qa-db-ja.com

Gboard:EditTextでのGIF挿入を有効にする

アプリでGboard Googleを使用していて、キーボードアプリから[〜#〜] gif [〜#〜]を入力すると、EditTextトーストが表示されます

"テキストフィールドはキーボードからのGIF挿入をサポートしていません"

私はこれについて何千回も検索しましたが、結果を見つけることができません

任意の助けいただければ幸いです。

12
GGWP

画像キーボードのサポート

ユーザーは、絵文字、ステッカー、およびその他の種類の豊富な
コンテンツ。以前のバージョンのAndroidでは、ソフトキーボード(入力とも呼ばれます) 
メソッドエディターまたはIME)は、ユニコードの絵文字のみをアプリに送信できます。金持ちのため 
コンテンツでは、アプリは、アプリで使用できないアプリ固有のAPIを構築する必要がありました 
他のアプリ、またはEasy Share Actionまたは 
クリップボード。

使い方

キーボード画像の挿入には、IMEとアプリの両方からの参加が必要です。次のシーケンスは、イメージ挿入プロセスの各ステップを示しています。

ユーザーがEditTextをタップすると、エディターはEditorInfo.contentMimeTypesで受け入れるMIMEコンテンツタイプのリストを送信します。

IMEはサポートされているタイプのリストを読み取り、エディターが受け入れることができるコンテンツをソフトキーボードに表示します。

ユーザーが画像を選択すると、IMEはcommitContent()を呼び出し、InputContentInfoをエディターに送信します。 commitContent()呼び出しはcommitText()呼び出しに似ていますが、リッチコンテンツが対象です。 InputContentInfoには、コンテンツプロバイダーのコンテンツを識別するURIが含まれています。その後、アプリは許可をリクエストし、URIからコンテンツを読み取ることができます。

IMEからのリッチコンテンツを受け入れるために、アプリはIMEにそれをタイプするコンテンツを通知する必要があります 
コンテンツが存在するときに実行されるcallbackupメソッドを受け入れて指定します 
受け取った。次の例は、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);
    }
};
_

ここに完全なドキュメントリファレンスがあります

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
    }
}
_

ユーザーが画像を選択したときにコンテンツをアプリにコミットします。エディターがフォーカスを失う可能性があるため、作成中のテキストがある場合は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);
}
_

ここに完全なドキュメントがあります

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

14
Mallikarjuna

私はどこかから以下の解決策を見つけました。それが確実に皆を助けることを願っています。

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;
    }
}

この機能が組み込まれたEditTextが必要な場合は、私のライブラリRichContentEditTextを確認してください: https://github.com/GregoryConrad/RichContentEditText

リッチコンテンツ(画像やその他のファイル)をIMEからアプリに簡単に転送できます。ここにいくつかのサンプルコードがあります:

XML

<?xml version="1.0" encoding="utf-8"?>
<!-- Root layout can be anything. Just make sure to include xmlns:app line. -->
<Android.support.constraint.ConstraintLayout xmlns:Android="http://schemas.Android.com/apk/res/Android"
    xmlns:app="http://schemas.Android.com/apk/res-auto"
    xmlns:tools="http://schemas.Android.com/tools"
    Android:layout_width="match_parent"
    Android:layout_height="match_parent"
    tools:context=".MainActivity">

    <!-- The RichContentEditText -->
    <!-- Notice app:allowedMimeTypes="images"; it is what accepts certain mime types
             (you can do this programmatically too) -->
    <com.gsconrad.richcontentedittext.RichContentEditText
        Android:id="@+id/rich_content_edit_text"
        Android:layout_width="match_parent"
        Android:layout_height="wrap_content"
        Android:hint="@string/rich_content_edit_text_hint"
        Android:inputType="text"
        app:allowedMimeTypes="images" />
</Android.support.constraint.ConstraintLayout>

Java

// MainActivity.Java
private void setupRichContentEditText() {
    RichContentEditText editText = findViewById(R.id.rich_content_edit_text);
    // The following line sets the listener that is called when rich content is received
    editText.setOnRichContentListener(new RichContentEditText.OnRichContentListener() {
        // Called when a keyboard sends rich content
        @Override
        public void onRichContent(Uri contentUri, ClipDescription description) {
            if (description.getMimeTypeCount() > 0) {
                final String fileExtension = MimeTypeMap.getSingleton()
                        .getExtensionFromMimeType(description.getMimeType(0));
                final String filename = "filenameGoesHere." + fileExtension;
                File richContentFile = new File(getFilesDir(), filename);
                // See the library example app for an implementation of writeToFileFromContentUri
                if (!writeToFileFromContentUri(richContentFile, contentUri)) {
                    // We are in the background right now, make sure to run this in the foreground
                    Toast.makeText(MainActivity.this,
                            R.string.rich_content_copy_failure, Toast.LENGTH_LONG).show();
                } else {
                    // We are in the background right now, make sure to run this in the foreground
                    WebView displayView = findViewById(R.id.display_view);
                    displayView.loadUrl("file://" + richContentFile.getAbsolutePath());
                }
            }
        }
    });
}
1
Gregory Conrad