5.9 KiB
5.9 KiB
Android ウィジェット機能 概要
ウィジェット一覧(app.json 登録済み: 4種)
| 名前 | ラベル | 概要 |
|---|---|---|
JR_shikoku_train_info |
列車遅延速報EX | GAS API から遅延データ取得→表示 |
JR_shikoku_train_strange |
怪レい列車 | app.json に定義あるが専用レンダリング分岐なし |
JR_shikoku_info |
運行情報 | app.json に定義あり。AsyncStorage の widgetType/{id} で Info_Widget に手動切替可能 |
JR_shikoku_apps_shortcut |
クイックアクセス | FeliCa IC カード残高表示 + タップでスキャン画面へディープリンク |
全ウィジェット共通: updatePeriodMillis: 1800000(30分)、resizeMode: "horizontal|vertical"
ファイル構成
| ファイル | 役割 |
|---|---|
components/AndroidWidget/TraInfoEXWidget.tsx |
遅延速報EXウィジェットUI + データ取得 |
components/AndroidWidget/InfoWidget.tsx |
運行情報ウィジェットUI + データ取得 |
components/AndroidWidget/FelicaQuickAccessWidget.tsx |
クイックアクセスウィジェットUI + 残高データ取得 |
components/AndroidWidget/widget-task-handler.tsx |
ウィジェットイベントハンドラ(全ウィジェット共通) |
components/AndroidWidget/HelloWidgetPreviewScreen.tsx |
死コード(HelloWidget が存在しない) |
components/Settings/WidgetSettings.tsx |
ウィジェット設定画面(ウィジェットIDごとに表示タイプ切替) |
index.ts |
registerWidgetTaskHandler() でハンドラ登録(Android のみ) |
app.json |
ウィジェットプラグイン設定 + intentFilters |
constants/storage.ts |
FELICA_LAST_SNAPSHOT キー定義 |
lib/rootNavigation.ts |
グローバルナビゲーション ref(createNavigationContainerRef) |
ディープリンク設定
intentFilters(app.json)
[
{ "action": "VIEW", "data": [{"scheme": "jrshikoku"}],
"category": ["BROWSABLE", "DEFAULT"] },
{ "action": "VIEW",
"data": [{"scheme": "jrshikoku", "host": "open", "pathPrefix": "/felica"}],
"category": ["BROWSABLE", "DEFAULT"] }
]
Linking config(Apps.tsx)
const linking = {
prefixes: ["jrshikoku://"],
config: {
screens: {
positions: { screens: { Apps: "positions/apps" } },
topMenu: {
screens: {
menu: "topMenu/menu",
setting: {
screens: {
settingTopPage: "topMenu/setting",
FelicaHistoryPage: "topMenu/setting/FelicaHistoryPage",
},
},
},
},
information: "information",
},
},
};
ウィジェットタップ → Felica スキャン画面 フロー
FelicaQuickAccessWidget タップ
→ clickAction="OPEN_URI", uri="jrshikoku://open/felica"
→ Android OS が intentFilter マッチでアプリ起動
→ App.tsx: Linking.getInitialURL() or addEventListener("url")
→ routeFromUrl(url): "open/felica" を検知
→ openFelicaPage(): rootNavigationRef.navigate("topMenu" > "setting" > "FelicaHistoryPage")
※ nav 未 ready なら 250ms × 最大8回 retry
→ FelicaHistoryPage で NFC スキャン画面表示
→ scan() 成功後:
- UI に結果表示
- AS.setItem(FELICA_LAST_SNAPSHOT, { balance, idm, systemCode, scannedAt })
- requestWidgetUpdate("JR_shikoku_apps_shortcut") でウィジェット即時更新
widget-task-handler イベントディスパッチ
widgetAction:
WIDGET_ADDED / WIDGET_UPDATE / WIDGET_CLICK / WIDGET_RESIZED
→ widgetName === "JR_shikoku_apps_shortcut"
→ getFelicaQuickAccessData() → FelicaQuickAccessWidget 描画
→ それ以外
→ AS.getItem(`widgetType/${widgetId}`) でユーザー設定判定
- "Info_Widget" → getInfoString() → InfoWidget
- "JR_shikoku_train_info" → getDelayData() → TraInfoEXWidget (デフォルト)
WIDGET_DELETED
→ AS.removeItem(`widgetType/${widgetId}`)
残高スナップショット保存箇所
| ファイル | トリガー | ウィジェット更新 |
|---|---|---|
FelicaHistoryPage.tsx (L159) |
handleScan() 成功 |
✅ requestWidgetUpdate あり |
settings.tsx (L63) |
testNFC() 成功 |
⚠️ なし(次回定期更新まで反映されない) |
保存形式: { balance, idm, systemCode, scannedAt } → AsyncStorage キー felicaLastSnapshot
通知タップ → ナビゲーション(useNotifications.tsx)
| 判定キー | アクション | ナビゲーション先 |
|---|---|---|
遅延速報ex, trainfoex, tra_info_ex |
delay-ex |
topMenu/menu → ActionSheet JRSTraInfo |
怪レい列車bot, strange_train |
strange-train |
positions/Apps |
運行情報, information |
information |
information タブ |
チャンネルID / categoryIdentifier / data.category を優先判定、フォールバックで通知テキストの正規化マッチング。
ネイティブモジュール(expo-felica-reader)
- エクスポート:
scan()のみ - 戻り値:
FelicaCardInfo { idm, balance, systemCode, history[] } - Android:
NfcF(FeliCa) リーダーモード、サービスコード0x090Fで残高+履歴読取 launchApp等のネイティブヘルパーは除去済み
既知の不整合・注意点
JR_shikoku_train_strange: app.json に定義済みだが widget-task-handler に専用描画分岐がない(nameToWidgetにもマッピングなし)HelloWidgetPreviewScreen.tsx:HelloWidgetを import しているが該当ファイルが存在しない(死コード)testNFC(settings.tsx): スナップショット保存するがrequestWidgetUpdateを呼ばないためウィジェット未同期- ディープリンク:
intentFiltersは app.json に追加済みだがネイティブビルド未実施のため未検証