AndroidのウィジェットをタップしてActivityを起動したい
本記事ではAndroidアプリ開発の中でも、ウィジェットに対してタップ時の動作を仕込む方法について記載します。
間違い指摘大歓迎です。
結論
やり方は2通りあります。
-
getActivityを用いてPendingIntentを発行
こちらは単純に自分自身を起動させたいときに便利です。 -
getBroadcastを用いてBroadcastを受け取ってから手動でActivityを起動
こちらは通知を出したい、ブラウザを開きたいときなどに使えます。
もちろん自分自身の起動も可能です。
それでは解説します。
Pending intents
Android Developers - Pending intents
Pendingは 保留中 という意味です。
ウィジェットは通常のアクティビティとはライフサイクルが異なります。
具体的には、その動作をさせたいときに自身が起動していないことがあります。
そんな状態でも指定したタイミングで動作させるために、前もってその動作を 保留 させる必要があります。
PendingIntent.getActivity
Android Developers - PendingIntent - Public methods - getActivity
自身のActivityを起動させるためのIntentを前もって作成しViewに仕込みます。
// create an intent to open the main activity
Intent intent = new Intent(context, MainActivity.class);
intent.setAction("ACTION_APPWIDGET_TAPPED");
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
// create a pending intent
PendingIntent pendingIntent = PendingIntent.getActivity(
context,
0,
intent,
PendingIntent.FLAG_IMMUTABLE);
// set the pending intent to the text view
views.setOnClickPendingIntent(
R.id.appwidget_text,
pendingIntent);
PendingIntent.getBroadcast
Android Developers - PendingIntent - Public methods - getBroadcast
暗黙的インテントや独自実装(通知など)を仕込みたいときに使用します。
BroadcastのIntentが発行されるように 保留 し、onReceiveで受け取ります。
例として、ウィジェットをタップしてブラウザを開いてみましょう。
PendingIntentを使ってBroadcastを発行します。
// create intent to myself
Intent intent = new Intent(context, SampleWidget.class);
intent.setAction("ACTION_APPWIDGET_TAPPED");
// create a pending intent
PendingIntent pendingIntent = PendingIntent.getBroadcast(
context,
0,
intent,
PendingIntent.FLAG_IMMUTABLE);
// set the pending intent to the text view
views.setOnClickPendingIntent(
R.id.appwidget_text,
pendingIntent);
発行したBroadcastをウィジェット側で受け取ります。
// receive broadcast and open browser
@Override
public void onReceive(Context context, Intent intent) {
super.onReceive(context, intent);
// create an intent to open browser
Intent browserIntent = new Intent(Intent.ACTION_VIEW, Uri.parse("https://example.com"));
mainActivityIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
// check if the broadcast is from the widget
if (Objects.equals(intent.getAction(), "ACTION_APPWIDGET_TAPPED")) {
context.startActivity(browserIntent);
}
}
少し手間ではありますが、コチラは柔軟に動作を仕込めそうですね。
まとめ
ウィジェットにタップ時の動作を仕込む方法について解説しました。
getActivityとgetBroadcast、用途に合わせて使い分けましょう。
宣伝
以上の機能を使って、単純なアプリを作成しました。
GitHubのIssue作成画面にワンクリックで飛ぶウィジェットです。
私はタスク管理にもGitHubを使っているので大変捗っています。
Discussion