DevicePoseProvider: improve getLocation() (#1454)

* Only take updated location when it is of better quality

* Rename to AndroidLocation for clarification

* be pedantic about licenses

* fix race condition in DevicePoseProvider.kt

* add possibility to explicitly skip cache upon requesting location updates for WeatherRepository.kt

* LocationsRepository.kt: use getLocation() in combineTransform() to properly wait for & update on new locations

* LocationItem.kt: fix getAzimuthDegrees() usage for userHeading
This commit is contained in:
shtrophic
2025-07-04 11:55:20 +02:00
committed by GitHub
parent dd14c6cbaa
commit 31a1580db9
7 changed files with 119 additions and 54 deletions
@@ -0,0 +1,48 @@
package de.mm20.launcher2.ktx
import android.hardware.GeomagneticField
import kotlin.time.Duration.Companion.minutes
import kotlin.time.Duration.Companion.nanoseconds
import android.location.Location as AndroidLocation
/* https://github.com/streetcomplete/StreetComplete/blob/master/app/src/main/java/de/westnordost/streetcomplete/util/location/LocationUtils.kt
* GPL-3.0-or-later
*/
fun AndroidLocation?.isBetterThan(previous: AndroidLocation?): Boolean {
if (this == null) return false
if (longitude.isNaN() || latitude.isNaN()) return false
if (previous == null) return true
val locationTimeDiff = elapsedRealtimeNanos.nanoseconds - previous.elapsedRealtimeNanos.nanoseconds
val isMuchNewer = locationTimeDiff > 2.minutes
val isMuchOlder = locationTimeDiff < (-2).minutes
val isNewer = locationTimeDiff.isPositive()
val accuracyDelta = accuracy - previous.accuracy
val isLessAccurate = accuracyDelta > 0f
val isMoreAccurate = accuracyDelta < 0f
val isMuchLessAccurate = accuracyDelta > 200f
val isFromSameProvider = provider == previous.provider
return when {
// the user has likely moved
isMuchNewer -> true
// If the new location is more than two minutes older, it must be worse
isMuchOlder -> false
isMoreAccurate -> true
isNewer && !isLessAccurate -> true
isNewer && !isMuchLessAccurate && isFromSameProvider -> true
else -> false
}
}
val AndroidLocation.declination: Float
get() = GeomagneticField(
latitude.toFloat(),
longitude.toFloat(),
altitude.toFloat(),
time
).declination
@@ -1,5 +1,14 @@
package de.mm20.launcher2.ktx
inline fun Boolean.toInt(): Int {
fun Boolean.toInt(): Int {
return if (this) 1 else 0
}
}
fun <T> Boolean.fold(
whenTrue: () -> T,
otherwise: () -> T
): T = if (this) whenTrue() else otherwise()
fun <T> Boolean.foldOrNull(
whenTrue: () -> T
): T? = fold(whenTrue) { null }