On-device location track, with debug controls - #552
Open
whes1015 wants to merge 8 commits into
Open
Conversation
|
✅ OpenCodeReview: Review partially complete: 0 finding(s); 7 of 10 selected item(s) failed. |
lowrt
approved these changes
Aug 25, 2026
whes1015
force-pushed
the
location/track-store
branch
from
August 25, 2026 09:13
dbc583e to
b1a25e0
Compare
Platform: ios New(zh-Hant): 背景移動時會將位置記錄在裝置本機,最多佔用 50 MB,超過時自動刪除最舊的紀錄 New(en-US): record the device's movement to on-device storage while in the background, capped at 50 MB with the oldest fixes dropped first
Platform: android New(zh-Hant): 背景移動時會將位置記錄在裝置本機,最多佔用 50 MB,超過時自動刪除最舊的紀錄 New(en-US): record the device's movement to on-device storage while in the background, capped at 50 MB with the oldest fixes dropped first
The native stores own every write, so this side opens the file read-only and does nothing but decode: one owner for the format, one for the 50 MB budget. Measured at 14.19 bytes a fix, which is 3.7 million of them. New(zh-Hant): 儲存空間頁面新增「位置紀錄」項目,可以看到本機移動紀錄佔用多少空間 New(en-US): add a Location track slice to the storage screen, showing what the on-device movement history costs
whes1015
force-pushed
the
location/track-store
branch
from
August 25, 2026 11:47
8537864 to
3eacf1a
Compare
New(zh-Hant): 錯誤回報討論串區分「開發人員」與「工作人員」徽章,官方回覆一眼可辨 New(en-US): bug threads now distinguish a developer badge from a staff badge, so official replies stand out at a glance
New(zh-Hant): 錯誤回報的工作人員名單新增三位成員 New(en-US): three more members join the bug-tracker staff list
New(zh-Hant): 錯誤回報的工作人員名單新增一位成員 New(en-US): one more member joins the bug-tracker staff list
New(zh-Hant): 除錯資訊新增位置軌跡的紀錄筆數與佔用空間 New(en-US): Debug info shows how many fixes the location track holds and what it costs on disk
New(zh-Hant): 除錯資訊新增清除位置軌跡的按鈕,刪除後空間立即歸還 New(en-US): Debug info gains a button that clears the recorded location track and returns the space it held
whes1015
force-pushed
the
location/track-store
branch
from
August 25, 2026 16:37
3eacf1a to
b72a02e
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
這個 PR 做了什麼
背景移動時把位置記錄在裝置本機的壓縮資料庫(原生寫、Dart 只讀),除錯頁可看筆數與清除;另含錯誤回報討論串的工作人員身分區分。
相關 issue
怎麼驗
背景定位(安全關鍵,額外說明)
記錄點刻意放在回報閘門之前——iOS 在
shouldReport之前,Android 在一分鐘節流之前。節流的存在是為了替伺服器省下 429,本機軌跡沒有伺服器要省,而丟掉一筆作業系統費力送來的定位,會在歷史裡留下一個和它自己毫無關係的洞。回報路徑不能被這件事拖垮:兩邊的
record()都吞掉所有例外且不記錄。iOS 走自己的 serial queue,Android 是@Synchronized並在catch (_: Throwable)裡靜默返回。磁碟滿了、資料庫壞了、檔案被保護類別擋住——任何一種都只會讓這一筆軌跡消失,不會讓那一次的位置回報失敗。驗法:授權背景定位後帶著裝置移動,回到 App 看「設定 → 儲存空間 → 位置紀錄」的筆數與位元組是否增長;同時確認位置回報本身仍然正常(伺服器端收得到)。把裝置磁碟塞滿再移動一次,回報應該照常,只有軌跡停止增長。
除錯頁(更多 → 版本號點十下 → Debug info)
Location區塊多一列Track fixes,筆數與位元組並列——比值就是壓縮有沒有在運作,筆數漲而檔案不漲(或反過來)是差值鏈出錯的第一個徵兆。沒有紀錄的裝置整列不出現。Maintenance多一顆紅色的 Clear location track,有確認對話框,措辭寫明不可復原:和它上面的清除快取不同,軌跡沒有任何地方可以重新下載。刪除走原生,不是 Dart 刪檔。 兩邊的 store 都把 database handle 快取整個 process 生命週期,從 Dart unlink 檔案只會讓原生繼續往一個已死的 inode 寫——下次讀取時列會全部回來,空間永遠不歸還,而且沒有任何地方會報錯。所以走既有的
com.exptech.dpip/background_locationchannel 加一個clearTrack,兩邊都在刪除真的跑完之後才回覆,因為呼叫端一返回就會重讀筆數。PRAGMA incremental_vacuum之所以能把空間還回去,是因為auto_vacuum=INCREMENTAL設在建表之前。驗法:記錄幾筆之後看
Track fixes,按下清除,確認筆數歸零、Storage區塊的 Location track 位元組同步縮小,然後再移動一次確認還會繼續記錄。錯誤回報討論串
工作人員與一般回報者在討論串上以徽章區分。
資料格式
各自獨立的
location_track.db,不併進dpip.db——那個檔案屬於 Dart 的sqlite_async,它跨 isolate 維持 WAL 連線池並自行遷移 schema,多一個跨行程寫入者只會製造麻煩。每列存的是與前一列的差值,不是絕對值。SQLite 本來就用一到兩個位元組存小整數、四到六個存大的,所以寫差值等於白拿記錄格式自己的壓縮——沒有私有 blob 要編碼,解碼也只是加法。每 64 列一個絕對值錨點,靠
rowid % 64 == 0認出來,不花任何一個欄位。刪除以整個錨點群組為單位:差值列離開它所依附的錨點就沒有意義,從中間抽掉一列會讓後面每一個位置都平移,而且沒有任何跡象。實測 14.19 bytes 一筆,50 MB 約 370 萬筆。significant-change 一天送幾十到低百筆。
Dart 端
唯讀,這是整個設計。定位在 App 沒有執行時抵達,所以寫入歸原生;超額刪除也歸原生,因為一個由兩邊各自執行的容量上限,等於兩邊都沒有執行。
測過的裝置
LocationTrackStore.clear、Android dex 的clearTrack)檢查清單
tool/check/commits.sh origin/main..HEAD通過—— commit 訊息就是更新日誌,格式見 commit.md
mise exec -- flutter analyze與mise exec -- flutter test通過AppLocalizations,沒有寫死AppSpacing/AppRadius/AppMotion,深色模式看過,文字對比度可接受