ユーザーは多くの場合、絵文字やステッカーなど、さまざまな情報を使用してコミュニケーションを 説明します。以前のバージョンの Android では、ソフト キーボード(別名「ソフト キーボード」)が インプット メソッド エディタ IME - Unicode 絵文字のみをアプリに送信できます。リッチ コンテンツの場合、 他のアプリで使用できない、または次のような回避策を使用したアプリ固有の API シンプルな共有操作による画像の送信 アクセスできます。
Android 7.1(API レベル 25)以降、Android SDK には Content API は、IME が画像やその他のコンテンツを送信するためのユニバーサルな方法を提供します。 アプリのテキスト エディタに直接エクスポートできます。この API は サポート ライブラリをサポートしています。Support API の使用には、 実装を簡素化するヘルパー メソッドが含まれるためです。
この API を使用すると、あらゆるユーザーのリッチ コンテンツを受け入れるメッセージ アプリを構築できます。 あらゆるアプリにリッチ コンテンツを送信できるキーボードのほか、Google キーボード Google Chat でメッセージを Google Android 7.1 では、図 1 のとおり、Commit Content API をサポートしています。
このドキュメントでは、IME と 。
仕組み
キーボードの画像挿入には、IME とアプリからの参加が必要です。「 次の順序で、画像挿入プロセスの各ステップを説明します。
ユーザーが
EditTextをタップすると、 エディタは、受け入れ可能な MIME コンテンツ タイプのリストをEditorInfo.contentMimeTypes。IME は、サポートされているタイプのリストを読み取り、エディタが受け入れ可能なコンテンツをソフト キーボード内に表示します。
ユーザーが画像を選択すると、IME は
commitContent()送信され、InputContentInfo移動します。commitContent()の呼び出しは、commitText()の呼び出し。ただし、リッチ コンテンツ用です。InputContentInfoには、次の URI が含まれている。 は、コンテンツ内のコンテンツを識別します。 提供します。
このプロセスを図 2 に示します。
アプリに画像サポートを追加する
IME からのリッチ コンテンツを受け入れるには、アプリが IME にコンテンツ タイプを伝える必要があります。
は、コンテンツの受信時に実行されるコールバック メソッドを受け入れ、指定します。
次の例は、PNG を受け入れる EditText を作成する方法を示しています。
images:
Kotlin
var editText: EditText = object : EditText(this) { override fun onCreateInputConnection(outAttrs: EditorInfo): InputConnection { var ic = super.onCreateInputConnection(outAttrs) EditorInfoCompat.setContentMimeTypes(outAttrs, arrayOf("image/png")) val mimeTypes = ViewCompat.getOnReceiveContentMimeTypes(this) if (mimeTypes != null) { EditorInfoCompat.setContentMimeTypes(outAttrs, mimeTypes) ic = InputConnectionCompat.createWrapper(this, ic, outAttrs) } return ic } }
Java
EditText editText = new EditText(this) { @Override public InputConnection onCreateInputConnection(EditorInfo outAttrs) { InputConnection ic = super.onCreateInputConnection(outAttrs); EditorInfoCompat.setContentMimeTypes(outAttrs, new String[]{"image/png"}); String[] mimeTypes = ViewCompat.getOnReceiveContentMimeTypes(this); if (mimeTypes != null) { EditorInfoCompat.setContentMimeTypes(outAttrs, mimeTypes); ic = InputConnectionCompat.createWrapper(this, ic, outAttrs); } return ic; } };
以下で詳しく説明します。
この例ではサポート ライブラリを使用しているため、
android.support.v13.view.inputmethod、android.view.inputmethod。この例では、
EditTextを作成してそれをオーバーライドします。onCreateInputConnection(EditorInfo)メソッドをInputConnection。InputConnectionは、IME とデバイスの間の通信チャネルです。 応答します。コール
super.onCreateInputConnection()組み込みの動作(テキストの送受信)が維持され、InputConnectionへの参照を提供します。setContentMimeTypes()は、サポートされている MIME タイプのリストをEditorInfo。発信setContentMimeTypes()までにsuper.onCreateInputConnection()。IME がコンテンツをコミットするたびに、
callbackが実行されます。メソッドonCommitContent()参照先がInputContentInfoCompat, コンテンツ URI が含まれています。- API レベル 25 でアプリを実行している場合は、権限をリクエストして解放する
以上、かつ
INPUT_CONTENT_GRANT_READ_URI_PERMISSIONフラグが IME によって設定されていること。それ以外の場合は、すでにコンテンツへのアクセス権があります URI は、IME によって付与されているか、コンテンツ プロバイダによって付与されているため、 アクセスは制限されません詳細については、イメージ サポートの追加先 IME。
- API レベル 25 でアプリを実行している場合は、権限をリクエストして解放する
以上、かつ
createWrapper()InputConnection、変更されたEditorInfo、コールバックをラップ 新しいInputConnectionに変換して返します。
おすすめの方法は次のとおりです。
リッチ コンテンツに対応していないエディタでは、
setContentMimeTypes()。EditorInfo.contentMimeTypesの設定はそのままにします。nullに送信。InputContentInfoで指定された MIME タイプの場合、エディタはコンテンツを無視します。 使用できるタイプのいずれにも一致しません。リッチ コンテンツはテキストの位置に影響せず、テキストの位置の影響も受けない カーソルを合わせます。コンテンツを操作する際、エディタはカーソルの位置を無視できます。
エディタの
OnCommitContentListener.onCommitContent()メソッドを使用すると、非同期でtrueを返すことができます。 コンテンツを読み込みます。コミットする前に IME で編集できるテキストとは異なり、リッチ 即座に commit されます。ユーザーにファイルの編集や削除を許可するには、 自分でロジックを実装する必要があります。
アプリをテストするには、デバイスまたはエミュレータに、送信可能なキーボードが備わっていることを確認してください。 リッチ コンテンツを利用できます。Android 7.1 以降の場合は、Google キーボードを使用できます。
IME に画像サポートを追加する
リッチ コンテンツをアプリに送信する IME はコミット コンテンツを実装する必要がある 必要があります。
- オーバーライド
onStartInput()またはonStartInputView()を実行して、サポートされているコンテンツ タイプのリストをターゲットから読み取る クリックします。ターゲット エディタが GIF 画像を受け入れるかどうかをチェックするコード スニペットを以下に示します。
Kotlin
override fun onStartInputView(editorInfo: EditorInfo, restarting: Boolean) { val mimeTypes: Array<String> = EditorInfoCompat.getContentMimeTypes(editorInfo) val gifSupported: Boolean = mimeTypes.any { ClipDescription.compareMimeTypes(it, "image/gif") } if (gifSupported) { // The target editor supports GIFs. Enable the corresponding content. } else { // The target editor doesn't support GIFs. Disable the corresponding // content. } }
Java
@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 the corresponding content. } else { // The target editor doesn't support GIFs. Disable the corresponding // content. } }
- ユーザーが画像を選択したときに、アプリにコンテンツを commit します。電話をかけない
commitContent(): 作成中のテキストがある場合 エディタがフォーカスを 失う可能性があります次のコード スニペットは、 GIF 画像を確定できます。
Kotlin
// 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. fun commitGifImage(contentUri: Uri, imageDescription: String) { val inputContentInfo = InputContentInfoCompat( contentUri, ClipDescription(imageDescription, arrayOf("image/gif")), null ) val inputConnection = currentInputConnection val editorInfo = currentInputEditorInfo var flags = 0 if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N_MR1) { flags = flags or InputConnectionCompat.INPUT_CONTENT_GRANT_READ_URI_PERMISSION } InputConnectionCompat.commitContent(inputConnection, editorInfo, inputContentInfo, flags, null) }
Java
// 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"}), null ); InputConnection inputConnection = getCurrentInputConnection(); EditorInfo editorInfo = getCurrentInputEditorInfo(); Int flags = 0; if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N_MR1) { flags |= InputConnectionCompat.INPUT_CONTENT_GRANT_READ_URI_PERMISSION; } InputConnectionCompat.commitContent( inputConnection, editorInfo, inputContentInfo, flags, null); }
IME 作成者は、ほとんどの場合、独自のコンテンツ プロバイダを実装して
コンテンツ URI リクエストに応答できます。例外は、IME がコンテンツをサポートしている場合です。
コンテンツプロバイダ
MediaStore。詳細については、
コンテンツ プロバイダについて詳しくは、
provider と file を指定
プロバイダに関するドキュメントをご覧ください。
独自のコンテンツ プロバイダを作成している場合は、エクスポートしないことをおすすめします。
「新規顧客の獲得」目標を
android:exported~
false。代わりに、プロバイダで権限の付与を有効にするには、
android:grantUriPermission
宛先: true。IME は、コンテンツがコミットされると、コンテンツ URI にアクセスするパーミッションを付与できるようになります。変換には次の 2 つの方法があります。
Android 7.1(API レベル 25)以降では、
commitContent()を呼び出すときに以下を行います。 フラグ パラメータをINPUT_CONTENT_GRANT_READ_URI_PERMISSION。 その後、アプリが受け取るInputContentInfoオブジェクトは、 一時的な読み取り権限を解放するには、requestPermission()およびreleasePermission()。Android 7.0(API レベル 24)以前では、
INPUT_CONTENT_GRANT_READ_URI_PERMISSIONは無視されるため、手動で付与してください 許可する必要があります。これを行う方法の一つはgrantUriPermission()ですが、独自のメカニズムを実装して、 独自の要件を満たすことができます。
IME をテストするには、デバイスまたはエミュレータに搭載されているアプリが リッチ コンテンツを利用できます。Google Messenger アプリは Android 7.1 以降で利用できます。