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

図 1: Sharesheet のダイレクト シェア行(1 で表示)

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

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

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

Sharesheet Direct Share の行には、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 に対応していない場合、対応するショートカットをテキスト以外の MIME タイプ(image/*video/* など)に関連付けることはできません。
  • 特定の会話で動的ショートカットがプッシュされ、使用状況が報告された後は、ショートカット ID を変更しないでください。これにより、ランキング用の使用状況データが確実に保持されます。

ユーザーがダイレクト シェア ターゲットをタップした場合、アプリは、ターゲット サブジェクトに対して直接アクションを実行できる UI にユーザーを誘導する必要があります。確認用の 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() を使用してアダプティブ ビットマップを提供します。

アダプティブ ビットマップが、アダプティブ アイコンに設定されているガイドラインとサイズと同じであることを確認してください。 最も一般的な方法は、目的の正方形のビットマップを 72x72 dp に拡大縮小し、108x108 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)との下位互換性があります。

送信メールのショートカットの使用状況を報告

ユーザーが送信したメッセージに関するレポートの使用方法は、メッセージの作成後に [送信] ボタンをクリックする場合とほぼ同じです。

使用状況レポートをトリガーするには、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 の選択とターゲット サービス セットとインテント フィルタ セットが含まれている必要があります。現在の ChooserTargetService Direct Share 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 Direct Share 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 個のショートカットが表示されます。ショートカットの共有の詳細とガイダンスについては、こちらのよくある質問をご覧ください。