🗂

AndroidのウィジェットをタップしてActivityを起動したい

2024/02/10に公開

本記事ではAndroidアプリ開発の中でも、ウィジェットに対してタップ時の動作を仕込む方法について記載します。
間違い指摘大歓迎です。

結論

やり方は2通りあります。

  1. getActivityを用いてPendingIntentを発行
    こちらは単純に自分自身を起動させたいときに便利です。

  2. getBroadcastを用いてBroadcastを受け取ってから手動でActivityを起動
    こちらは通知を出したい、ブラウザを開きたいときなどに使えます。
    もちろん自分自身の起動も可能です。

それでは解説します。

Pending intents

Android Developers - Pending intents

Pendingは 保留中 という意味です。
ウィジェットは通常のアクティビティとはライフサイクルが異なります。
具体的には、その動作をさせたいときに自身が起動していないことがあります。
そんな状態でも指定したタイミングで動作させるために、前もってその動作を 保留 させる必要があります。

PendingIntent.getActivity

Android Developers - PendingIntent - Public methods - getActivity

自身のActivityを起動させるためのIntentを前もって作成しViewに仕込みます。

SampleWidget.java
// 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を発行します。

SampleWidget.java
// 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をウィジェット側で受け取ります。

SampleWidget.java
// 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を使っているので大変捗っています。

ご興味のある方は以下からダウンロードしてみてください。
(Google Playのテスト要件、難しすぎますね...。)

Discussion