diff options
| author | Claude <noreply@anthropic.com> | 2026-06-04 23:34:44 +0000 |
|---|---|---|
| committer | Claude <noreply@anthropic.com> | 2026-06-04 23:34:44 +0000 |
| commit | 23e72f39ced0e051d9803415efde3729a9fd433a (patch) | |
| tree | b09c2269ff20df7eb75676491599e91c9f5f8e54 /android-app | |
| parent | 75c61c2b5b3fbda316dc4e82b6027d80ff7132d3 (diff) | |
Fix location-retention regression: stop GPS when backgrounded and idle
The previous fix (48ae3b0) dropped to ECONOMY (5 s interval) on app
pause, but never stopped location requests. The fusedLocationClient
continued polling indefinitely in the background even with nothing
recording or anchor-watching — accessing location without any need.
Fix:
- Add PowerMode.NONE to represent "no updates in flight"
- Add ACTION_STOP_UPDATES to LocationService: calls
stopLocationUpdatesInternal() and parks _currentPowerMode at NONE
- Guard startLocationUpdatesInternal() against PowerMode.NONE so a
stray setPowerMode(NONE) call can never request zero-interval updates
- Change _currentPowerMode initial value from FULL to NONE (accurate:
no updates are running at process start)
- throttleLocationIfIdle() now sends ACTION_STOP_UPDATES instead of
ACTION_START_ECONOMY; the existing restoreLocationMode() on onResume
already sends ACTION_START_ECONOMY which transitions NONE→ECONOMY
correctly since NONE != ECONOMY bypasses the no-op guard
Tracking and anchor-watch paths are unchanged: throttleLocationIfIdle()
skips the stop if either is active, and onResume sends ACTION_START_FULL
when recording is still in progress.
https://claude.ai/code/session_0126zvB69ccVoFtx2o96oaE2
Diffstat (limited to 'android-app')
3 files changed, 15 insertions, 8 deletions
diff --git a/android-app/app/src/main/kotlin/org/terst/nav/LocationService.kt b/android-app/app/src/main/kotlin/org/terst/nav/LocationService.kt index c47c7a5..c1ff60e 100644 --- a/android-app/app/src/main/kotlin/org/terst/nav/LocationService.kt +++ b/android-app/app/src/main/kotlin/org/terst/nav/LocationService.kt @@ -270,6 +270,10 @@ class LocationService : Service() { } ACTION_START_ECONOMY -> setPowerMode(PowerMode.ECONOMY) ACTION_START_FULL -> setPowerMode(PowerMode.FULL) + ACTION_STOP_UPDATES -> serviceScope.launch { + stopLocationUpdatesInternal() + _currentPowerMode.emit(PowerMode.NONE) + } ACTION_START_ANCHOR_WATCH -> { val radius = intent.getDoubleExtra(EXTRA_WATCH_RADIUS, AnchorWatchState.DEFAULT_WATCH_CIRCLE_RADIUS_METERS) serviceScope.launch { @@ -316,6 +320,7 @@ class LocationService : Service() { @SuppressLint("MissingPermission") private fun startLocationUpdatesInternal(powerMode: PowerMode) { + if (powerMode == PowerMode.NONE) return val priority = if (powerMode == PowerMode.FULL) Priority.PRIORITY_HIGH_ACCURACY else @@ -411,8 +416,9 @@ class LocationService : Service() { companion object { const val ACTION_START_FOREGROUND_SERVICE = "ACTION_START_FOREGROUND_SERVICE" const val ACTION_STOP_FOREGROUND_SERVICE = "ACTION_STOP_FOREGROUND_SERVICE" - const val ACTION_START_ECONOMY = "ACTION_START_ECONOMY" - const val ACTION_START_FULL = "ACTION_START_FULL" + const val ACTION_START_ECONOMY = "ACTION_START_ECONOMY" + const val ACTION_START_FULL = "ACTION_START_FULL" + const val ACTION_STOP_UPDATES = "ACTION_STOP_UPDATES" const val ACTION_START_ANCHOR_WATCH = "ACTION_START_ANCHOR_WATCH" const val ACTION_STOP_ANCHOR_WATCH = "ACTION_STOP_ANCHOR_WATCH" const val ACTION_UPDATE_WATCH_RADIUS = "ACTION_UPDATE_WATCH_RADIUS" @@ -469,7 +475,7 @@ class LocationService : Service() { _currentDirectionDeg.value = directionDeg } - private val _currentPowerMode = MutableStateFlow(PowerMode.FULL) + private val _currentPowerMode = MutableStateFlow(PowerMode.NONE) val currentPowerMode: StateFlow<PowerMode> get() = _currentPowerMode private val _tidalCurrentState = MutableStateFlow(TidalCurrentState()) diff --git a/android-app/app/src/main/kotlin/org/terst/nav/MainActivity.kt b/android-app/app/src/main/kotlin/org/terst/nav/MainActivity.kt index 94b9c81..476fb0d 100644 --- a/android-app/app/src/main/kotlin/org/terst/nav/MainActivity.kt +++ b/android-app/app/src/main/kotlin/org/terst/nav/MainActivity.kt @@ -505,11 +505,11 @@ class MainActivity : AppCompatActivity(), SafetyFragment.SafetyListener { private fun locationServiceIntent(action: String) = Intent(this, LocationService::class.java).apply { this.action = action } - /** Drop to economy rate when the app goes to the background and nothing needs precision. */ + /** Stop location updates when the app is backgrounded and nothing needs location. */ private fun throttleLocationIfIdle() { if (!serviceStarted) return if (!viewModel.isRecording.value && !LocationService.anchorWatchState.value.isActive) { - startService(locationServiceIntent(LocationService.ACTION_START_ECONOMY)) + startService(locationServiceIntent(LocationService.ACTION_STOP_UPDATES)) } } diff --git a/android-app/app/src/main/kotlin/org/terst/nav/PowerMode.kt b/android-app/app/src/main/kotlin/org/terst/nav/PowerMode.kt index 22e1b77..d55c965 100644 --- a/android-app/app/src/main/kotlin/org/terst/nav/PowerMode.kt +++ b/android-app/app/src/main/kotlin/org/terst/nav/PowerMode.kt @@ -1,7 +1,8 @@ package org.terst.nav enum class PowerMode(val gpsUpdateIntervalMillis: Long) { - FULL(1000L), // 1 Hz - ECONOMY(5000L), // 0.2 Hz - ANCHOR_WATCH(10000L) // 0.1 Hz + NONE(0L), // no location updates (background idle) + FULL(1000L), // 1 Hz, high accuracy + ECONOMY(5000L), // 0.2 Hz, balanced accuracy + ANCHOR_WATCH(10000L) // 0.1 Hz, balanced accuracy } |
