ホーム画面に自分だけのウィジェットを置きたいけれど、どこから手をつけていいか迷っていませんか。
この記事を読むと、Androidウィジェットをゼロから作って実機で動かすまでの実践的な手順と、つまずきやすいポイントの回避方法が分かります。
| 項目 | 内容 |
|---|---|
| 実践的な手順 | セットアップからManifest設定、RemoteViewsの作成、更新処理まで具体的に手順化している点。 |
| トラブルシューティング | よくある落とし穴と実際に使える対処法を、経験に基づいて丁寧に解説している点。 |
| 応用のヒント | サイズ可変対応やタップでの操作、データ同期など実用的な拡張アイデアを紹介している点。 |
順を追って進めれば短時間で使えるウィジェットが作れるので、一緒に手を動かして完成させてみませんか。
Android博士最初は戸惑って当然です。わかりやすく段階を追って教えるので安心して進めてくださいね。
Androidで基本のホーム画面ウィジェットを作る手順


ホーム画面ウィジェット作りは、まず全体像をつかむことが大事です。固定表示でシンプルに情報を出す方法と、リストを表示するコレクション方式の二つが多く使われます。どちらを選ぶかで必要なクラスやXMLが変わるので、最初に使い方を決めてしまいましょう。
ここでは実際に動く最小構成を目指して説明します。ポイントはRemoteViewsの制約を理解して、更新ロジックをシンプルに保つことです。慌てずに小さなステップで組み立てると失敗が減ります。
- 固定表示ウィジェット:単純な情報を置くのに最適です。
- コレクションウィジェット:一覧やスクロールが必要なときに使います。



最初は小さなウィジェットから始めると失敗が少なくてできますよ。困ったら落ち着いてログを見て、少しずつ動かしていきましょう。
シンプルな固定表示ウィジェットを作るパターン


シンプルな固定表示ウィジェットは、レイアウトXMLとAppWidgetProviderがあれば作れます。RemoteViewsで使えるビューに注意して、複雑なカスタムビューは避けるのがコツです。
更新はonUpdateやAlarmManager、あるいはWorkManagerで行います。更新タイミングは端末負荷を考えて最小限に抑えるとユーザーに優しいです。
res/layoutにウィジェット用のXMLレイアウトを作る手順
res/layoutにwidget_layout.xmlを作ります。rootはRemoteViewsで使えるLinearLayoutやFrameLayoutにして、TextViewやImageViewを配置します。
各ビューにandroid:idを必ず付けます。更新時にfindViewByIdの代わりにRemoteViews#setTextViewTextなどで参照します。
RemoteViewsで使えない属性やカスタムビューがあるので、実機で表示確認をしてから進めます。
appのパッケージにAppWidgetProviderクラスを作る場所と書き方
- appパッケージ配下にクラスを作成する。AppWidgetProviderを継承したクラスを用意します。
- onUpdateでウィジェットを更新するロジックを記述します。必要ならonReceiveやonEnabledも実装します。
- 更新処理は独立したメソッドにまとめるとテストや再利用がしやすくなります。
res/xmlにウィジェット情報を定義してAndroidManifestに登録する方法
res/xml/widget_info.xmlを作り、minWidthやminHeight、updatePeriodMillis、initialLayoutなどを設定します。
作成したAppWidgetProviderクラスをreceiverとして登録し、meta-dataで先ほどのXMLを参照させます。
updatePeriodMillisを使うか、WorkManagerやAlarmManagerで細かく制御するかを決めます。
一覧を表示するコレクションウィジェットを作るパターン


コレクションウィジェットはリスト表示やスタック表示ができる便利な方式です。RemoteViewsServiceとRemoteViewsFactoryでアイテムごとのRemoteViewsを返す構造になっているので、データ取得とビュー生成を分けて考えると楽になります。
注意点はパフォーマンスと空の状態の扱いです。データが多い場合は適切にページングやキャッシュを入れて、空のときはemptyViewを用意して見た目を整えましょう。
ServiceとRemoteViewsFactoryクラスをapp/srcに作る具体的な構成
| 項目 | 内容 |
|---|---|
| RemoteViewsService | Serviceを継承してRemoteViewsFactoryを返すエントリーポイントになります。 |
| RemoteViewsFactory | データ読み込みと各アイテムのRemoteViews生成を担当します。getViewAtでビューを返します。 |
| 配置場所 | app/src/main/java内のウィジェット用パッケージに置くと管理しやすくなります。 |
res/layoutと行アイテムXMLに一覧表示用レイアウトを作る手順
res/layout/widget_collection.xmlにListViewやStackViewを配置して、android:id=”@+id/list”のようにIDを付けます。
res/layout/widget_item.xmlでアイテムの見た目を定義します。RemoteViewsで使えるシンプルなビューだけを使いましょう。
データがないとき用に空表示レイアウトを用意し、ウィジェットで見栄えを整えます。
AppWidgetProviderでRemoteViewsServiceを接続して更新する実際の流れ
AppWidgetProviderのonUpdateでRemoteViews#setRemoteAdapterを呼んで、ListViewにRemoteViewsServiceを接続します。
setPendingIntentTemplateでアイテムクリックのテンプレートを設定し、RemoteViewsFactory側でfillInIntentを使って個別処理を渡します。
データが変わったらAppWidgetManager#notifyAppWidgetViewDataChangedを呼んでリストを更新させます。
Androidでウィジェットの更新と操作を安定して実装する応用


ウィジェットの更新と操作を安定して作るには、小さな工夫が効きます。周期更新はWorkManagerに任せて、タップ操作はPendingIntentで受け取るのが基本です。
更新処理は短くして例外処理をきちんと入れておくと落ちにくくなります。RemoteViewsの差分更新やsetRemoteAdapterを活用すると無駄な描画を減らせます。
APIごとの振る舞いは端末で必ず確認しておくと安心です。ユニークなWork名やPendingIntentのフラグを適切に使って重複登録や意図しない動作を防いでください。



初めてでも大丈夫です。小さなステップで構成して動くところを早めに作ると理解が進みますし安心して作業できますよ。
WorkManagerでウィジェットを定期更新するパターン


WorkManagerで周期更新を行うと、OSにやさしく確実にウィジェットを更新できます。PeriodicWorkRequestを使い、Constraintsでバッテリーやネットワーク条件を付けると無駄な実行を減らせます。
ユニークなワーク名を指定してExistingPeriodicWorkPolicy.REPLACEなどで重複を防いでください。更新処理はCoroutineWorkerで書くと非同期処理が扱いやすくなります。
Workerクラスにウィジェット更新処理を書く場所と実装のコツ
更新ロジックはWorkerのdoWorkまたはsuspendなdoWork内部に置いてください。重い処理はここで行わないように分割してください。
AppWidgetManagerとComponentNameを取得してRemoteViewsを作成しupdateAppWidgetで反映してください。部分更新を使うと効率的です。
例外をキャッチしてResult.retryやResult.failureを返してください。戻り値でWorkManagerに再実行を任せると安定します。
AppWidgetProviderからWorkManagerを登録して実行する具体的な呼び出し場所
アプリウィジェットが最初に配置されたときにonEnabledでPeriodicWorkRequestをenqueueしておくと安全です。
ユーザーが配置や更新操作をしたときはonUpdateから一時的にWorkManagerに即時ワークをenqueueして最新化を行ってください。
ウィジェットのタップでActivityやサービスを起動するパターン


ウィジェットのタップでActivityやServiceを起動するにはPendingIntentを使います。RemoteViews.setOnClickPendingIntentでビューに紐付けし、getActivityやgetServiceを使い分けてください。
バックスタックを正しくしたいときはTaskStackBuilderを利用してください。サービス起動はAPIレベルやフォアグラウンド要件に注意してIntentを組み立ててください。
RemoteViewsにPendingIntentを作成してセットする具体的なコード配置
起動先のActivityやServiceのIntentを作成してください。必要なExtrasはここでセットしておくと扱いやすくなります。
PendingIntent.getActivityやgetServiceでPendingIntentを作成し、適切なフラグを指定してください。リクエストコードはユニークにしてください。
RemoteViews.setOnClickPendingIntentでビューIDにPendingIntentを割り当ててください。ウィジェット側での反応が素早くなります。
Androidバージョン差に対応したPendingIntentフラグの付け方と確認方法
| 項目 | 内容 |
|---|---|
| API31以上 | 明示的にFLAG_IMMUTABLEかFLAG_MUTABLEを指定してください。通常は変更しないならFLAG_IMMUTABLEを推奨します。 |
| API30以下 | 従来のフラグで問題ありませんが互換性を考えてFLAG_UPDATE_CURRENTなどを適切に使ってください。 |
| 確認方法 | 実機でタップ動作とバックスタックを確認し、LogやADBでPendingIntentが期待どおり呼ばれるかチェックしてください。 |
よくある質問


- ウィジェットを作ったのにホーム画面に表示されないのはなぜ
まずウィジェットのinfo XMLとマニフェストのreceiver登録が正しいか確認してください。meta-dataで指定するリソース名のミスやreceiverに必要な属性がないと表示されません。アプリがインストール済みで有効になっているかも見てください。
- 頻繁にデータを更新したいがバッテリーを節約するにはどうする
無闇に短い間隔で更新を繰り返すのは避けてください。更新はユーザー操作トリガーやWorkManagerなどのバッテリーに優しいスケジューラでまとめて行うのがおすすめです。可能なら差分取得やローカルキャッシュで通信を減らしてください。
- ウィジェットのサイズ変更に対応するにはどうする
AppWidgetProviderのonAppWidgetOptionsChangedでサイズ変化を受け取りレイアウトを切り替えてください。appwidget-provider XMLでresizeModeやminWidth,minHeightを適切に設定することも大切です。エミュレータや実機で複数のサイズを実際に試してください。
- マニフェストやXMLでやりがちなミスは何
meta-dataのresource指定ミスやファイル名のtypoが多いです。Android12以降はreceiverのexported属性の扱いにも注意してください。意図したintent-filterが正しく書かれているかを必ず確認してください。
- デバッグの効率を上げるコツはある
まずlogcatで例外やスタックトレースを確認して原因を絞ってください。エミュレータでウィジェットを追加してonUpdateやonReceiveが呼ばれるかログを追うと早く見つかります。更新処理は小さな単位で動作確認すると原因追及が楽になります。
まとめ


ここまででホーム画面ウィジェットを作るための基本がそろいました。AppWidgetProvider(ウィジェットの状態を扱うコンポーネント)を用意し、ウィジェットレイアウトをXMLで作ってAppWidgetProviderInfoに登録すればまず動くようになります。マニフェストや権限の設定も忘れずに確認してください。
現場でよく役立つコツは、更新処理を軽くすることです。定期更新はWorkManager(バックグラウンド処理を安定させる仕組み)を使い、onUpdateでは最小限の差分だけ反映するようにするとバッテリー消費とバグが減ります。画像やネットワークリクエストは非同期で分割して扱うと安定します。
実機でウィジェットを置いてサイズやレスポンシブ挙動を確かめながら微調整してください。小さな改善を積み重ねると使い勝手がぐっと良くなります。気軽に試して楽しんでください。
