しめ鯖日記

swift, iPhoneアプリ開発, ruby on rails等のTipsや入門記事書いてます

Kotlinでウィジェットのボタンを押したらActivityを起動する

ウィジェットのボタンを押したら特定のActivityを開くような実装をしてみたいと思います

まずは新規プロジェクトを作成します

次はウィジェットを追加します

追加後はnew_app_widget.xmlで下のようにボタンを配置します

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    style="@style/Widget.MyApplication.AppWidget.Container"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:theme="@style/Theme.MyApplication.AppWidgetContainer">

    <Button
        android:id="@+id/appwidget_text"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_centerHorizontal="true"
        android:layout_centerVertical="true"
        android:text="テスト" />
</RelativeLayout>

アプリを起動してウィジェットを配置すると下のような表示になります

次はウィジェットのボタンを押した時に表示されるActivityを作成します

最後にウィジェットのボタンを押したときのアクションを追加します
NewAppWidget.ktのupdateAppWidgetを下のように編集します

internal fun updateAppWidget(
    context: Context,
    appWidgetManager: AppWidgetManager,
    appWidgetId: Int
) {
    val views = RemoteViews(context.packageName, R.layout.new_app_widget)
    val intent = Intent(context, MyActivity::class.java)
    val pendingIntent = PendingIntent.getActivity(context, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT or PendingIntent.FLAG_IMMUTABLE)
    views.setOnClickPendingIntent(R.id.appwidget_text, pendingIntent)

    appWidgetManager.updateAppWidget(appWidgetId, views)
}

併せてMainActivity.ktのどこかにウィジェットの更新処理を追加します

val appWidgetManager = AppWidgetManager.getInstance(this)
appWidgetManager.getAppWidgetIds(ComponentName(this, NewAppWidget::class.java)).forEach {
    updateAppWidget(this, appWidgetManager, it)
}

これでボタンを押すと新しいActivityが表示されます

タップしたウィジェットのIDをActivityに渡したい場合、下のようにputExtraを使ってIDをセットします

val intent = Intent(context, MyActivity::class.java).apply {
    putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, appWidgetId)
}

Activity側では下のようにIDを受け取ります

val appWidgetId = intent.extras?.getInt(AppWidgetManager.EXTRA_APPWIDGET_ID) ?: AppWidgetManager.INVALID_APPWIDGET_ID

IDを渡したい場合、PendingIntentのフラグにFLAG_UPDATE_CURRENTを足す必要があります
渡さない場合、古いものが残っているからか値が正しく取れない事がありました

val pendingIntent = PendingIntent.getActivity(context, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT or PendingIntent.FLAG_IMMUTABLE)