AppShortcutsでNavigation Drawerを持ったActivityを起動するときの実装方法

More than 1 year has passed since last update.

今回、私の開発しているKyudoScoreBookでAppShortcutsを実装しました。

KyudoScoreBookはGooglePlayStoreのようにNavigation Drawerを使っています。

Navigation Drawerから遷移できる基本機能の画面には、Navigation Drawerのメニューが選択された状態で表示するため、各画面はFragmentで切り替える実装を行っています。


AppShortcutsで実現したいこと

AppShortcutsでは、Navigation Drawerのメニューに表示されている、記録、メモ一覧、グラフ、占いの4つのメニューを実装することにしました。

先程述べたように、記録のショートカットから起動された場合は、Navigation Drawerの記録が選択状態で起動してほしいです。

また、各画面は同じActivityで複数Fragmentを切り替える実装になっているので、AppShortcutsから起動するときは同じAcitivityを起動する必要があります。

App ShortCutsの説明やgooglesamples/android-AppShortcutsには1つのショートカットのサンプルコードしかなく、困りました。


Static ShortcutsのintentにExtraを詰め込む

AppShortcutsから同じActivityを起動し、異なるFragmentを表示させたいので、intentにExtraを詰め込んで起動する必要があります。

その場合以下のように<intent>タグで<extra>タグを囲みます。


<shortcuts xmlns:android="http://schemas.android.com/apk/res/android">
<shortcut
android:enabled="true"
android:icon="@drawable/ic_short_record"
android:shortcutId="shortcut_record"
android:shortcutLongLabel="@string/shortcut_record"
android:shortcutShortLabel="@string/shortcut_record">
<intent
android:action="android.intent.action.VIEW"
android:targetClass="com.bowyer.app.appshortcuts.ui.activity.MainActivity"
android:targetPackage="com.bowyer.app.appshortcuts">
<extra
android:name="shortcut_id"
android:value="RecordTabFragment"/>
</intent>
<categories android:name="android.shortcut.conversation"/>

</shortcut>
<shortcut
android:enabled="true"
android:icon="@drawable/ic_short_memo"
android:shortcutId="shortcut_memos"
android:shortcutLongLabel="@string/shortcut_memo_list"
android:shortcutShortLabel="@string/shortcut_memo_list">
<intent
android:action="android.intent.action.VIEW"
android:targetClass="com.bowyer.app.appshortcuts.ui.activity.MainActivity"
android:targetPackage="com.bowyer.app.appshortcuts">
<extra
android:name="shortcut_id"
android:value="MemoListFragment"/>
</intent>

<categories android:name="android.shortcut.conversation"/>
</shortcut>
</shortcuts>


どのAppShortcutsから起動されたかハンドリングする

AppShortcutsから起動したMainActivity側では、intentからshortcut_idのExtraを取得します。

私の場合、通常起動もMainActivityを使用するので、shortcut_idが存在しているかチェックしています。


private static final String KEY_SHORTCUT_ID = "shortcut_id";
・・・
private void handleShortcutsAction() {
boolean hasExtra = getIntent().hasExtra(KEY_SHORTCUT_ID);
if (!hasExtra) {
return;
}
String shortcutId = getIntent().getStringExtra(KEY_SHORTCUT_ID);
・・・

あとはこのshortcutIdに応じた処理を記載します。


String shortcutId = getIntent().getStringExtra(KEY_SHORTCUT_ID);
// 取得したshortcutIdからどのFragmentを起動するか決める
Page page = Page.forMenuId(shortcutId);
switch (page.getMenuId()) {
case R.id.nav_record:
pageChange(RecordTabFragment.newInstance());
break;
case R.id.nav_memo:
pageChange(MemoListFragment.newInstance());
break;
case R.id.nav_chart:
pageChange(ChartFragment.newInstance());
break;
case R.id.nav_notification:
pageChange(NotificationFragment.newInstance());
break;
case R.id.nav_fortune:
pageChange(FortuneFragment.newInstance());
break;
}
// Navigation Drawerを選択状態にする
navigationView.setCheckedItem(page.getMenuId());

GooglePlayStoreのようにNavigation Drawerで複数のFragmentを切り替えて使うようなアプリで、AppShortcutsを実装する場合は、参考にしてみてください。


AppShortcutsのサンプルコード

今回リリースしたアプリの一部コードを切り出したものを公開してます。KyudoScoreAppShortcuts

このサンプルコードを提供してすぐはStatic ShortcutsのintentにExtraを詰め込む方法が分からなかったので、Dynamic Shortcutsを使って複数のIntentを作成するイケてない実装でした。

そのDynamic ShortcutsからStatic Shortcutsに実装をやり直したPRもありますので、よければ参考にしてください。

Use static shortcuts with bundle extras


最後に

AppShortcutsはまだ情報が少なく、躓くことは多々あります。

私の公開したAppShortcutsのサンプルコードも、実装的にイケてない部分があります。

もしAppShortcutsのサンプルコードを見て、もっとこうした方が良いとかありましたらPRお願いします。