Keep the mode while network fixes arrive between GNSS fixes

Network fixes have no speed. While driving, one of them could switch the
mode to DWELL until the next GNSS fix. Rename DWELL to "Stationary",
because "Stopped" reads as if tracking is off.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
AuthorKonata <konata@posteo.jp>
Date
Commitb82d3cd91dca8cd354a2f608893300ff63c9ae76
Parente8b31cb
4 files changed, 18 insertions(+), 4 deletions(-)
▾Mandroid/app/src/main/java/org/opentracker/SamplingPolicy.kt
@@ -41,12 +41,14 @@ class SamplingPolicy {
private val kept = ArrayDeque<Fix>()
private val lastKept get() = kept.lastOrNull()
private var lastFix: Fix? = null
private var lastGnssMs = Long.MIN_VALUE
private var stillSinceMs = 0L
private var slowSinceMs: Long? = null
/** Updates the mode and returns whether the fix is worth uploading. */
fun onFix(fix: Fix): Boolean {
tick(fix.timeMs)
if (fix.speed != null) lastGnssMs = max(lastGnssMs, fix.timeMs)
updateMode(fix, speedOf(fix))
lastFix = fix
return keep(fix)
@@ -101,7 +103,8 @@ class SamplingPolicy {
stillSinceMs = now
}
}
mode != Mode.DWELL -> {
// Network fixes have no speed. While GNSS still reports, they cannot tell a stop.
mode != Mode.DWELL && (fix.speed != null || fix.timeMs - lastGnssMs >= LATE_MS) -> {
mode = Mode.DWELL
stillSinceMs = now
slowSinceMs = null
▾Mandroid/app/src/main/res/values-de/strings.xml
@@ -61,6 +61,6 @@
<string name="notification_title">Dein Standort wird geteilt</string>
<string name="mode_vehicle">Fährt</string>
<string name="mode_walk">Unterwegs</string>
<string name="mode_dwell">Angehalten</string>
<string name="mode_stationary">Steht</string>
<string name="mode_dwell">Steht</string>
<string name="mode_stationary">Ruht</string>
</resources>
▾Mandroid/app/src/main/res/values/strings.xml
@@ -62,7 +62,7 @@
<string name="notification_title">Sharing your location</string>
<string name="mode_vehicle">Driving</string>
<string name="mode_walk">Moving</string>
<string name="mode_dwell">Stopped</string>
<string name="mode_dwell">Stationary</string>
<string name="mode_stationary">Still</string>
<string name="url_hint" translatable="false">https://track.example.com</string>
</resources>
▾Mandroid/app/src/test/java/org/opentracker/SamplingPolicyTest.kt
@@ -31,6 +31,17 @@ class SamplingPolicyTest {
assertEquals(Mode.WALK, p.mode)
}
@Test
fun network_fixes_between_gnss_fixes_keep_the_mode() {
val p = SamplingPolicy()
p.onFix(fix(0, speed = 16f))
p.onFix(fix(3_000, 30.0, speed = null, acc = 40f))
assertEquals(Mode.VEHICLE, p.mode)
// Indoors, GNSS goes silent and network fixes alone have to show the stop.
p.onFix(fix(6 * min, 30.0, speed = null, acc = 40f))
assertEquals(Mode.DWELL, p.mode)
}
@Test
fun stopping_turns_gnss_off_after_dwelling() {
val p = SamplingPolicy()