Files
jrshikoku/docs/widget-overview.md

5.9 KiB
Raw Blame History

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: 180000030分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 グローバルナビゲーション refcreateNavigationContainerRef

ディープリンク設定

intentFiltersapp.json

[
  { "action": "VIEW", "data": [{"scheme": "jrshikoku"}],
    "category": ["BROWSABLE", "DEFAULT"] },
  { "action": "VIEW",
    "data": [{"scheme": "jrshikoku", "host": "open", "pathPrefix": "/felica"}],
    "category": ["BROWSABLE", "DEFAULT"] }
]

Linking configApps.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 等のネイティブヘルパーは除去済み

既知の不整合・注意点

  1. JR_shikoku_train_strange: app.json に定義済みだが widget-task-handler に専用描画分岐がない(nameToWidget にもマッピングなし)
  2. HelloWidgetPreviewScreen.tsx: HelloWidget を import しているが該当ファイルが存在しない(死コード)
  3. testNFCsettings.tsx: スナップショット保存するが requestWidgetUpdate を呼ばないためウィジェット未同期
  4. ディープリンク: intentFilters は app.json に追加済みだがネイティブビルド未実施のため未検証