feat(eew): announce predicted intensity before warning sound - #546
feat(eew): announce predicted intensity before warning sound#546archie0732 wants to merge 4 commits into
Conversation
|
記得要 rebase before merging |
New(zh-Hant): 強震監視器會先朗讀地震預估震度,再播放警示音 New(en-US): the seismic monitor announces predicted intensity before the warning sound
Platform: android
ad76de1 to
1f489c4
Compare
|
`flutter_tts` ships no Swift Package Manager support, and the iOS build has none of the CocoaPods setup it therefore needs (README → 參與開發: "iOS 已改用 Swift Package Manager,不需要 CocoaPods"). Flutter says so during every build and adds that it "will become an error in a future version" — until then it quietly reintroduces a Podfile through a transitive dependency, which is the half of that warning nobody reads. So the two calls it was providing are owned here, as the eleventh iOS plugin and the thirteenth Android channel: `AVSpeechSynthesizer` on one side, `android.speech.tts.TextToSpeech` on the other, thirty lines each. `SpeechService` was already an interface with the package behind a single implementation, so the announcement controller, the notification gate and their tests are untouched. Both sides answer a `speak` exactly once and answer it normally when a later phrase supersedes it: latest-report-wins is this caller's contract, so a cut-off phrase is the expected path rather than an error. The Android half replies on the main thread — `UtteranceProgressListener` runs on a binder thread, and a `MethodChannel.Result` answered from there is a crash rather than a warning — and holds the first call until the engine finishes binding, because the announcement that matters most is the first one.
|
@archie0732 另外剛創 https://github.com/ExpTechTW/flutter_tts 可以開PR |
maplibre_gl 那條路我沒想到,fork 確實是這個 repo 既有的做法。上游那三個 PR 從 5 月放到現在都沒合,等作者應該是等不到了。 不過在你留言之前我已經先改成 app 自有的 channel 了(c537a540),所以想先把兩個方案的現況擺出來,你決定要哪一個我照做。 現在這版(自有 channel) com.exptech.dpip/speech,SpeechPlugin.swift + SpeechChannel.kt,兩邊各約 30 行,跟現有的 CompassPlugin / ScreenWakeChannel 同一個模子 保留完整功能,之後要調語速那類的不用再寫原生 另外不論走哪條路,我沒有 Mac,iOS 端的執行期行為(語音真的出得來、audio session 不會蓋掉別的 app)都要麻煩有裝置的人幫忙看一下。 你說走 fork 我就把 c537a54 拿掉改成 git 相依,覺得自有 channel 可以就維持現狀。 |
|
等 @whes1015 起床再看方案說法 經過測試iOS模擬器有說話 預估所在地震度 |
|
五弱 五強 六弱 六強的部份,有需要加「等級」嗎?因為地牛是直接五弱 這樣感覺贅字也比較少 |
這個 PR 做了什麼
在強震監視器顯示於前景時,以系統 TTS 朗讀最新 EEW 預估震度,朗讀完成後才播放原有警示音;新報會中斷舊播報並改讀最新結果。
相關 issue
怎麼驗
手動測試(Android Emulator,x86_64)
執行:
進入「雷達」,切換為「強震監視器」,確認四項:
MethodChannel.Result只回一次)iOS 尚未驗證:開發環境為 Windows,沒有實機或模擬器。
SpeechPlugin.swift只經過 CI 編譯。自動測試
tool/check/commits.sh upstream/main..HEAD:4 commits 通過tool/dev/analyze.sh:flutter analyze無問題tool/check/l10n.sh、layering.sh、storage.sh、notification_sounds.sh、tooling.sh完整
tool/dev/test.sh在 Windows 上有 56 個失敗,其中 55 個集中在test/tool/*(Git Bash 把 Windows 路徑轉成D:GitHub...),另一個是test/shared/semantics_overlay_portal_test.dart,該檔案本次未修改且在 CI 上為綠。安全關鍵的部分
播報只在前景、可見的監視器上發生;背景與終止狀態的推播完全不經過這個閘門。TTS 引擎不存在或卡住時有兩層逾時(控制器 8 秒、通知閘門 10 秒),任何情況下都不會讓警示通知被無限期壓住 —— 最壞情況是警報比平常早響,不會晚。feed 進入 stale/offline 時直接停止播報。
其他兩則 commit
ci(android)—Build Android先前為紅,原因與本功能無關:這個 PR 從 fork 開,pull_request事件拿不到 repository secrets,Decode keystore於是寫出空的 keystore 與四個值全空的key.properties,Gradle 在packageRelease讀不到 keystore 而失敗。同顆 commit 的 iOS job 是綠的,因為它以--no-codesign建置。修法是把簽章從這個 job 拿掉:可上傳的簽章成品本來就由release.yml在 push 到 main 時產生,而android/app/build.gradle.kts在key.properties不存在時會退回 debug signing。refactor(eew)—flutter_tts不支援 Swift Package Manager,而這個專案的 iOS 端不使用 CocoaPods(README → 參與開發)。Flutter 每次建置都會警告並說明「will become an error in a future version」,在那之前它會透過相依關係悄悄把 Podfile 帶回來。因此改為 app 自有的com.exptech.dpip/speechchannel,兩邊各三十行;SpeechService原本就是介面,上層的控制器、閘門與測試一行未改。pubspec.yaml與pubspec.lock現在與 main 完全相同,這個 PR 不再引入任何相依套件。檢查清單
tool/check/commits.sh origin/main..HEAD通過flutter analyze通過;新增測試全數通過AppLocalizations,沒有寫死(含新增的粵語app_yue.arb)