Androidのショートカット実装 その2
今回は動的ショートカット
先日は、Androidのショートカット実装で静的ショートカットを実装した時の事を書いたので、今回は動的ショートカットについて書こうと思います。
動的ショートカットについて
「動的」ということで何となくイメージできると思いますが、事前にイメージしたのはショートカットに表示する内容を「動的」に変えられるようなイメージと思ってました。
公式サイトでは「コンテキスト依存のアプリのアクションに使用されます。コンテキスト依存のショートカットは、アプリ内でユーザーが行うアクションに合わせて調整されます。」と紹介されてます。
具体的な使用例として「ユーザーがレベルをクリアするたびにショートカットを更新する。」とあるので、アプリ内の任意のアクションに応じてショートカットを更新できるということですね。
動的ショートカットの実装
さて、静的ショートカットではxmlなどを用いて実装しましたが、今回の動的ショートカットはxmlは登場しません。
動的ショートカットはJetpackライブラリのShortcutManagerCompatを利用します。
動的ショートカットの追加はpushDynamicShortcut()を利用します。
val shortcut = ShortcutInfoCompat.Builder(applicationContext, "id")
.setShortLabel(formatted)
.setIcon(IconCompat.createWithResource(applicationContext, R.drawable.ic_launcher_foreground))
.setIntent(Intent.makeMainActivity(ComponentName(applicationContext, "com.example.vcs.MainActivity")))
.build()
ShortcutManagerCompat.pushDynamicShortcut(applicationContext, shortcut)
上記の例ではShortcutInfoCompat.Builder(context, String)のidを固定で指定してるので、pushDynamicShortcut()を実行するたびに同じショートカットの内容を更新します。
idを変化させればショートカットも複数作成する事ができました。
その他の設定の概要は以下の通りです。
- setShortLabel -> ランチャーがショートカットをユーザーに表示するときに使用する
- setIcon -> ランチャーがショートカットをユーザーに表示するときに使用する
- setIntent -> ショートカットをタップした時に実行するIntent
なお、Intentを設定しないと「Shortcut must have an intent」で怒られます。
追加したショートカットを削除するには、removeDynamicShortcuts()またはremoveAllDynamicShortcuts()を使います。
idを指定して個別に削除するショーカットを指定する場合は「removeDynamicShortcuts()」、全てのショートカットを削除する場合は「removeAllDynamicShortcuts()」で可能です。
ShortcutManagerCompat.removeDynamicShortcuts(applicationContext, listOf("id"))
ShortcutManagerCompat.removeAllDynamicShortcuts(applicationContext)
Google Shortcuts Integration Library
詳しくはこちらに書いてありますが、オプションのJetpackライブラリです。
Google Shortcuts Integration Libraryを使用すると、Android サーフェス(ランチャーなど)と Google サーフェス(アシスタントなど)の両方に表示可能な動的ショートカットをプッシュできるようになります。
Google Shortcuts Integration Library は、アドレス可能な機能そのものは提供しません。このライブラリをアプリに追加することにより、ShortcutManagerCompat でプッシュしたショートカットを Google サーフェスが取り込めるようになります。
具体的な例としては以下のユースケースが紹介されてました。
メッセージ アプリなら、ユーザーが「山田さん」という相手にメッセージを送信した後、山田さんの連絡先の動的ショートカットをプッシュできます。その動的ショートカットがプッシュされた後は、ユーザーがアシスタントに「OK Google, 山田さんに ExampleApp でメッセージを送信」と言えば、アシスタントが ExampleApp を起動して山田さんにメッセージを送信するよう自動的に設定できるようになります。
Google Shortcuts Integration Libraryの追加方法は次の通りです。
- AndroidX ライブラリをサポートするためgradle.propertiesに以下を追加
android.useAndroidX=true
# Automatically convert third-party libraries to use AndroidX
android.enableJetifier=true
- app/build.gradleにGoogle Shortcuts Integration Library と ShortcutManagerCompat の依存関係を追加
implementation "androidx.core:core:1.6.0"
implementation 'androidx.core:core-google-shortcuts:1.0.0'
- ShortcutManagerCompat の pushDynamicShortcut()を通じて動的ショートカットを追加する
サンプル実装
今回は、id固定で追加ボタンタップする度に時刻を取得し、ラベルの更新を行うような実装をしてみました。
また、削除ボタンで全てのショートカットを削除することも試しました。
※だいぶ省略してますが、JetpackComposeを利用してMainコンポーザブルに追加ボタンと削除ボタンがある前提です。
Main(
onAddClick = {
// 時間のみ
val current = LocalDateTime.now()
val formatter = DateTimeFormatter.ISO_TIME
val formatted = current.format(formatter)
val shortcut = ShortcutInfoCompat.Builder(applicationContext,"id")
.setShortLabel(formatted)
.setIcon(IconCompat.createWithResource(applicationContext, R.drawable.ic_launcher_foreground))
.setIntent(Intent.makeMainActivity(
ComponentName(applicationContext, "com.example.vcs.MainActivity")))
.build()
ShortcutManagerCompat.pushDynamicShortcut(applicationContext, shortcut)
},
onRemoveClick = {
ShortcutManagerCompat.removeAllDynamicShortcuts(applicationContext)
}
)
1回目の追加
2回目の追加(ラベルが変わっている)
最後に
ショートカット機能自体を活用してもらうには、まずはユーザーに認知してもらう必要があるので、そこが課題ではあります。
しかし、うまく利用すれば便利な機能だと感じたので、自プロダクトへの導入も含めて検討していきたい。
Discussion