Google Apps Script(GAS)で管理しているスプレッドシートの予定データを、 Android アプリ側に定期的に取り込み、 ① テキストのリスト型ウィジェット と ② 画像として描画する1日タイムテーブル画像ウィジェット の二つの形で ホーム画面に表示するためのアプリです。
このアプリは、予定のソースをスプレッドシートに一本化しつつ、 スマホ側では「見る専用」に集中できる環境を作ることを目的にしています。 GAS がスプレッドシートから予定を JSON に変換し、 Android アプリがその JSON を取得してローカルに保存。 そこから 2 種類のホーム画面ウィジェットに描画します。
リスト型ウィジェットは、今日と明日の予定を縦に並べて確認するためのもの。 タイムテーブル画像ウィジェットは、1日を0〜24時の縦軸にした画像を Bitmap/Canvas で描画し、視覚的に「空き時間」と「詰まっている時間」を 一発で把握できるようにする試みです。
スプレッドシートを GAS で Web API 化し、 Android アプリがその API から JSON を取得します。 取得した予定はローカルDBに保存し、 AppWidgetProvider がリスト型ウィジェットと 1日タイムテーブル画像ウィジェットの両方に同じデータを配布する構成です。
[{ date, start, end, title, type }, ...] の JSON にして返す。
予定の元データは Google スプレッドシートにまとめ、
GAS 側で doGet() を実装して JSON を返す Webアプリにしました。
これにより、ブラウザでもアプリでも同一の予定データを参照できます。
function doGet(e) {
const rows = sheet.getDataRange().getValues();
const items = rows.slice(1).map(r => ({
date: r[0], start: r[1], end: r[2], title: r[3], type: r[4]
}));
return ContentService
.createTextOutput(JSON.stringify(items))
.setMimeType(ContentService.MimeType.JSON);
}
「リスト型ウィジェット」は、今日と明日の予定だけ を縦に並べる コレクションウィジェットです。AppWidgetProvider から RemoteViewsService を紐づけ、Room から予定を読み出して 1 行ずつ RemoteViews を返しています。
dao.eventsBetween(todayStart, tomorrowEnd)
.sortedBy { it.startAt }
.map { toWidgetItem(it) }
「1日タイムテーブル画像ウィジェット」は、
背景に 0〜24 時の時間軸を描き、その上に予定ブロックを長方形として重ねる
画像を生成します。
Bitmap.createBitmap() でキャンバスを作り、
1マス30分などのスケールで矩形を塗りつぶしていきます。
val totalMinutes = 24 * 60
val yStart = height * (eventStartMinutes / totalMinutes.toFloat())
val yEnd = height * (eventEndMinutes / totalMinutes.toFloat())
GAS との同期は WorkManager or 自前の AlarmManager で定期実行し、
成功時に notifyAppWidgetViewDataChanged() や
画像再描画処理を呼んで、2種類のウィジェットを更新します。
深夜0時のタイミングには日付切り替え用の更新も走らせ、
「昨日の予定が残ったウィジェット」が画面に残らないようにしています。
最初はリスト型ウィジェットだけを作り、 文字で予定を確認していましたが、 実験として 1 日のタイムテーブルを画像で描画したところ、 「この時間帯は絶対に埋めたくない」など感覚的な判断が しやすくなる手応えがありました。
・GAS 側のレスポンス遅延や、ネットワーク無しのときの扱い ・ウィジェットのサイズが小さい端末での可読性 ・タイムテーブル画像の解像度と描画コストのバランス といった点にまだ課題があります。
GAS から予定を同期し、リスト型ウィジェットと 1日タイムテーブル画像ウィジェットが更新される一連の流れを 撮影したデモ動画です。
widget アプリは、GAS を中心に据えた 「予定の一元管理」の最初の一歩です。 将来的には、Rootine の遂行率や EEG の集中度、 タスクの重要度なども同じ GAS/シートに集約し、 ホーム画面のウィジェットが日々のダッシュボードになることを目指しています。
同期の安定化・ウィジェットの見やすさ・他データとの統合の 3つの観点で改善を進めます。
GAS と Android ウィジェットを組み合わせることで、 「自分だけの予定サーバ」と「好きな形の表示」をつなげられることが分かりました。 スプレッドシートという身近なツールを起点にしつつ、 ホーム画面にはかなり自由度の高い UI を出せるのが面白いと感じています。
一方で、ウィジェットは制約も多く、 キャッシュ戦略や描画コスト、更新タイミングなどを丁寧に設計しないと すぐに「重い」「バッテリーを食う」アプリになってしまうことも学びました。 この経験は、今後 Rootine や EEG 関連のウィジェットを作るときにも 活かしていきたいです。