From b5ed2165a06883afe2cc40b88aaef8089caa9ba6 Mon Sep 17 00:00:00 2001 From: Ellen Poe Date: Thu, 23 Oct 2025 15:14:34 -0700 Subject: [PATCH] fix: prefer GPS over fused rather than the opposite --- .../maps/cardinal/data/LocationRepository.kt | 92 ++++++------------- 1 file changed, 29 insertions(+), 63 deletions(-) diff --git a/cardinal-android/app/src/main/java/earth/maps/cardinal/data/LocationRepository.kt b/cardinal-android/app/src/main/java/earth/maps/cardinal/data/LocationRepository.kt index efc5918..7679f1d 100644 --- a/cardinal-android/app/src/main/java/earth/maps/cardinal/data/LocationRepository.kt +++ b/cardinal-android/app/src/main/java/earth/maps/cardinal/data/LocationRepository.kt @@ -56,8 +56,8 @@ class LocationRepository @Inject constructor( private const val LOCATION_REQUEST_TIMEOUT_MS = 5000L // 5 seconds private const val CONTINUOUS_LOCATION_UPDATE_INTERVAL_MS = 5000L // 5 seconds private const val CONTINUOUS_LOCATION_UPDATE_DISTANCE_M = 5f // 5 meters - private const val FUSED_PROVIDER_TIMEOUT_MS = - 5000L // 5 seconds - discard GPS if fused hasn't updated + private const val GPS_PROVIDER_TIMEOUT_MS = + 10_000L // 10 seconds - discard fused locations if fused has updated within this timeout } // Location caching with thread safety @@ -76,8 +76,8 @@ class LocationRepository @Inject constructor( private var gpsLocationListener: LocationListener? = null private var fusedLocationListener: LocationListener? = null - // Track last fused provider update time - private var lastFusedLocationTime: Long = 0L + // Track last GPS update time + private var lastGpsLocationTime: Long = 0L /** * Gets the current location, either from cache or by requesting a fresh one. @@ -142,8 +142,8 @@ class LocationRepository @Inject constructor( * This should be called from the UI when the map is ready. * * Subscribes to both GPS and fused providers to handle unreliable fused location - * on some microG devices. GPS updates are discarded unless fused hasn't provided - * a location for 5 seconds. + * on some microG devices. Fused updates are discarded unless GPS hasn't provided + * a location for 10 seconds. */ @SuppressLint("MissingPermission") fun startContinuousLocationUpdates(context: Context) { @@ -165,7 +165,23 @@ class LocationRepository @Inject constructor( fusedLocationListener = object : LocationListener { override fun onLocationChanged(location: Location) { Log.d("LocationRepository", "Fused location update received") - lastFusedLocationTime = System.currentTimeMillis() + val currentTime = System.currentTimeMillis() + val timeSinceLastGps = currentTime - lastGpsLocationTime + + // Discard this position update if the GPS is providing updates. + if (timeSinceLastGps <= GPS_PROVIDER_TIMEOUT_MS) { + Log.d( + "LocationRepository", + "Discarding fused update (GPS active: ${timeSinceLastGps}ms ago)" + ) + return + } + + // Only use GPS if fused hasn't updated in 10 seconds + Log.d( + "LocationRepository", + "Using Fused location (GPS timeout: ${timeSinceLastGps}ms)" + ) // Always use fused provider updates _locationFlow.value = location @@ -211,27 +227,15 @@ class LocationRepository @Inject constructor( if (availableProviders.contains(LocationManager.GPS_PROVIDER)) { gpsLocationListener = object : LocationListener { override fun onLocationChanged(location: Location) { - val currentTime = System.currentTimeMillis() - val timeSinceLastFused = currentTime - lastFusedLocationTime + lastGpsLocationTime = System.currentTimeMillis() - // Only use GPS if fused hasn't updated in 5 seconds - if (timeSinceLastFused >= FUSED_PROVIDER_TIMEOUT_MS) { - Log.d( - "LocationRepository", - "Using GPS location (fused timeout: ${timeSinceLastFused}ms)" - ) - _locationFlow.value = location - orientationRepository.setDeclination(location) + _locationFlow.value = location + orientationRepository.setDeclination(location) - synchronized(locationLock) { - lastRequestedLocation = location - } - } else { - Log.d( - "LocationRepository", - "Discarding GPS update (fused active: ${timeSinceLastFused}ms ago)" - ) + synchronized(locationLock) { + lastRequestedLocation = location } + } override fun onProviderDisabled(provider: String) { @@ -272,44 +276,6 @@ class LocationRepository @Inject constructor( } } - /** - * Stops location updates and orientation tracking. - */ - fun stopLocationUpdates(context: Context) { - // Stop orientation tracking - orientationRepository.stop() - Log.d("LocationRepository", "Orientation sensor stopped") - - val locationManager = try { - getLocationManager(context) - } catch (_: Exception) { - null - } - - // Remove GPS listener - gpsLocationListener?.let { listener -> - try { - locationManager?.removeUpdates(listener) - } catch (_: Exception) { - // Ignore exceptions during cleanup - } - gpsLocationListener = null - } - - // Remove fused listener - fusedLocationListener?.let { listener -> - try { - locationManager?.removeUpdates(listener) - } catch (_: Exception) { - // Ignore exceptions during cleanup - } - fusedLocationListener = null - } - - // Reset fused location timestamp - lastFusedLocationTime = 0L - } - /** * Checks if a location is recent (less than LOCATION_REQUEST_INTERVAL_MS old). */ -- GitLab