離線語音照護 App 實錄:從家屬痛點到上架 Google Play

重點摘要
  • 一個家屬朋友試過我的照護工具、也想用,卻在聽到「這是我自己做的」之後放棄——阻力不是難用,是不想麻煩我。真正的解法是一個「非人情的入口」:上架商店,他自己下載、自己用、全程不用找我。
  • 要不要辨識手寫白板,我沒用猜的,用的:實測手寫中文 OCR 只有六成、還錯在關鍵詞;改用手機本機語音辨識,失效模式安全很多。
  • 整支 App 完全離線、資料只存在手機——這同時避開了醫療個資責任,也把「隱私」變成了讓朋友願意用的「信任」。
  • 上架 Google Play 是另一場關卡:簽章金鑰、三星 Auto Blocker、AAB、以及個人新帳號要「封閉測試 12 人 × 14 天」才能公開。

這篇是一段完整的實錄:從「該不該把我自架的 ERP 硬塞給別的家庭」開始,到最後做出一支離線語音照護記錄 App、送上 Google Play 審查。我想留下的不是「我做了一個 App」,而是過程中幾個真的改變決策的判斷——尤其是「用量不用猜」和「真正的障礙常常是人、不是技術」這兩件事。這也是我一直在講的把 AI 當一個新同事、自己動手解痛點的一個具體例子。

🧭 本文導覽

起點:朋友試過卻不用,原因不是難用

我原本有一套自架的照護記錄流程(拍白板、辨識、寫進我自架的系統),自己家在用。一個同樣在照顧家人的朋友試過、也想用。但當他知道「這是 Tom 自己做的」之後,他就放棄了——不是覺得難用,也不是不信任,是「不想一直麻煩我」

這句話比任何技術問題都重要:他放棄的原因,連「好不好用」都還沒輪到。所以真正該解的,不是把工具做得更炫,而是給他一個不需要透過我的入口——一個他自己能從商店下載、自己更新、壞了也不用找我的東西。「上架」在這裡不是虛榮,而是把「人情負擔」歸零的唯一辦法。

為什麼不把 ERP 硬塞給家庭

最直覺的做法是「把我自架的系統開放給他用」。但只要誠實列一下對方要做的事,這條路就死了:自架伺服器、申請雲端 API 金鑰、填一堆設定、維護資料庫。這些對一個只想記錄長輩狀況的家庭來說完全不可能。

企業級工具的價值,在企業級的維運能力上才成立。硬塞給家庭,只是把我的技術債變成別人的門檻。所以方向很清楚:要做一個家庭自己就能用完的東西——不自架、不用金鑰、裝了就能用。

關鍵決策:用「量」不用「猜」

第一個技術岔路:要不要用相機拍手寫白板、自動辨識成文字?直覺上很酷。但我沒有憑感覺決定,而是拿真實的手寫照片實測,再對照已知的正確內容算準確率。結果很殘酷。

辨識方式(離線、手機端) 實測結果 對照護紀錄
手寫中文 OCR 約 61–67%,且錯在關鍵詞 危險:把重要的字認成形狀相近的常見字,會誤導醫生
語音轉文字(國語) 日常詞近乎全對,只錯冷僻專有名詞 安全:偶爾漏字,但不會無中生有講錯

兩者的差別不只是分數,而是失效模式:OCR 會把 A 認成無關的 B(危險);語音頂多把一句話少講半句(安全,人一眼就補回來)。對「錯的資料比缺的資料更危險」的醫療紀錄場景,這個差別決定一切。所以最後選語音,而且是手機本機離線辨識——不是憑感覺,是量出來的。

這是我一直提醒自己的一條線:能量的就別猜。一個下午的實測,幫我省掉一整段做錯方向的開發。

離線優先:把隱私變成信任

整支 App 的核心約束是:完全離線、資料只存在使用者的手機、沒有帳號、沒有伺服器。語音辨識也在手機本機完成,錄音不上雲。

這個決定有兩個好處疊在一起。第一,健康照護資料在法規上很敏感,不收集、不上傳,就沒有保管責任。第二,也是更關鍵的——它正好解掉了最開始那個朋友的顧慮。當一個 App 可以誠實地說「你的資料永遠不會離開你的手機,連我都看不到」,「隱私」就從一句口號變成了「信任」。一個素人做的東西,反而因為什麼都不收而更讓人安心。

代價是:跨裝置分享不能靠雲端同步,只能匯出成檔案、由使用者自己選管道傳。但對這個場景,這個取捨是對的。

這支 App 做了什麼

用一句話描述使用流程:對著手機講一句今天的狀況,它在本機轉成文字(自動加標點),你看一眼、需要才改,就存好了。例如講「今天精神穩定,午餐吃一半,下午走一走,晚上睡得好」,幾秒後就是一筆帶日期的紀錄。

  • 語音記錄:本機離線辨識,可分多次接續成一筆,可隨時編輯或刪除。
  • 加照片:每筆可選擇性附照片,記錄者在列表就看得到。
  • 給醫生的整理:按日期分組的 review 畫面,也能匯出成單一 HTML 檔,任何手機瀏覽器直接開,不必裝 App。
  • 多位家人共用:把某位的紀錄匯出成檔、傳到另一支手機匯入合併;帶去看診的人手機上就有完整紀錄。
  • 多位病人:預設單一被照顧者時介面極簡,有需要才顯示切換——複雜度跟著資料長,不打擾單一使用者。

技術上是 Flutter 一份程式碼、手機端 whisper 語音模型、SQLite 本機儲存。但這些都不是重點——重點是每一個功能都對應一個真實的使用回饋(「記錄者卻看不到照片」「每次錄音把上次蓋掉」「醫生沒空一張張翻照片」),而不是我拍腦袋想出來的。

上 Google Play 的真實關卡

把 App 做完只是一半。「上架」本身是另一場行政與工程的關卡,很多是文件上不會第一時間告訴你的。以下是我實際踩過的:

關卡 重點 / 我踩到的坑
正式簽章金鑰 要建一把 upload key 並永久保存(弄丟=更新麻煩)。測試金鑰跟正式金鑰不同,換金鑰會導致舊版蓋不上去。
版本號(versionCode) 每次更新一定要 +1,否則「蓋裝更新」會失敗、只能移除重裝(連帶重下模型)。
AAB 格式 Play 只收 .aab(不收 .apk),而且會依機型最佳化,實際下載比你打包的還小。
三星 Auto Blocker 新款三星預設擋掉所有非商店來源的安裝——sideload 的 APK 一律裝不了,要先關掉。這也是「為什麼要上架」的另一個理由。
測試軌道 內部測試(快、給自己人、不需審查)、封閉測試、正式版是不同軌道,人數與 AAB 要分別設定。
封閉測試 12 人 × 14 天 個人新帳號要「至少 12 位測試者持續 opt-in 滿 14 天」才能申請公開正式版。越早湊滿 12 人,14 天越早跑完。
送審宣告 隱私權政策(要公開網址)、資料安全問卷、內容分級、目標對象、廣告聲明等,全部填完才會出現「送出審查」。新 App 第一版還要等 Google 審查。

其中最容易讓人以為「壞掉」的,是測試者一直看到「App not available」。九成不是設定錯,而是:裝置登入的帳號跟受邀的帳號對不上、或版本還在審查/鋪設中。另外那個「隱私權政策要一個公開網址」的要求,剛好可以用自己的部落格或子網域掛一頁解決。

📌 後記更新(2026-07-26)
文章發佈後這兩天,我把宣傳影片、商店截圖做完,也真的撞上了「個人開發者上架」才會遇到的三道關卡。把最耗神、最違反直覺的部分補在這裡——都是查證過的事實,不是猜測。

上架後才發現:封閉測試「12 人 / 14 天」到底怎麼算

個人開發者帳號要發正式版,得先在封閉測試湊滿 12 名「選擇參加(opted-in)」的測試者,並連續維持 14 天。最違反直覺的一點:它數的是「opt-in 的 Google 帳號」,不是「下載次數」,而且你自己的開發者帳號不列入。

我實際踩到的狀況:我用自己、老婆、朋友、另一支手機的不同帳號,一共裝了 4 支,但 Play Console 只顯示「目前已有 3 名測試人員選擇參加」。原因就是——擁有這個開發者帳號的那個帳號不算。

4 支下載 → 只算 3 個
① 我(開發者帳號)🚫 不算
② 老婆✅ 算
③ 朋友✅ 算
④ 另一支不同帳號✅ 算
合計:算 3 / 需要 12
條件 會被算進 12 人嗎?
你自己的開發者(擁有者)帳號🚫 不算
只是拿到 APK 或直接安裝、沒走 opt-in 連結🚫 不算
同一個 Google 帳號、裝在多支手機⚠️ 只算 1
別人的真 Gmail + 在你名單上 + 走 opt-in 連結加入✅ 算 1

還有一個容易誤會的點:那個計數會延遲,常常慢半天到一天才更新,不是即時。整條上架流程長這樣:

✓ 發布封閉測試版本 湊滿 12 名 opt-in 測試者 連續維持 14 天 申請發布正式版

targetSdk 是「移動靶」:Play 每年把門檻往前推

Google Play 每年會把要求的最低 targetSdk 往前推一級,規則是「App 的 targetSdk 必須落在最新 Android 發布後一年內」。所以你今天上架符合,明年同一支就會收到「請更新目標 API 級別」的警告——這是常態,不是你的 App 有問題。

期限 最低 targetSdk 對應 Android
2025-08-31API 35Android 15
2026-08-31API 36 ← 我這次要升的Android 16

我用的 Flutter 3.27(2024-12 版)預設 targetSdk 還停在 35,所以第一版上架就是 35,自然收到警告。修法其實只有兩行——在 android/app/build.gradle 把預設值蓋掉、寫死 36(前提是本機已裝好 Android SDK Platform 36):

// android/app/build.gradle
android {
    compileSdk = 36        // 原本是 flutter.compileSdkVersion (Flutter 3.27 = 35)
    defaultConfig {
        minSdk = 24        // 語音套件需要,不動
        targetSdk = 36     // 原本是 flutter.targetSdkVersion (= 35)
    }
}

改完把版本號的 versionCode 遞增(Play 每次上傳都必須 +1),重新 flutter build appbundle,再傳一版即可。教訓:上架不是一次性的,targetSdk 每年都要回來補一次。

宣傳影片別做成 PPT:要用「真實 App 畫面」

商店的宣傳影片,我一開始做成投影片卡片(標題 + 條列),看起來很「乾淨」,但一放上去就覺得不對——使用者要看的是這支 App 長什麼樣、怎麼操作,不是一份簡報。最後改成「每一幕都是真手機截圖當主角 + 旁白字幕」,並把六大功能(語音記錄、轉文字、加照片、按日期整理、匯出換手機、多位家人、給醫生看)全部涵蓋,說服力完全不同。

版本 做法 結果
第 1 版簡報卡片(標題+條列)🚫 像 PPT,看不到 App
第 2 版真手機截圖當主角 + 旁白⚠️ 對了,但只涵蓋 4 個功能
第 3 版真畫面 + 六大功能全覆蓋✅ 這版放商店

還有一個小坑:Play 商店的「宣傳影片」欄位接受 YouTube「不公開(Unlisted)」,但「私人(Private)」不行——設成私人的話,商店讀不到影片。想不公開分享又要能放商店,選「不公開」才對。

幾個我學到的事

  • 真正的障礙常常是人,不是技術。朋友不用,不是功能問題,是人情負擔。看懂這個,方向才會對。
  • 能量的就別猜。OCR 六成 vs 語音的實測,一個下午就把錯方向擋掉。
  • 離線可以是一個功能,不只是限制。「資料不出門」在隱私敏感的場景,反而是最強的賣點與信任基礎。
  • 把 App 做完只是一半。簽章、版本號、測試軌道、12 人 × 14 天——上架是另一條要一步步走完的路。
  • 每個功能都該對應一個真實回饋。「記錄者看不到照片」「語音會蓋掉上一段」這類回饋,比任何我拍腦袋的點子都值錢。

目前這支 App 已經把公開上架需要的素材與宣告全部送審,剩下的是等審查、湊滿 12 位測試者。技術活基本結束,行政流程在跑。對我來說,這趟最大的收穫不是多了一個 App,而是又一次驗證了同一件事:找到一個真實的痛點,老實地量、老實地做,然後把「用得到的人」擺在「我做得爽不爽」前面。

留言

發佈留言

發佈留言必須填寫的電子郵件地址不會公開。 必填欄位標示為 *