はじめに
たまに触るとすぐ忘れてしまうので。。自分の備忘録も兼ねてまとめていきます!
AppWidgetProviderって何?
簡単に言うと、ウィジェットの色々なイベントを受け取って処理するやつです。
BroadcastReceiverを継承してて、システムやユーザーからの通知を受け取れる。
メソッドたち
1. onUpdate() [ 絶対使うやつ ]
override fun onUpdate(
context: Context,
appWidgetManager: AppWidgetManager,
appWidgetIds: IntArray
) {
// ウィジェット更新処理
}
いつ呼ばれる?
- ウィジェットをホーム画面に置いたとき
- 設定した更新間隔ごと
- システムから「更新して!」って通知が来たとき
何に使う?
ウィジェットの表示を更新するのに使う。
初期化や定期更新の処理はここに書く。
2. onReceive() - ウィジェット内のボタンとか押した時
override fun onReceive(context: Context, intent: Intent) {
super.onReceive(context, intent) // これいる。
when (intent.action) {
"BUTTON_CLICK" -> {
// ボタン押された時の処理
}
}
}
いつ呼ばれる?
- ウィジェットのボタンをタップしたとき
- カスタムのブロードキャスト送ったとき
- 日付変わった時とか
何に使う?
ボタンタップとか、自分で作ったアクションを処理する。
注意!
super.onReceive(context, intent)を呼び忘れると、
他のメソッド(onUpdateとか)が動かなくなる...!
3. onEnabled() - 最初の1個だけ
override fun onEnabled(context: Context) {
// 初期化処理
}
いつ呼ばれる?
最初のウィジェットを置いた時だけ。2個目以降は呼ばれない。
何に使う?
- データベースとか作る
- 定期更新のスケジュール設定
- 初回だけやりたいこと全般
4. onDisabled() - 最後の1個が消えた時
override fun onDisabled(context: Context) {
// お掃除処理
}
いつ呼ばれる?
最後のウィジェットを削除した時だけ。
何に使う?
- 定期更新を止める
- リソースの解放
- データベースとか消すとか
onEnabled()とセットで使う!
5. onDeleted() - 個別に消された時
override fun onDeleted(context: Context, appWidgetIds: IntArray) {
// そのウィジェットのデータ削除
}
いつ呼ばれる?
ウィジェットを削除するたび。
何に使う?
そのウィジェット固有の設定とかデータを消す。
onDisabled()との違いは?
onDeleted(): ウィジェット消すたびに呼ばれるonDisabled(): 最後の1個が消えた時だけ
6. onAppWidgetOptionsChanged() - サイズ変わった時
override fun onAppWidgetOptionsChanged(
context: Context,
appWidgetManager: AppWidgetManager,
appWidgetId: Int,
newOptions: Bundle
) {
// サイズに合わせてレイアウト変更
}
いつ呼ばれる?
ウィジェットのサイズを変更した時。
何に使う?
サイズに応じてレイアウトを切り替えたり、表示内容を変えたり。
ライフサイクルの流れ
1. ウィジェット配置:
onEnabled() → onUpdate()
2. 定期更新:
onUpdate()
3. サイズ変更:
onAppWidgetOptionsChanged()
4. ボタンタップとか:
onReceive()
5. ウィジェット削除:
onDeleted() → (最後なら) onDisabled()
実装例
実際に書くとこんな感じ:
class MyWidgetProvider : AppWidgetProvider() {
// アクション定義
companion object {
const val ACTION_BUTTON = "BUTTON_CLICK"
}
// ウィジェット更新
override fun onUpdate(
context: Context,
appWidgetManager: AppWidgetManager,
appWidgetIds: IntArray
) {
appWidgetIds.forEach { id ->
val views = RemoteViews(
context.packageName,
R.layout.widget_layout
)
// ボタンにアクション設定
val intent = Intent(context, MyWidgetProvider::class.java).apply {
action = ACTION_BUTTON
}
val pendingIntent = PendingIntent.getBroadcast(
context, 0, intent,
PendingIntent.FLAG_UPDATE_CURRENT or PendingIntent.FLAG_IMMUTABLE
)
views.setOnClickPendingIntent(R.id.button, pendingIntent)
// ウィジェット更新
appWidgetManager.updateAppWidget(id, views)
}
}
// ボタンタップとか処理
override fun onReceive(context: Context, intent: Intent) {
super.onReceive(context, intent)
if (intent.action == ACTION_BUTTON) {
// ボタン押された!
}
}
// サイズ変更対応
override fun onAppWidgetOptionsChanged(
context: Context,
appWidgetManager: AppWidgetManager,
appWidgetId: Int,
newOptions: Bundle
) {
// サイズ変更対応(幅・高さ取得してレイアウト変更とか)
val minWidth = newOptions.getInt(AppWidgetManager.OPTION_APPWIDGET_MIN_WIDTH)
val minHeight = newOptions.getInt(AppWidgetManager.OPTION_APPWIDGET_MIN_HEIGHT)
}
// 初回だけの初期化
override fun onEnabled(context: Context) {
// DBとか作る
}
// 全部消えた時のお掃除
override fun onDisabled(context: Context) {
// リソース解放とか
}
}
まとめ
-
onUpdate(): 更新処理 (絶対使う) -
onReceive(): ボタンとかのアクション処理。 -
onEnabled()/onDisabled(): 最初と最後の初期化・お掃除 -
onDeleted(): 個別削除の処理 -
onAppWidgetOptionsChanged(): サイズ変更対応
これ覚えとけば、とりあえずウィジェット系は大丈夫なはず!