Loading cardinal-android/app/src/main/java/earth/maps/cardinal/data/LocationRepository.kt +29 −63 Original line number Diff line number Diff line Loading @@ -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 Loading @@ -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. Loading Loading @@ -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) { Loading @@ -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 Loading Loading @@ -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) synchronized(locationLock) { lastRequestedLocation = location } } else { Log.d( "LocationRepository", "Discarding GPS update (fused active: ${timeSinceLastFused}ms ago)" ) } } override fun onProviderDisabled(provider: String) { Loading Loading @@ -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). */ Loading Loading
cardinal-android/app/src/main/java/earth/maps/cardinal/data/LocationRepository.kt +29 −63 Original line number Diff line number Diff line Loading @@ -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 Loading @@ -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. Loading Loading @@ -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) { Loading @@ -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 Loading Loading @@ -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) synchronized(locationLock) { lastRequestedLocation = location } } else { Log.d( "LocationRepository", "Discarding GPS update (fused active: ${timeSinceLastFused}ms ago)" ) } } override fun onProviderDisabled(provider: String) { Loading Loading @@ -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). */ Loading