ショートカットを管理する

ショートカットを作成すると、アプリの全期間にわたってショートカットを管理する必要が生じる場合があります。たとえば、アプリを最適化するため、ユーザーがショートカットを使用して特定のアクションを行う頻度を測定する場合などです。また、固定ショートカットを無効にして、アプリが古くなったアクションや存在しなくなったアクションを実行しないようにする場合もあります。会話で参照されるショートカットについては、使用状況をトラッキングして、ショートカットのランキングを改善するシグナルを提供することが望ましいでしょう。

このページでは、上記をはじめ、ショートカットを管理する一般的な方法について説明します。

ショートカットの動作

ここでは、ショートカットの動作(表示、表示順序、ランク)に関する一般的な情報について説明します。

ショートカットの表示

静的ショートカットと動的ショートカットは、ユーザーが特定の操作や音声コマンドを実行したときに、サポートされているランチャーまたはアシスタントに表示されます。サポートされているランチャーの場合、この操作はアプリのランチャー アイコンのタッチ&ホールドですが、他のランチャー アプリの場合は実際の操作がこれと異なる場合があります。Google アシスタントを使用すると、ショートカットをアシスタント内に表示したり、ユーザーの音声コマンドで起動したりできます。

LauncherApps クラスは、ランチャー アプリが ショートカットにアクセスするための API を提供します。

固定ショートカットはランチャー自体に表示されるため、常にユーザーの目に入ります。 固定ショートカットは、以下の場合にのみ、ランチャーから削除されます。

  • ユーザーが削除した。
  • ショートカットに関連付けられているアプリがアンインストールされた。
  • ユーザーが [設定 > アプリと通知] に移動してアプリを選択し、[ストレージ > ストレージを消去] をタップして、アプリのデータを消去した。

共有ターゲットは、Android 共有シートの直接 共有の行に表示される動的ショートカットのサブセットです。

Android Sharesheet
図 1.Android Sharesheet。最初の行にダイレクト シェア ターゲットが表示され、その後にランク付けされたアプリ、アプリリストが続きます。

ショートカットの表示順序

ランチャーがアプリのショートカットを表示する際は、次の順序で表示する必要があります。

  1. 静的ショートカット: isDeclaredInManifest() メソッドが true を返すショートカット。
  2. 動的ショートカット: ShortcutInfo.isDynamic() メソッドが true を返すショートカット。

同じ種類(静的または動的)の中では、ショートカットは ランクの昇順でShortcutInfo.getRankに従って並べられます。Google アシスタントは、ユーザーに表示する状況依存のショートカットを決定する際に、ショートカットのランクも考慮します。

ランクは、負ではない連続した整数です。静的ショートカットは、shortcuts.xml ファイルに表示される順に、最初から最後までのランクが付けられます。動的 ショートカットの場合は、 updateShortcuts(Context, List)addDynamicShortcuts(Context, List)pushDynamicShortcut(Context, ShortcutInfoCompat)、または setDynamicShortcuts(Context, List) のいずれかを呼び出すと、既存のショートカットのランクを更新できます。

共有ターゲットの順序は、過去のユーザー履歴、最新性、頻度、ランクのヒント、アプリの使用状況、共有ショートカットに関連付けられた会話に設定された優先度など、さまざまな要因に基づいて決まります。Sharing targets created using the Sharing Shortcuts API are prioritized over the sharing targets produced by the ChooserTargetService which was deprecated in Android 11. Android 12 以降では、非推奨の ChooserTargetService によって生成された共有ターゲットは共有シートに表示されなくなります。

ほとんどのランチャーでは、最大 4 つのショートカットが表示されます。定義されている静的ショートカットと動的ショートカットの組み合わせに関係なく、ランチャーには最大 2 つの静的ショートカットと 2 つの動的ショートカットが表示されます。たとえば、4 つの静的ショートカットを定義し、プログラムで 3 つの動的ショートカットを作成した場合、ランチャーには最初の 2 つの静的ショートカットと、ランクが最も高い 2 つの動的ショートカットが表示されます。

複数のインテントとアクティビティを管理する

ユーザーがショートカットを有効にしたときにアプリで複数のオペレーションを実行する場合は、連続するアクティビティをトリガーするようにアプリを構成できます。これを行うには、ショートカットの種類に応じて、複数のインテントを割り当てる、アクティビティから別のアクティビティを開始する、インテント フラグを設定します。

アクティビティから別のアクティビティを開始する

静的ショートカットにカスタム インテント フラグを含めることはできません。静的 ショートカットの最初のインテントには、常に Intent.FLAG_ACTIVITY_NEW_TASKIntent.FLAG_ACTIVITY_CLEAR_TASK が設定されます。つまり、アプリの実行中に静的ショートカットが起動されると、アプリ内の既存のアクティビティはすべて破棄されます。この動作を回避するには、起動ブロック内または Compose コンテンツが設定される前に onCreate 内で finish を呼び出して、トランポリン アクティビティ(別のアクティビティを開始する非表示のアクティビティ)を使用します。

  1. AndroidManifest.xml file で、トランポリン アクティビティに android:taskAffinity="" 属性割り当てを含めます。

  2. ショートカットのリソース ファイルで、静的ショートカット内のインテントでトランポリン アクティビティを参照します。

トランポリン アクティビティについて詳しくは、 アクティビティから別のアクティビティを開始するをご覧ください。

インテント フラグを設定する

動的ショートカットは、Intent フラグの任意のセットを使用して公開できます。 ショートカットのインテントでは、Intent.FLAG_ACTIVITY_SINGLE_TOPIntent.FLAG_ACTIVITY_CLEAR_TOP の組み合わせを指定することをおすすめします。これにより、ComponentActivity がすでにアクティブな場合は、破棄されずにフォアグラウンドに移動して再利用されるため、単一アクティビティ アーキテクチャで onNewIntent() を介してショートカット イベントを適切に処理できます。

タスクとインテント フラグについて詳しくは、タスクとバックスタックをご覧ください。

ショートカットを更新する

各アプリのランチャー アイコンには、静的ショートカットと動的 ショートカットを組み合わせて、 getMaxShortcutCountPerActivity が返す値までの数を含めることができます。アプリで作成できる固定ショートカットの数に制限はありません。

動的ショートカットが固定されている場合、パブリッシャーがそれを動的ショートカットとして削除しても、固定ショートカットは引き続き表示され、起動可能です。これにより、アプリは getMaxShortcutCountPerActivity の数を超えるショートカットを持つことができます。

次の例では、getMaxShortcutCountPerActivity が返す値が 4 であると想定しています。

  1. あるチャットアプリが、最新の 4 つのスレッド(c1、c2、c3、c4)を表す 4 つの動的ショートカットを公開します。
  2. ユーザーが 4 つのショートカットをすべて固定します。
  3. その後、ユーザーが追加のスレッド(c5、c6、c7)を 3 つ開始します。公開元アプリは動的ショートカットを再公開します。新しい動的ショートカット リストは、c4、c5、c6、c7 です。

アプリは 4 つを超える動的ショートカットを表示できないため、c1、c2、c3 を削除する必要が生じます。ただし、c1、c2、c3 は、依然としてユーザーがアクセスして起動できる固定ショートカットのままです。

これで、ユーザーは、公開元アプリのアクティビティにリンクする合計 7 つのショートカットを利用できるようになりました。この合計数には、最大数のショートカットと 3 つの固定ショートカットが両方とも含まれているからです。

  1. アプリは updateShortcuts(Context, List) を使用して、既存の 7 つのショートカットのいずれも更新できます。たとえば、チャット相手のアイコンが変更されたときに、このショートカット セットを更新できます。
  2. addDynamicShortcuts(Context, List) メソッドと setDynamicShortcuts(Context, List) メソッドを使用して、同じ ID を持つ既存のショートカット を更新することもできます。ただし、この 2 つは、指定されたリストのショートカットを動的ショートカットに変換しようとするため、動的でない固定ショートカットの更新には使用できません。

プッシュして Google アシスタントなどのアシスタント アプリに表示できるショートカットの数に制限はありません。アシスタント アプリで使用するショートカットを作成、更新するには、ShortcutManagerCompat Jetpack ライブラリの pushDynamicShortcut メソッドを使用します。また、Google アシスタントにダイナミック リンクを表示するには、Google Shortcuts Integration Library をアプリに追加する必要があります。

ショートカットの更新など、アプリのショートカットのガイドラインについて詳しくは、 ショートカットに関するおすすめの方法をご覧ください。

システム ロケールの変更を処理する

アプリは、システム ロケールの変更を示す Intent.ACTION_LOCALE_CHANGEDブロードキャストを受信したときに、動的ショートカットと固定ショートカットを更新する必要があります。

ショートカットの使用状況をトラッキングする

静的ショートカットと動的ショートカットが表示される状況を判別するために、ランチャーはショートカットの使用履歴を調べます。静的ショートカットの場合、 次のいずれかのイベントが発生した際に、 reportShortcutUsed メソッドを呼び出してショート 101}カットの ID を渡すことにより、ユーザーがアプリ内で特定のアクションを完了したタイミングをトラッキングできます。

  • ユーザーが特定の ID のショートカットを選択した。
  • アプリ内で、ユーザーが同じショートカットに対応するアクションを手動で完了した。

動的ショートカットの使用状況をトラッキングするには、関連するイベントが発生した際に、pushDynamicShortcut メソッドを呼び出してショートカットの ID を渡します。 このメソッドで動的ショートカットの使用状況をプッシュすると、Google アシスタントなどのアシスタント アプリが関連のショートカットをユーザーに提案できるようになります。pushDynamicShortcut メソッドを呼び出すことで使用状況が報告されるため、同じショートカットに対してさらに reportShortcutUsed メソッドを呼び出さないようにします。

会話関連のショートカットについては、送信メッセージと受信メッセージの使用状況をトラッキングすることが重要です。詳しくは、ユーザーと会話に関する おすすめの方法をご覧ください。

ショートカットを無効にする

アプリとそのユーザーはショートカットをデバイスのランチャーに固定できるため、固定ショートカットによって、アプリ内の古くなったアクションまたは存在しなくなったアクションにユーザーが誘導されることがあります。この状況に対処するには、 ユーザーに選択させたくないショートカットを disableShortcutsを呼び出して無効にします。これにより、指定したショートカットが静的 ショートカットと動的ショートカットのリストから削除され、対応する固定ショートカットが無効になります。このメソッドのオーバーロード版を使用することもできます。これは、 CharSequence をカスタム エラー メッセージとして受け入れます。このエラー メッセージは、ユーザーが無効なショートカットを起動しようとしたときに表示されます。

レート制限

setDynamicShortcuts, addDynamicShortcutsupdateShortcuts のいずれかのメソッドを使用する場合、バックグラウンド アプリ(現在フォアグラウンドで動作しているアクティビティまたはサービスがないアプリ)では、これらのメソッドを特定の回数しか呼び出せない可能性があるため、ご注意ください。 これらのメソッドを呼び出すことができる回数の制限は、レート制限と呼ばれます。 この機能により、ShortcutManagerCompat が デバイスリソースを過剰に消費することを防ぎます。

レート制限が有効になっている場合、isRateLimitingActive は true を返します。 ただし、レート制限は特定のイベントでリセットされるため、バックグラウンド アプリであっても、レート制限に再び達するまで ShortcutManager メソッドを呼び出すことができます。これらのイベントには、次のものがあります。

  • アプリがフォアグラウンドに復帰した。
  • システム ロケールが変更された。
  • ユーザーが通知でインライン返信アクションを実行した。

開発中またはテスト中にレート制限が発生した場合は、 [開発者向けオプション > ShortcutManager のレート制限をリセット] を デバイスの 設定 から選択するか、adb で次のコマンドを入力します。

$ adb shell cmd shortcut reset-throttling [ --user <var>your-user-id</var> ]

バックアップと復元

アプリのマニフェスト ファイルに android:allowBackup="true" 属性 割り当てを含めると、ユーザーがデバイスを変更する際にアプリでバックアップと復元を行えるようになります。バックアップと復元をサポートする場合は、アプリのショートカットについて次の点に注意してください。

  • 静的ショートカットは自動的に再公開されますが、ユーザーが新しいデバイスにアプリを再インストールした場合に限られます。
  • 動的ショートカットはバックアップされないため、ユーザーが新しいデバイスでアプリを開いたときに動的ショートカットを再公開するには、アプリにそのためのロジックを組み込む必要があります。
  • 固定ショートカットはデバイスのランチャーに自動的に復元されますが、固定ショートカットに関連付けられたアイコンはバックアップされません。 そのため、固定ショートカットの画像をアプリに保存して、新しいデバイスで簡単に復元できるようにする必要があります。

次のコード スニペットは、アプリの動的ショートカットを復元する最適な方法と、アプリの固定ショートカットが保持されたかどうかを確認する方法を示しています。

class MainActivity : ComponentActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        if (ShortcutManagerCompat.getDynamicShortcuts(this).isEmpty()) {
            // Application restored. Re-publish dynamic shortcuts.
            if (ShortcutManagerCompat.getPinnedShortcuts(this).isNotEmpty()) {
                // Pinned shortcuts are restored. Use updateShortcuts() to make
                // sure they contain up-to-date information.
            }

        }
    }
    // ...
}