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

図 1: Sharesheet の直接共有行(1 で表示)

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

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

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

共有シートのダイレクト シェア行には、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 を使用してショートカットの使用状況をすぐに報告します。詳しくは、このページのコミュニケーション アプリのショートカットの使用状況を報告するをご覧ください。たとえば、actions.intent.SEND_MESSAGE 機能を使用して ShortcutInfoCompat.Builder#addCapabilityBinding を介してショートカットで機能のバインディングを指定し、ユーザーが送信したメッセージの使用状況を報告します。

    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 共有シートでのランキングを上げることができます。これを行うには、ShortcutManagerCompat.pushDynamicShortcut を使用して、連絡先を表す会話ショートカットを再公開します。

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

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

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

使用状況レポートをトリガーするには、actions.intent.SEND_MESSAGE 機能を使用した ShortcutInfoCompat.Builder#addCapabilityBinding で、ショートカットに機能バインディングを指定します。

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);

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

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、チャット メッセージ、メール、通知などのメッセージを受信したときに使用状況レポートをトリガーするには、actions.intent.RECEIVE_MESSAGE 機能を使用して ShortcutInfoCompat.Builder#addCapabilityBinding を介してショートカットで機能のバインディングを追加で指定する必要があります。

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);

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

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 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>

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

ショートカットの使用状況データはどのように保存され、デバイス外に送信されますか?

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

ダイレクト シェアリングの経緯を教えてください。

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

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 個のショートカットが表示されます。ショートカットの共有に関する詳細とガイダンスについては、こちらのよくある質問をご覧ください。