直接共有ターゲットを提供する

図 1: Sharesheet のダイレクト シェア行(1で示されています)

ダイレクト シェア ターゲットを使用すると、他のアプリのユーザーが URL、画像、その他の種類のデータをアプリと簡単かつ迅速に共有できるようになります。ダイレクト シェアは、メッセージング アプリやソーシャル アプリの連絡先を Android Sharesheet に直接表示することで機能します。ユーザーはアプリを選択してから連絡先を検索する必要はありません。

ShortcutManagerCompat は、共有ショートカットを提供する AndroidX API であり、非推奨の ChooserTargetService API との下位互換性があります。共有ショートカットと ChooserTargets の両方を公開する方法としておすすめします。手順については、 このページの AndroidX を使用して共有ショートカットと ChooserTarget の両方を提供する をご覧ください。

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

Sharesheet のダイレクト シェア行には、Sharing Shortcuts API によって提供される動的ショートカットのみが表示されます。ダイレクト シェア ターゲットを公開する手順は次のとおりです。

  1. アプリの XML リソース ファイルで、share-target 要素を宣言します。

    <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>
    
  2. アプリの初期化時に、setDynamicShortcuts を使用して、動的ショートカットを重要度順に並べます。

    インデックスが小さいほど重要度が高くなります。コミュニケーション アプリを作成する場合は、アプリに表示される順に、最新の会話を上位に表示できます。古いショートカットは公開しないでください。過去 30 日間ユーザー アクティビティがない会話は古いと見なされます。

    Kotlin

    ShortcutManagerCompat.setDynamicShortcuts(myContext, listOf(shortcut1, shortcut2, ..))

    Java

    List<ShortcutInfoCompat> shortcuts = new ArrayList<>();
    shortcuts.add(shortcut1);
    shortcuts.add(shortcut2);
    ...
    ShortcutManagerCompat.setDynamicShortcuts(myContext, shortcuts);
  3. コミュニケーション アプリを開発している場合は、ユーザーが連絡先にメッセージを受信または送信するたびに、ショートカットの使用状況を pushDynamicShortcut使用してすぐに報告します。詳細については、このページのコミュニケーション アプリ のショートカットの使用状況を報告するをご覧ください。たとえば、ユーザーが送信したメッセージの使用状況を報告するには、 ショートカットに機能バインディングを ShortcutInfoCompat.Builder#addCapabilityBinding 指定して、actions.intent.SEND_MESSAGE 機能を使用します。

    Kotlin

    val shortcutInfo = ShortcutInfoCompat.Builder(myContext, staticConversationIdentifier)
      ...
      .setShortLabel(firstName)
      .setLongLabel(fullName)
      .setCategories(matchedCategories)
      .setLongLived(true)
    .addCapabilityBinding("actions.intent.SEND_MESSAGE").build()
    ShortcutManagerCompat.pushDynamicShortcut(myContext, shortcutInfo)

    Java

    ShortcutInfoCompat shortcutInfo = new ShortcutInfoCompat.Builder(myContext, staticConversationIdentifier)
      ...
      .setShortLabel(firstName)
      .setLongLabel(fullName)
      .setCategories(matchedCategories)
      .setLongLived(true)
      .addCapabilityBinding("actions.intent.SEND_MESSAGE")
      .build();
    
    ShortcutManagerCompat.pushDynamicShortcut(myContext, shortcutInfo);
  4. ユーザーが連絡先を削除した場合は、 removeLongLivedShortcut を使用します。これは、システム サービスによってキャッシュされているかどうかに関係なく、ショートカットを削除する方法としておすすめです。次のコード スニペットは、その方法の例を示しています。

    Kotlin

    val deleteShortcutId = "..."
    ShortcutManagerCompat.removeLongLivedShortcuts(myContext, listOf(deleteShortcutId))

    Java

    String deleteShortcutId = "...";
    ShortcutManagerCompat.removeLongLivedShortcuts(
        myContext, Arrays.asList(deleteShortcutId));

ダイレクト シェア ターゲットのランキングを改善する

Android Sharesheet には、一定数のダイレクト シェア ターゲットが表示されます。これらの候補はランク順に並べ替えられます。次の操作を行うことで、ショートカットのランキングを改善できる可能性があります。

  • すべての shortcutIds が一意であり、異なるターゲットに再利用されないようにします。
  • setLongLived(true) を呼び出して、ショートカットが長期にわたって維持されるようにします。
  • 会話関連のショートカットの場合は、送信メッセージと受信メッセージのショートカットの使用状況 を、対応するショートカット を ShortcutManagerCompat.pushDynamicShortcut を介して再公開することで報告します。 詳細については、このページのコミュニケーション アプリのショートカットの使用状況を報告するをご覧ください。
  • 関連性のないダイレクト シェア ターゲットや古いダイレクト シェア ターゲット(たとえば、過去 30 日間にユーザーがメッセージを送信していない連絡先)は提供しないようにします。
  • SMS アプリの場合は、ショートコードや、スパムの可能性があると判断された会話のショートカットは提供しないようにします。ユーザーがそのような会話に共有する可能性は非常に低いです。
  • setCategories() を呼び出して、ショートカットを適切な mimeType 属性に関連付けます。たとえば、SMS アプリの場合、連絡先が RCS または MMS に対応していない場合は、対応するショートカットを image/*video/* などのテキスト以外の MIME タイプに関連付けないでください。
  • 特定の会話で、動的ショートカットがプッシュされ、使用状況が報告されたら、ショートカット ID を変更しないでください。これにより、ランキングに使用状況データが保持されます。

ユーザーがダイレクト シェア ターゲットをタップした場合、アプリは、ターゲットのサブジェクトに対してアクションを直接実行できる UI にユーザーを誘導する必要があります。確認ダイアログを表示したり、タップされたターゲットとは関係のない UI にユーザーを誘導したりしないでください。たとえば、メッセージ アプリの場合、ダイレクト シェア ターゲットをタップすると、選択したユーザーとのスレッド表示をユーザーに表示します。キーボードが表示され、メッセージには共有データが事前入力されます。

Sharing Shortcuts API

Android 10(API レベル 29)以降、 ShortcutInfo.Builder には、共有ターゲットに関する追加情報を提供するメソッドと機能強化が追加されました。

setCategories()
Android 10 以降、共有インテントや共有アクションを処理可能なショートカットをフィルタリングする際にも、カテゴリが使用されるようになりました。詳細については、共有ターゲットを宣言するをご覧ください。このフィールドは、共有ターゲットとして使用されるショートカットに必須です。
setLongLived()

ショートカットがアプリによって非公開にされたり、非表示にされたりした場合(動的ショートカットまたは固定ショートカットとして)、そのショートカットが有効かどうかを指定します。ショートカットの有効性が継続する場合、動的ショートカットとしては非公開になった後も、さまざまなシステム サービスによってキャッシュされる可能性があります。

ショートカットを長期にわたって維持すると、ランキングが向上します。詳細については、最適な ランキングを取得するをご覧ください。

setShortLabel()setLongLabel()

個々のユーザーにショートカットを公開する場合は、setLongLabel() にフルネームを、setShortLabel() にニックネームやファーストネームなどの略称を含めてください。

GitHub で共有ショートカットを公開する例をご覧ください

ショートカット画像を提供する

共有ショートカットを作成するには、setIcon() を使用して画像を追加する必要があります。

共有ショートカットは、システム サーフェス全体で表示される可能性があり、形状が変更されることもあります。 また、Android バージョン 7、8、9(API レベル 25、26、27、28)を実行している一部のデバイスでは、背景のないビットマップのみのアイコンが表示されることがあり、コントラストが大幅に低下します。意図どおりにショートカットを表示するには、 アダプティブ ビットマップをIconCompat.createWithAdaptiveBitmap()を使用して提供します。

アダプティブ ビットマップは、アダプティブ アイコン向けに規定されているガイドラインおよびサイズと同じルールを遵守する必要があります。 遵守するために最も一般的に行われているのは、目的の正方形ビットマップを 72×72 dp にスケーリングして、108×108 dp の透明なキャンバス内の中央に配置する方法です。アイコンに透明な領域が含まれている場合は、背景色を含める必要があります。そうしないと、透明な領域が黒く表示されます。

特定の形状にマスキングした画像を提供しないようにしてください。たとえば、Android 10(API レベル 29)より前の時代では、円形にマスキングしたダイレクト シェア ChooserTarget のユーザー アバターを提供するのが一般的でした。現在の Android 10 の Android Sharesheet や各種システム サーフェスでは、デザインに応じてショートカット画像の形状が自動的に変更されて配列されます。 そのため、共有ショートカットを提供する場合は、 ShortcutManagerCompatを通じて、後方互換ダイレクト シェア ChooserTarget オブジェクトの形状を自動的に円形に変更する方法をおすすめします。

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

共有ターゲットは、静的ショートカットの定義と同様に、アプリのリソース ファイル内で宣言する必要があります。リソース ファイルの <shortcuts> ルート要素内に、他の静的ショートカット定義と一緒に、共有 ターゲット定義を追加してください。各 <share-targets> 要素 には、共有データタイプや、マッチング用カテゴリ、 共有インテントを処理するターゲット クラスに関する情報が格納されます。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>

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

Android 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 を手動で渡す必要があります。

コミュニケーション アプリのショートカットの使用状況を報告する

コミュニケーション アプリを開発している場合は、送信メッセージと受信メッセージの両方の使用状況を報告することで、Android Sharesheet でのランキングを改善できます。 そのためには、 ShortcutManagerCompat.pushDynamicShortcut を介して、連絡先を表す会話ショートカットを再公開します。

ショートカットの使用状況と機能バインディングは、Android 5.0(API 21)と下位互換性があります。

送信メッセージのショートカットの使用状況を報告する

ユーザーが送信したメッセージの使用状況を報告することは、メッセージを作成した後に [送信] ボタンをクリックすることと機能的に似ています。

使用状況の報告をトリガーするには、ショートカット に機能バインディングを指定しますShortcutInfoCompat.Builder#addCapabilityBindingactions.intent.SEND_MESSAGE 機能を使用します。

Kotlin

val shortcutInfo = ShortcutInfoCompat.Builder(myContext, staticConversationIdentifier)
  ...
  .setShortLabel(firstName)
  .setLongLabel(fullName)
  .setCategories(matchedCategories)
  .setLongLived(true)
.addCapabilityBinding("actions.intent.SEND_MESSAGE").build()
ShortcutManagerCompat.pushDynamicShortcut(myContext, shortcutInfo)

Java

ShortcutInfoCompat shortcutInfo = new ShortcutInfoCompat.Builder(myContext, staticConversationIdentifier)
  ...
  .setShortLabel(firstName)
  .setLongLabel(fullName)
  .setCategories(matchedCategories)
  .setLongLived(true)
  .addCapabilityBinding("actions.intent.SEND_MESSAGE")
  .build();

ShortcutManagerCompat.pushDynamicShortcut(myContext, shortcutInfo);

送信メッセージがグループ チャットの場合は、Audience パラメータ値も追加する必要があります。recipient タイプは機能に関連付けられているためです。

Kotlin

val shortcutInfo = ShortcutInfoCompat.Builder(myContext, staticConversationIdentifier)
  ...
  .setShortLabel(groupShortTitle)
  .setLongLabel(groupLongTitle)
  .setCategories(matchedCategories)
  .setLongLived(true)
  .addCapabilityBinding("actions.intent.SEND_MESSAGE", "message.recipient.@type", listOf("Audience")).build()

ShortcutManagerCompat.pushDynamicShortcut(myContext, shortcutInfo)

Java

ShortcutInfoCompat shortcutInfo = new ShortcutInfoCompat.Builder(myContext, staticConversationIdentifier)
  ...
  .setShortLabel(groupShortTitle)
  .setLongLabel(groupLongTitle)
  .setCategories(matchedCategories)
  .setLongLived(true)
  .addCapabilityBinding("actions.intent.SEND_MESSAGE", "message.recipient.@type", Arrays.asList("Audience"))
  .build();

ShortcutManagerCompat.pushDynamicShortcut(myContext, shortcutInfo);

受信メッセージのショートカットの使用状況を報告する

ユーザーが SMS、 チャット メッセージ、メール、通知などのメッセージを受信したときに使用状況の報告をトリガーするには、ショートカットに機能 バインディングを ShortcutInfoCompat.Builder#addCapabilityBinding を介して指定する必要があります。 actions.intent.RECEIVE_MESSAGE 機能を使用します。

Kotlin

val shortcutInfo = ShortcutInfoCompat.Builder(myContext, staticConversationIdentifier)
  ...
  .setShortLabel(firstName)
  .setLongLabel(fullName)
  .setCategories(matchedCategories)
  .setLongLived(true)
  .addCapabilityBinding("actions.intent.RECEIVE_MESSAGE").build()

ShortcutManagerCompat.pushDynamicShortcut(myContext, shortcutInfo)

Java

ShortcutInfoCompat shortcutInfo = new ShortcutInfoCompat.Builder(myContext, staticConversationIdentifier)
  ...
  .setShortLabel(firstName)
  .setLongLabel(fullName)
  .setCategories(matchedCategories)
  .setLongLived(true)
  .addCapabilityBinding("actions.intent.RECEIVE_MESSAGE")
  .build();

ShortcutManagerCompat.pushDynamicShortcut(myContext, shortcutInfo);

受信メッセージがグループ チャットからのものである場合は、Audience パラメータ値も追加する必要があります。sender タイプ は機能に関連付けられているためです。

Kotlin

val shortcutInfo = ShortcutInfoCompat.Builder(myContext, staticConversationIdentifier)
  ...
  .setShortLabel(groupShortTitle)
  .setLongLabel(groupLongTitle)
  .setCategories(matchedCategories)
  .setLongLived(true)
  .addCapabilityBinding("actions.intent.RECEIVE_MESSAGE", "message.sender.@type", listOf("Audience")).build()

ShortcutManagerCompat.pushDynamicShortcut(myContext, shortcutInfo)

Java

ShortcutInfoCompat shortcutInfo = new ShortcutInfoCompat.Builder(myContext, staticConversationIdentifier)
  ...
  .setShortLabel(groupShortTitle)
  .setLongLabel(groupLongTitle)
  .setCategories(matchedCategories)
  .setLongLived(true)
  .addCapabilityBinding("actions.intent.RECEIVE_MESSAGE", "message.sender.@type", Arrays.asList("Audience"))
  .build();

ShortcutManagerCompat.pushDynamicShortcut(myContext, shortcutInfo);

AndroidX を使用して共有ショートカットと ChooserTarget の両方を提供する

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

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

次の例の場合、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>

共有ショートカットに関するよくある質問

ショートカットの使用状況データはどのように保存され、デバイスから離れることはありますか?

ショートカットは、暗号化されたディスク パーティションのシステム データ ディレクトリにデバイス上に完全に保存されます。アイコン、インテント、ユーザー名、リソース名などのショートカット内の情報にアクセスできるのは、システム サービスと、ショートカットを公開した同じアプリのみです。

ダイレクト シェアの履歴について教えてください。

Android 6.0(API レベル 23)でダイレクト シェアを導入し、アプリが ChooserTarget オブジェクトを ChooserTargetService を介して提供できるようにしました。結果はオンデマンドで受動的に取得されるため、ターゲットの読み込みに時間がかかっていました。

Android 10(API レベル 29)において、ChooserTargetService DirectShare API は、新しい Sharing Shortcuts API に置き換えられました。Sharing Shortcuts API を使用すると、事後的にオンデマンドで結果を取得するのではなく、事前にダイレクト シェア ターゲットを公開できます。これにより、ShareSheet の準備時にダイレクト シェア ターゲットを取得するプロセスが大幅に高速化されました。ChooserTargetService ダイレクト シェア メカニズムは引き続き機能しますが、この方法で提供されたターゲットは、Sharing Shortcuts API を使用しているどのターゲットよりも下位にランク付けされます。

Android 11(API レベル 30)では、ChooserTargetService サービスが非推奨となり、Sharing Shortcuts API がダイレクト シェア ターゲットを提供するための唯一の方法となりました。

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

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

公開する共有ショートカットの数に関するガイダンスはありますか?

共有ショートカットの数は、動的 ショートカットと同じ上限に制限されます。 getMaxShortcutCountPerActivity(android.content.Context)その上限まで任意の数を公開できますが、共有ショートカットはアプリ ランチャーの長押しと共有シートに表示される可能性があることに注意してください。ほとんどのアプリ ランチャーでは、長押しすると、縦向きモードで最大 4 つまたは 5 つのショートカット、横表示で 8 つのショートカットが表示されます。共有ショートカットの詳細とガイダンスについては、こちらの よくある質問 をご覧ください。