ショートカットの作成

ショートカットは、ユーザーがアプリの要素にすばやくアクセスできる方法で、特定の種類のコンテンツを提供します。

ショートカットでコンテンツを提供する方法は、ユースケースと、ショートカットのコンテキストがアプリ主導かユーザー主導かによって異なります。静的ショートカットのコンテキストは不変であり、動的ショートカットのコンテキストは常に変化しますが、どちらの場合もコンテキストはアプリ主導で決まります。固定ショートカットのようにユーザーがアプリのコンテンツ提供方法を選択する場合、コンテキストはユーザー主導で決まります。ショートカットの種類ごとにユースケースをいくつか示します。

  • 静的ショートカットは、ユーザーがアプリを操作している間、一貫した構造でコンテンツにリンクするアプリに最適です。ほとんどのランチャーは一度に 4 つのショートカットしか表示できないため、静的ショートカットは一般的なアクティビティで有用です。たとえば、ユーザーがカレンダーまたはメールを特定の方法で表示したい場合、静的ショートカットにより、ルーティン タスクを一貫した方法で実施できます。
  • 動的ショートカットは、コンテキスト依存のアプリのアクションに使用されます。コンテキスト依存のショートカットは、アプリ内でユーザーが行うアクションに合わせて調整されます。たとえば、ユーザーがゲームを起動したときに現在のレベルから開始できるゲームを作成する場合、ショートカットを頻繁に更新する必要があります。動的ショートカットを使用すると、ユーザーがレベルをクリアするたびにショートカットが更新されます。
  • 固定ショートカットは、特定のユーザー主導アクションに使用されます。たとえば、特定のウェブサイトをランチャーに固定する場合などです。これは、ユーザーがカスタム アクションを実行できるようになるため、便利です。たとえば、ブラウザのデフォルト インスタンスを使用するより迅速に、ワンステップでウェブサイトに移動できます。

静的ショートカットを作成する

静的ショートカットは、アプリ内の一般的なアクションへのリンクを提供します。こうしたアクションは、アプリの現行バージョンの存続期間を通して一貫性を保つ必要があります。静的ショートカットの適切な使用方法としては、送信済みメッセージの表示、アラームの設定、ユーザーの 1 日の運動状況の表示などがあります。

静的ショートカットを作成する手順は次のとおりです。

  1. アプリのマニフェスト ファイル(AndroidManifest.xml)で、インテント フィルタが android.intent.action.MAIN アクションと android.intent.category.LAUNCHER カテゴリに設定されているアクティビティを見つけます。

  2. 次に示すように、アプリのショートカットが定義されているリソース ファイルを参照する <meta-data> 要素を、そのアクティビティに追加します。

    <manifest xmlns:android="http://schemas.android.com/apk/res/android"
              package="com.example.myapplication">
      <application ... >
        <activity android:name="Main">
          <intent-filter>
            <action android:name="android.intent.action.MAIN" />
            <category android:name="android.intent.category.LAUNCHER" />
          </intent-filter>
          
          <meta-data android:name="android.app.shortcuts"
                     android:resource="@xml/shortcuts" /> 
        </activity>
      </application>
    </manifest>
    
  3. 新しいリソース ファイル res/xml/shortcuts.xml を作成します。

  4. この新しいリソース ファイルに、<shortcut> 要素のリストを含む <shortcuts> ルート要素を追加します。各 <shortcut> 要素には、アイコン、説明ラベル、アプリ内で起動するインテントなど、静的ショートカットに関する情報を指定します。

    <shortcuts xmlns:android="http://schemas.android.com/apk/res/android">
      <shortcut
        android:shortcutId="compose"
        android:enabled="true"
        android:icon="@drawable/compose_icon"
        android:shortcutShortLabel="@string/compose_shortcut_short_label1"
        android:shortcutLongLabel="@string/compose_shortcut_long_label1"
        android:shortcutDisabledMessage="@string/compose_disabled_message1">
        <intent
          android:action="android.intent.action.VIEW"
          android:targetPackage="com.example.myapplication"
          android:targetClass="com.example.myapplication.ComposeActivity" />
        <!-- If your shortcut is associated with multiple intents, include them
             here. The last intent in the list determines what the user sees when
             they launch this shortcut. -->
        <categories android:name="android.shortcut.conversation" />
        <capability-binding android:key="actions.intent.CREATE_MESSAGE" />
      </shortcut>
      <!-- Specify more shortcuts here. -->
    </shortcuts>
    

属性値をカスタマイズする

以下では、静的ショートカット内のさまざまな属性について説明します。android:shortcutIdandroid:shortcutShortLabel の値は必須ですが、その他の値はすべて省略可能です。

android:shortcutId

文字列リテラル。 ShortcutManager オブジェクトがオペレーションを実行するときのショートカットを表します。

注: この属性の値をリソース文字列(@string/foo など)に設定することはできません。

android:shortcutShortLabel

ショートカットの目的を説明する簡潔なフレーズ。可能であれば、ショートカットの「短い説明」の長さは 10 文字以内にします。

詳しくは、 setShortLabel() をご覧ください。

注: この属性の値はリソース文字列(@string/shortcut_short_label など)にする必要があります。

android:shortcutLongLabel

ショートカットの目的を説明する詳細なフレーズ。十分なスペースがある場合、ランチャーは android:shortcutShortLabel の代わりにこの値を表示します。可能であれば、ショートカットの「長い説明」の長さは 25 文字以内にします。

詳しくは、 setLongLabel() をご覧ください。

注: この属性の値はリソース文字列(@string/shortcut_long_label など)にする必要があります。

android:shortcutDisabledMessage

ユーザーが無効なショートカットを起動しようとしたときに、サポートされているランチャーに表示されるメッセージ。このメッセージでは、ショートカットが現在無効になっている理由をユーザーに説明する必要があります。android:enabledtrue の場合、この属性の値は効力を持ちません。

注: この属性の値はリソース文字列(@string/shortcut_disabled_message など)にする必要があります。

android:enabled

サポートされているランチャーからユーザーがショートカットを操作できるかどうかを指定します。android:enabled のデフォルト値は true です。false に設定した場合は、android:shortcutDisabledMessage も設定して、ショートカットを無効にした理由を説明する必要があります。そのようなメッセージを提供する必要がないと考える場合は、XML ファイルからショートカットを完全に削除するのが最も簡単です。

android:icon

ランチャーがショートカットをユーザーに表示するときに使用するビットマップまたはアダプティブ アイコン。この値には、画像へのパスか、画像を含むリソース ファイルのいずれかを指定できます。パフォーマンスと一貫性を向上させるには、可能な限りアダプティブ アイコンを使用します。

注: ショートカット アイコンに色合いを持たせることはできません。

内部要素を設定する

アプリの静的ショートカットをリストした XML ファイルは、各 <shortcut> 要素内で以下の要素をサポートします。定義する静的ショートカットごとに、intent 内部要素を含める必要があります

intent

ユーザーがショートカットを選択したときにシステムが起動するアクション。このインテントでは、android:action 属性の値を指定する必要があります。

注: この intent 要素に文字列リソースを含めることはできません。

1 つのショートカットに複数のインテントを指定できます。詳しくは、複数のインテントとアクティビティを管理するインテントを設定する TaskStackBuilder クラスのリファレンスをご覧ください。

categories

アプリのショートカットで実行するアクション(新しいチャット メッセージの作成など)の種類をグループ化します。

サポートされているショートカット カテゴリの一覧については、 ShortcutInfo クラスのリファレンスをご覧ください。

capability-binding

このショートカットにリンクされたケーパビリティを宣言します。

上記の例では、CREATE_MESSAGEApp Actions 組み込みインテントの一つ)に対して宣言したケーパビリティにショートカットをリンクしています。このケーパビリティ バインディングを加えるだけで、ユーザーは Google アシスタントの音声コマンドを使ってこのショートカットを呼び出せるようになります。

動的ショートカットを作成する

動的ショートカットは、アプリ内のコンテキストに応じた特定のアクションへのリンクを提供します。このアクションは、アプリを使用するたびに、また、アプリの実行中でも変更できます。動的ショートカットのユースケースの良い例としては、特定の相手への通話発信、特定の場所へのナビゲーション、ユーザーの前回のセーブポイントからのゲームの読み込みなどがあります。また、動的ショートカットを使用して会話を開くこともできます。

ShortcutManagerCompat Jetpack ライブラリは、アプリの動的ショートカットを管理するための ShortcutManager API のヘルパーです。ShortcutManagerCompat ライブラリを使用すると、ボイラープレート コードを削減できるとともに、異なる Android バージョン間でのショートカットの動作を一貫させることができます。このライブラリは、Google Shortcuts Integration Library とともに、動的ショートカットをプッシュして Google サーフェス(アシスタントなど)に表示できるようにするためにも必要です。

ShorcutManagerCompat API を使用すると、アプリは動的ショートカットで次のオペレーションを行えます。

  • プッシュと更新: pushDynamicShortcut() を使用して、動的ショートカットの公開と更新を行います。同じ ID の動的ショートカットまたは固定ショートカットがすでに存在する場合は、その可変ショートカットが更新されます。
  • 削除: removeDynamicShortcuts() を使用して動的ショートカットのセットを削除するか、 removeAllDynamicShortcuts() を使用してすべての動的ショートカットを削除します。

ショートカットでオペレーションを実行する方法の詳細については、ショートカットを管理する ShortcutManagerCompat のリファレンスをご覧ください。

次のコード スニペットは、動的ショートカットを作成してアプリに関連付ける方法の例を示しています。

Kotlin


val shortcut = ShortcutInfoCompat.Builder(context, "id1")
        .setShortLabel("Website")
        .setLongLabel("Open the website")
        .setIcon(IconCompat.createWithResource(context, R.drawable.icon_website))
        .setIntent(Intent(Intent.ACTION_VIEW,
                Uri.parse("https://www.mysite.example.com/")))
        .build()

ShortcutManagerCompat.pushDynamicShortcut(context, shortcut)

Java


ShortcutInfo shortcut = new ShortcutInfoCompat.Builder(context, "id1")
    .setShortLabel("Website")
    .setLongLabel("Open the website")
    .setIcon(IconCompat.createWithResource(context, R.drawable.icon_website))
    .setIntent(new Intent(Intent.ACTION_VIEW,
                   Uri.parse("https://www.mysite.example.com/")))
    .build();

ShortcutManagerCompat.pushDynamicShortcut(context, shortcut);

Google Shortcuts Integration Library を追加する

Google Shortcuts Integration Library は、オプションの Jetpack ライブラリです。これを使用することで、Android サーフェス(ランチャーなど)と Google サーフェス(アシスタントなど)の両方に表示可能な動的ショートカットをプッシュできるようになります。また、ユーザーがショートカットを容易に見つけて、アプリ内の特定コンテンツへのアクセスや、アクションの再実行をすばやく行えるようにできます。たとえば、メッセージ アプリなら、ユーザーが「山田さん」という相手にメッセージを送信した後、山田さんの連絡先の動的ショートカットをプッシュできます。その動的ショートカットがプッシュされた後は、ユーザーがアシスタントに「OK Google, 山田さんに ExampleApp でメッセージを送信」と言えば、アシスタントが ExampleApp を起動して山田さんにメッセージを送信するよう自動的に設定できるようになります。

このライブラリでプッシュされる動的ショートカットは、デバイス単位で適用されるショートカットの制限の対象ではないため、ユーザーがアプリで関連付けられたアクションを完了するたびに、アプリがショートカットをプッシュできます。この方法でショートカットを頻繁にプッシュすることで、Google がユーザーの使用パターンを把握し、状況に応じたショートカットを提案できるようになります。たとえば、フィットネス トラッキング アプリがプッシュしたショートカットから、アシスタントはユーザーが毎朝ランニングに行くことを学習できるかもしれません。その場合、アシスタントはユーザーが朝スマートフォンを手に取ると、「ランニングを始める」ショートカットを能動的に提案するようになります。

Google Shortcuts Integration Library は、アドレス可能な機能そのものは提供しません。このライブラリをアプリに追加することにより、ShortcutManagerCompat でプッシュしたショートカットを Google サーフェスが取り込めるようになります。

アプリでこのライブラリを使用する手順は次のとおりです。

  1. AndroidX ライブラリをサポートするため、次のように gradle.properties ファイルを更新します。

    
             android.useAndroidX=true
             # Automatically convert third-party libraries to use AndroidX
             android.enableJetifier=true
    
          
  2. app/build.gradle に、Google Shortcuts Integration Library と ShortcutManagerCompat の依存関係を次のように追加します。

    
             dependencies {
               implementation "androidx.core:core:1.6.0"
               implementation 'androidx.core:core-google-shortcuts:1.0.0'
               ...
             }
    
          
  3. Android プロジェクトに追加したライブラリ依存関係により、アプリは ShortcutManagerCompat pushDynamicShortcut() メソッドを使用して、ランチャーや登録された Google サーフェスに表示可能な動的ショートカットをプッシュできるようになります。

    注: Google Shortcuts Integration Library を使用し、pushDynamicShortcut で動的ショートカットをプッシュすることをおすすめします。アプリから他の方法でショートカットを公開することもできますが、最大ショートカット数の制限によりエラーになる可能性があります。

固定ショートカットを作成する

Android 8.0(API レベル 26)以降では、固定ショートカットを作成できます。固定ショートカットは、静的ショートカットや動的ショートカットとは異なり、サポートされているランチャーに個別のアイコンとして表示されます。図 1 に、2 種類のショートカットの違いを示します。

注: サポートされているランチャーにショートカットを固定しようとすると、ショートカットを固定する権限をユーザーに求める確認ダイアログが表示されます。ユーザーがショートカットの固定を許可しなかった場合、ランチャーはリクエストをキャンセルします。

アプリのショートカットと固定ショートカットの違いを示すスクリーンショット
図 1. アプリのショートカットと固定ショートカットの外観

アプリを使用して、サポートされているランチャーにショートカットを固定する手順は次のとおりです。

  1. isRequestPinShortcutSupported() を使用して、デバイスのデフォルト ランチャーがショートカットのアプリ内固定をサポートしていることを確認します。
  2. ショートカットがすでに存在するかどうかに応じて、次のいずれかの方法で ShortcutInfo オブジェクトを作成します。

    1. ショートカットがすでに存在する場合は、既存のショートカットの ID のみを含む ShortcutInfo オブジェクトを作成します。ショートカットに関連するその他の情報はすべてシステムにより自動的に検出され、固定されます。
    2. 新しいショートカットを固定する場合は、新しいショートカットの ID、インテント、短いラベルを含む ShortcutInfo オブジェクトを作成します。

    注: システムによって固定ショートカットのバックアップと復元が自動的に行われるため、ショートカットの ID には、他のデバイスでは意味をなさないローカルで生成される識別子ではなく、不変の定数文字列またはサーバー側の識別子を使用する必要があります。

  3. ショートカットをデバイスのランチャーに固定するため、 requestPinShortcut() を呼び出します。このプロセス中に、 PendingIntent オブジェクトを渡すことができます。このオブジェクトは、ショートカットが正常に固定された場合にのみアプリに通知します。

    注: ユーザーがショートカットをランチャーに固定することを許可しなかった場合、アプリはコールバックを受け取りません。

    ショートカットが固定されたら、アプリは updateShortcuts() メソッドを使用してコンテンツを更新できます。詳しくは、ショートカットを更新するをご覧ください。

次のコード スニペットは、固定ショートカットを作成する方法を示しています。

注: ShortcutManager クラスのインスタンスを取得するには、引数に ShortcutManager.class を指定した Context.getSystemService(Class) か、引数に Context.SHORTCUT_SERVICE を指定した Context.getSystemService(String) を使用する必要があります。

Kotlin

val shortcutManager = getSystemService(ShortcutManager::class.java)

if (shortcutManager!!.isRequestPinShortcutSupported) {
    // Assumes there's already a shortcut with the ID "my-shortcut".
    // The shortcut must be enabled.
    val pinShortcutInfo = ShortcutInfo.Builder(context, "my-shortcut").build()

    // Create the PendingIntent object only if your app needs to be notified
    // that the user allowed the shortcut to be pinned. Note that, if the
    // pinning operation fails, your app isn't notified. We assume here that the
    // app has implemented a method called createShortcutResultIntent() that
    // returns a broadcast intent.
    val pinnedShortcutCallbackIntent = shortcutManager.createShortcutResultIntent(pinShortcutInfo)

    // Configure the intent so that your app's broadcast receiver gets
    // the callback successfully.For details, see PendingIntent.getBroadcast().
    val successCallback = PendingIntent.getBroadcast(context, /* request code */ 0,
            pinnedShortcutCallbackIntent, /* flags */ 0)

    shortcutManager.requestPinShortcut(pinShortcutInfo,
            successCallback.intentSender)
}

Java

ShortcutManager shortcutManager =
        context.getSystemService(ShortcutManager.class);

if (shortcutManager.isRequestPinShortcutSupported()) {
    // Assumes there's already a shortcut with the ID "my-shortcut".
    // The shortcut must be enabled.
    ShortcutInfo pinShortcutInfo =
            new ShortcutInfo.Builder(context, "my-shortcut").build();

    // Create the PendingIntent object only if your app needs to be notified
    // that the user allowed the shortcut to be pinned. Note that, if the
    // pinning operation fails, your app isn't notified. We assume here that the
    // app has implemented a method called createShortcutResultIntent() that
    // returns a broadcast intent.
    Intent pinnedShortcutCallbackIntent =
            shortcutManager.createShortcutResultIntent(pinShortcutInfo);

    // Configure the intent so that your app's broadcast receiver gets
    // the callback successfully.For details, see PendingIntent.getBroadcast().
    PendingIntent successCallback = PendingIntent.getBroadcast(context, /* request code */ 0,
            pinnedShortcutCallbackIntent, /* flags */ 0);

    shortcutManager.requestPinShortcut(pinShortcutInfo,
            successCallback.getIntentSender());
}

注: サポート ライブラリ API の isRequestPinShortcutSupported() requestPinShortcut() もご覧ください。これらの API は、Android 7.1(API レベル 25)以下で動作します。サポート ライブラリは、非推奨の EXTRA_SHORTCUT_INTENT エクストラにフォールバックして、固定プロセスを試行します。

カスタム ショートカット アクティビティを作成する

カスタム ダイアログ アクティビティにより「ホーム画面に Gmail のランチャー アイコンを追加しますか?」というメッセージが表示されているスクリーンショット。カスタム オプションは [いいえ] と [アイコンを追加] です。
図 2. カスタムのアプリ ショートカット ダイアログ アクティビティの例

カスタム オプションと確認ボタンを備えたショートカットを作成する際に役立つ、特別なアクティビティを作成することもできます。図 2 は、Gmail アプリにおけるそのようなアクティビティの例を示しています。

アプリのマニフェスト ファイルで、 ACTION_CREATE_SHORTCUT をアクティビティの <intent-filter> 要素に追加します。この宣言により、ユーザーがショートカットを作成しようとしたとき、次の動作が設定されます。

  1. システムがアプリの特別なアクティビティを開始します。
  2. ユーザーがショートカットのオプションを設定します。
  3. ユーザーが確認ボタンを選択します。
  4. アプリは createShortcutResultIntent() メソッドを使用してショートカットを作成します。このメソッドは Intent を返します。アプリは、 setResult() で以前実行したアクティビティに、これを送り返します。
  5. アプリは、カスタマイズされたショートカットの作成に使用されたアクティビティで、 finish() を呼び出します。

同様に、アプリがインストールされたとき、または初めて起動されたときに、固定ショートカットをホーム画面に追加するようユーザーにリクエストするメッセージを表示することもできます。この方法は、通常のワークフローの一環としてショートカットの作成をユーザーに促すため、効果的です。

ショートカットをテストする

アプリのショートカットをテストするには、ショートカットをサポートするランチャーを備えたデバイスにアプリをインストールします。次に、以下のアクションを行います。

  • アプリのランチャー アイコンを長押しして、アプリに定義したショートカットを表示します。
  • ショートカットをタップし、デバイスのランチャーにドラッグして、固定します。