ユーザーは多くの場合、絵文字やステッカーなど、さまざまな情報を使用してコミュニケーションを 説明します。以前のバージョンの 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 以降で利用できます。