共有の改善

Android Q では、共有に関してさまざまな新機能が追加されています。

Sharing Shortcuts API

Android Q では、ShareSheet が変更されています。また、DirectShare API は、新しい Sharing Shortcuts API に置き換えられました。既存のダイレクト シェア メカニズムは引き続き機能しますが、新しい API を使用する他のアプリよりも優先順位が低くなります。

Sharing Shortcuts API を使用すると、受動的にオンデマンドで結果を取得するのではなく、事前にダイレクト シェア ターゲットを公開できます。これは ShortcutManager の機能です。2 つの API は似ているため、ShortcutInfo API を拡張して両方の機能を使いやすくしました。新しい API を使用すると、カテゴリやユーザーを共有ターゲットに直接割り当てることができます。共有ターゲットは、同じアプリによって更新されるか、そのアプリがアンインストールされるまで、システム内に残ります。

サンプルコード: SharingShortcuts

ダイレクト シェア ターゲットを公開する

現在のところ、ダイレクト シェア ターゲットの公開でサポートされているのは、動的ショートカットに限られます。新しい API を使用してダイレクト シェア ターゲットを公開する手順は次のとおりです。

  1. アプリの XML リソース ファイルで、<share-target> 要素を宣言します。詳細については、下記の共有ターゲットを宣言するをご覧ください。
  2. 宣言した共有ターゲットに、適合カテゴリとともに動的ショートカットを公開します。AndroidX の ShortcutManager または ShortcutManagerCompat を使用して、ショートカットの追加、アクセス、更新、削除を行うことができます。Android の古いバージョンとの下位互換性を維持するために、AndroidX の互換性ライブラリを使用することをおすすめします。

DirectShare API

共有ターゲットに関する追加情報を提供する新しいメソッドや強化されたメソッドが ShortcutInfo.Builder に追加されています。

setCategories()
これは新しいメソッドではありませんが、カテゴリは、共有インテントや共有アクションを処理可能なショートカットのフィルタリングにも使用されるようになりました。詳細については、下記の共有ターゲットを宣言するをご覧ください。共有ターゲットとして使用することを目的としたショートカットの場合、このフィールドは必須です。
setLongLived()
ショートカットが非公開になった場合や、アプリによって動的ショートカットや固定ショートカットとして表示されなくなった場合に、ショートカットを有効のままにするかどうかを指定します。ショートカットの有効性が継続する場合、動的ショートカットとしては非公開になった後も、さまざまなシステム サービスによってキャッシュされる可能性があります。
setPerson()setPersons()

1 つ以上の Person オブジェクトをショートカットに関連付けます。これにより、さまざまなアプリを横断してユーザー行動を把握できます。また、フレームワーク内の予測サービスが ShareSheet 内で優れた候補を提示できるようになります。ショートカットに Person 情報を追加するのは必須ではありませんが、共有ターゲットをユーザーに関連付けることができる場合は強くおすすめします。クラウドなどの一部の共有ターゲットは、ユーザーに関連付けることができません。

一意の ID が付与された特定の Person オブジェクトを共有ターゲットと関連する通知に含めることで、候補の順序を改善することができます。その際、setKey() を使用します。

一般的なメッセージ アプリの場合、連絡先ごとに個別の共有ターゲット(ショートカット)を公開し、[Person] フィールドに連絡先の情報を含める必要があります。グループ チャットのように 1 つのターゲットを複数のユーザーに関連付けることができる場合は、単一の共有ターゲットに複数のユーザーを追加します。

共有ターゲットを宣言する

共有ターゲットは、静的ショートカットの定義と同様に、アプリのリソース ファイル内で宣言する必要があります。リソース ファイルの <shortcuts> ルート要素内に、他の静的ショートカット定義と一緒に、共有ターゲット定義を追加してください。各 <share-target> 要素には、共有データタイプや、適合カテゴリ、共有インテントを処理するターゲット クラスに関する情報が格納されます。XML コードは次のようになります。

<shortcuts xmlns:android="http://schemas.android.com/apk/res/android">
      <share-target android:targetClass="com.example.android.sharingshortcuts.SendMessageActivity">
        <data android:mimeType="text/plain" />
        <category android:name="com.example.android.sharingshortcuts.category.TEXT_SHARE_TARGET" />
      </share-target>
    </shortcuts>
    

共有ターゲットのデータ要素は、インテント フィルタのデータ指定と似ています。各共有ターゲットは複数のカテゴリを持つことができます。カテゴリは、アプリの公開済みショートカットと共有ターゲット定義をマッチングさせるためにのみ使用されます。カテゴリは、任意のアプリ定義の値を持つことができます。

ShareSheet 内で上記の <share-target> 例と合致するダイレクト シェア ターゲット(ショートカット)をユーザーが選択した場合、アプリは次の共有インテントを取得します。

Action: Intent.ACTION_SEND
    ComponentName: {com.example.android.sharingshortcuts /
                    com.example.android.sharingshortcuts.SendMessageActivity}
    Data: Uri to the shared content
    EXTRA_SHORTCUT_ID: <ID of the selected shortcut>
    

ユーザーがランチャーのショートカットから共有ターゲットを開くと、アプリは共有ショートカットを ShortcutManagerCompat に追加したときに作成されたインテントを取得します。別のインテントであるため Intent.EXTRA_SHORTCUT_ID は利用できず、必要な場合は手動で ID を渡す必要があります。

カスタム ターゲットを宣言する

ChooserTargetServices から読み込んだショートカット共有と ChooserTarget の前に表示する、限られた数の ChooserTarget オブジェクトを指定できます。また、アプリの候補の前に一覧表示されるアクティビティを指す、限られた数のインテントも指定できます。

Intent.createChooser() を呼び出す前に、EXTRA_CHOOSER_TARGETSEXTRA_INITIAL_INTENTS を共有インテントに追加します。

アプリを認識する

ユーザーが共有しているアプリは、マニフェストで定義されているアイコンラベルによって示されます。共有ターゲットとその機能をユーザーが把握できるように、アプリを明確に示す必要があります。アクティビティやインテント フィルタのラベルを設定すると、詳細なコンテキストを提供できます。

共有ターゲットが適切に定義されている場合、アクティビティやインテント フィルタのラベルを設定する必要はありません。受け取るアプリ名だけで、ユーザーは共有後に何が起きるかを理解できます。

AndroidX 内の DirectShare

ShortcutManagerCompat は、古い DirectShare API との下位互換性を提供する新しい AndroidX API です。共有ターゲットを公開する方法としておすすめします。

互換性ライブラリを使用できるようにするには、アプリのマニフェスト内に meta-data の chooser-target-service と intent-filter のセットが含まれている必要があります。現在の DirectShare API についてご確認ください。

このサービスは、すでに互換性ライブラリ内で宣言されているため、アプリのマニフェスト内でユーザーがサービスを宣言する必要はありません。ただし、共有アクティビティからサービスへのリンクを、チューザ ターゲット プロバイダに含める必要があります。

次の例の場合、ChooserTargetService の実装は androidx.core.content.pm.ChooserTargetServiceCompat です。これは AndroidX ですでに定義されています。

<activity
        android:name=".SendMessageActivity"
        android:label="@string/app_name"
        android:theme="@style/SharingShortcutsDialogTheme">
        <!-- This activity can respond to Intents of type SEND -->
        <intent-filter>
            <action android:name="android.intent.action.SEND" />
            <category android:name="android.intent.category.DEFAULT" />
            <data android:mimeType="text/plain" />
        </intent-filter>
        <!-- Only needed if you import the sharetarget AndroidX library that
             provides backwards compatibility with the old DirectShare API.
             The activity that receives the Sharing Shortcut intent needs to be
             taken into account with this chooser target provider. -->
        <meta-data
            android:name="android.service.chooser.chooser_target_service"
            android:value="androidx.sharetarget.ChooserTargetServiceCompat" />
    </activity>
    

コンテンツのプレビュー

アプリがコンテンツを共有すると、Sharesheet UI にそのコンテンツのプレビューをオプションとして表示できます。

プレビューにはタイトルか画像、またはその両方を含めることができます。

Intent sendIntent = new Intent(Intent.ACTION_SEND);
    sendIntent.putExtra(Intent.EXTRA_TEXT, "Hello!");

    // (Optional) Here we're setting the title of the content
    sendIntent.putExtra(Intent.EXTRA_TITLE, "Send message");

    // (Optional) Here we're passing a content URI to an image to be displayed
    sendIntent.setClipData(contentUri);
    sendIntent.setFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);

    // Start the chooser to show the Sharesheet
    startActivity(Intent.createChooser(sendIntent, null));
    

画像コンテンツの URI は FileProvider から提供されます(通常は <cache-path> に設定されています)。ファイルの共有をご覧ください。

コード全体の例はサンプルアプリでご確認ください。

よくある質問

新しい API と古い DirectShare API の主な違いは何ですか?

古い DirectShare API ではプルモデルが使用されていたのに対して、新しい API ではプッシュモデルが使用されています。これにより、ShareSheet の準備時にダイレクト シェア ターゲットを取得するプロセスが大幅に高速化されます。アプリ デベロッパーの観点からすると、新しい API を使用する場合、アプリは、ダイレクト シェア ターゲットのリストを事前に提供し、アプリの内部状態が変化するたびにショートカットのリストを更新する必要があります(たとえば、新しい連絡先がメッセージ アプリに追加された場合など)。

新しい API に移行しないとどうなりますか?

Android Q 以降では、ShareSheet は、ShortcutManager(新しい API)経由で提供される共有ターゲットを優先するようになります。そのため、公開した共有ターゲットが、他のアプリの共有ターゲットに埋もれてしまい、共有時に表示されなくなるおそれがあります。

後方互換性を維持するため、アプリ内で新旧両方の DirectShare API を使用することはできますか?

絶対にしないでください。代わりに、用意されているサポート ライブラリ API(ShortcutManagerCompat)を使用してください。2 つの API セットを混在させると、共有ターゲットを取得する際に、望ましくない動作や予期しない動作が発生するおそれがあります。

共有ターゲット用の公開ショートカットは、ランチャー ショートカット(ランチャー内でアプリアイコンを長押ししたときのショートカットの一般的な使い方)とどのように異なるのですか?

「共有ターゲット」の目的で公開されているショートカットは、すべてランチャーのショートカットでもあり、アプリアイコンを長押しするとメニュー内に表示されます。アクティビティごとの最大ショートカット数の制限は、アプリが公開しているショートカットの総数(共有ターゲットと旧式のランチャー ショートカットの合計)にも適用されます。