リッチ コンテンツの挿入

図 1. Unified API は、特定の UI メカニズムに縛られず、長押しメニューからの貼り付けやドラッグ&ドロップなどで受信コンテンツを処理できる単一の場所を提供します。

ユーザーは画像、動画、およびその他の表現力豊かなコンテンツを好みますが、そうしたコンテンツをアプリに挿入することは必ずしも容易ではありません。アプリがリッチ コンテンツを簡単に受信できるように、クリップボード、キーボード、ドラッグ&ドロップなどの任意のソースからコンテンツを受け取れる新しい Unified API が導入されました。

新しいインターフェースである OnReceiveContentListener を UI コンポーネントに接続すると、任意のメカニズムを通じてコンテンツが挿入されたときにコールバックを取得できます。コールバックは、プレーン テキストや書式付きテキストからマークアップ、画像、動画、音声ファイルまで、さまざまなコンテンツの受信をコードで処理するための単一の場所になります。

以前の Android バージョンとの下位互換性を維持するため、AndroidX にも新しい API を追加しました(Core 1.5.0-beta1 および Appcompat 1.3.0-beta-01 で利用できます)。この機能を実装する際は、新しい API を使用することをおすすめします。

概要

既存の API では、長押しメニューやドラッグ&ドロップなどの UI メカニズムごとに、それに対応する固有の API があります。これは、コンテンツを挿入するメカニズムごとに類似のコードを追加して、各 API を個別に統合する必要があることを意味します。

図 2. 以前は、コンテンツを挿入するための UI メカニズムごとに、異なる API をアプリに実装する必要がありました。

Unified API は、実装する単一の API を作成してこれらのコードパスを統合します。したがって、デベロッパーはアプリ固有のロジックに集中し、それ以外の処理はプラットフォームに委ねることができます。

図 3. 新しい Unified API では、すべての UI メカニズムをサポートする単一の API を実装できます。

このアプローチでは、コンテンツを挿入する新しい方法をプラットフォームに追加する際に、アプリでサポートを有効にするためにコードを変更する必要がありません。特定のユースケース用のフル カスタマイズをアプリに実装する必要がある場合も、同様に動作する既存の API を引き続き使用できます。

実装

新しい API は、単一のメソッド OnReceiveContentListener のリスナー インターフェースです。古いバージョンの Android プラットフォームをサポートするには、AndroidX Core ライブラリの一致する OnReceiveContentListener インターフェースの使用をおすすめします。

API を使用するには、アプリが処理できるコンテンツのタイプを指定して、リスナーの実装を開始します。

public class MyReceiver implements OnReceiveContentListener {
     public static final String[] MIME_TYPES = new String[] {"image/*", "video/*"};
     // ...

アプリがサポートするすべてのコンテンツ MIME タイプを指定した後、リスナーの残りの部分を実装します。

 public class MyReceiver implements OnReceiveContentListener {
     public static final String[] MIME_TYPES = new String[] {"image/*", "video/*"};

     @Override
     public ContentInfoCompat onReceiveContent(View view, ContentInfoCompat contentInfo) {
         Pair<ContentInfoCompat, ContentInfoCompat> split = contentInfo.partition(
                 item -> item.getUri() != null);
         ContentInfo uriContent = split.first;
         ContentInfo remaining = split.second;
         if (uriContent != null) {
             ClipData clip = uriContent.getClip();
             for (int i = 0; i < clip.getItemCount(); i++) {
                 Uri uri = clip.getItemAt(i).getUri();
                 // App-specific logic to handle the URI ...
             }
         }
         // Return anything that your app didn't handle. This preserves the default platform
         // behavior for text and anything else that you aren't implementing custom handling for.
         return remaining;
     }
 }

アプリがすでにインテントとの共有をサポートしている場合は、コンテンツ URI を処理するアプリ固有のロジックを再利用できます。残りすべてのデータを結果から取得し、そのデータの処理をプラットフォームに委ねます。

リスナーを実装した後、アプリの UI 要素のコンストラクタ内でリスナーを設定します。

public class MyActivity extends Activity {
     @Override
     public void onCreate(Bundle savedInstanceState) {
         // ...

         AppCompatEditText myInput = findViewById(R.id.my_input);
         ViewCompat.setOnReceiveContentListener(myInput, MyReceiver.MIME_TYPES, new MyReceiver());
     }
}

Keyboard Image API との比較

Unified Content API は、既存の Keyboard Image API の次期バージョンと考えることができます。新しい API は、Keyboard Image API の機能に加えて、以下の追加機能をサポートします。デバイスと機能の互換性は、Jetpack ライブラリを使用するか、Android SDK のネイティブ API を使用するかによって異なります。

サポートされる機能と API レベル: Jetpack

アクションまたは機能 Keyboard Image API によるサポート Unified API によるサポート
キーボードからの挿入 あり(API レベル 13 以上) あり(API レベル 13 以上)
長押しメニューからの貼り付けによる挿入 なし あり
ドラッグ&ドロップによる挿入 なし あり(API レベル 24 以上)

サポートされる機能と API レベル: ネイティブ API

アクションまたは機能 Keyboard Image API によるサポート Unified API によるサポート
キーボードからの挿入 あり(API レベル 25 以上) あり(Android 12 以降)
長押しメニューからの貼り付けによる挿入 なし
ドラッグ&ドロップによる挿入 なし