Skip to content
This repository has been archived by the owner on Jul 2, 2024. It is now read-only.

Commit

Permalink
Use altitude above mean sea level
Browse files Browse the repository at this point in the history
  • Loading branch information
SanmerDev committed Dec 13, 2023
1 parent bb69982 commit 765231e
Show file tree
Hide file tree
Showing 3 changed files with 72 additions and 13 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import android.annotation.SuppressLint
import android.content.Context
import android.content.pm.PackageManager
import android.location.LocationManager
import android.location.OnNmeaMessageListener
import android.os.Handler
import android.os.Looper
import androidx.compose.runtime.Composable
Expand Down Expand Up @@ -85,6 +86,7 @@ object LocationManagerUtils {
close()
}

val locationManager = context.locationManager
val listener = LocationListenerCompat {
trySend(it)
}
Expand All @@ -97,21 +99,22 @@ object LocationManagerUtils {
runCatching {
Timber.d("requestLocationUpdates")
LocationManagerCompat.requestLocationUpdates(
context.locationManager,
locationManager,
LocationManager.GPS_PROVIDER,
locationRequest,
listener,
Looper.getMainLooper()
)
}.onFailure {
Timber.e(it, "locationUpdates")
Timber.e(it, "getLocationAsFlow")
close(it)
}

awaitClose {
Timber.d("removeUpdates")
LocationManagerCompat.removeUpdates(context.locationManager, listener)
LocationManagerCompat.removeUpdates(locationManager, listener)
}

}.flowOn(Dispatchers.Default)

@SuppressLint("MissingPermission")
Expand All @@ -120,6 +123,7 @@ object LocationManagerUtils {
close()
}

val locationManager = context.locationManager
val callback = object : GnssStatusCompat.Callback() {
override fun onSatelliteStatusChanged(status: GnssStatusCompat) {
trySend(status)
Expand All @@ -129,18 +133,59 @@ object LocationManagerUtils {
runCatching {
Timber.d("registerGnssStatusCallback")
LocationManagerCompat.registerGnssStatusCallback(
context.locationManager,
locationManager,
callback,
Handler(Looper.getMainLooper())
)
}.onFailure {
Timber.e(it, "gnssStatusUpdates")
Timber.e(it, "getGnssStatusAsFlow")
close(it)
}

awaitClose {
Timber.d("unregisterGnssStatusCallback")
LocationManagerCompat.unregisterGnssStatusCallback(context.locationManager, callback)
LocationManagerCompat.unregisterGnssStatusCallback(locationManager, callback)
}
}

}.flowOn(Dispatchers.Default)

@SuppressLint("MissingPermission")
fun getAltitudeMeanSeaLevel(context: Context) = callbackFlow {
if (!(context.hasPermissions() && isEnable)) {
close()
}

val locationManager = context.locationManager
val listener = OnNmeaMessageListener { message, _ ->
if (NMEA_KEYS.any { message.startsWith(it) }) {
val mslAltitudeMeters = message.split(",")
.getOrNull(MSL_ALTITUDE_INDEX)
?.toDoubleOrNull()

if (mslAltitudeMeters != null) {
trySend(mslAltitudeMeters)
}
}
}

runCatching {
Timber.d("addNmeaListener")
locationManager.addNmeaListener(
listener,
Handler(Looper.getMainLooper())
)
}.onFailure {
Timber.e(it, "getNmeaAsFlow")
close(it)
}

awaitClose {
Timber.d("removeNmeaListener")
locationManager.removeNmeaListener(listener)
}

}.flowOn(Dispatchers.Default)

private const val MSL_ALTITUDE_INDEX = 9
private val NMEA_KEYS = listOf("\$GPGGA", "\$GNGNS", "\$GNGGA")
}
3 changes: 3 additions & 0 deletions app/src/main/kotlin/com/sanmer/geomag/app/utils/OsUtils.kt
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,9 @@ import android.os.Build
import androidx.annotation.ChecksSdkIntAtLeast

object OsUtils {
@get:ChecksSdkIntAtLeast(api = Build.VERSION_CODES.UPSIDE_DOWN_CAKE)
val atLeastU get() = Build.VERSION.SDK_INT >= Build.VERSION_CODES.UPSIDE_DOWN_CAKE

@get:ChecksSdkIntAtLeast(api = Build.VERSION_CODES.TIRAMISU)
val atLeastT get() = Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU

Expand Down
23 changes: 17 additions & 6 deletions app/src/main/kotlin/com/sanmer/geomag/service/LocationService.kt
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,9 @@ import androidx.lifecycle.LifecycleService
import androidx.lifecycle.flowWithLifecycle
import androidx.lifecycle.lifecycleScope
import com.sanmer.geomag.app.utils.LocationManagerUtils
import com.sanmer.geomag.app.utils.OsUtils
import com.sanmer.geomag.model.gnss.Satellite
import kotlinx.coroutines.flow.combine
import kotlinx.coroutines.flow.launchIn
import kotlinx.coroutines.flow.onEach

Expand All @@ -25,17 +27,26 @@ class LocationService : LifecycleService() {

LocationManagerUtils.getLocationAsFlow(this)
.flowWithLifecycle(lifecycle, Lifecycle.State.STARTED)
.onEach {
location = it
}
.launchIn(lifecycleScope)
.combine(
LocationManagerUtils.getAltitudeMeanSeaLevel(this)
) { mLocation, mMslAltitudeMeters ->

mLocation.altitude = if (OsUtils.atLeastU && mLocation.hasMslAltitude()) {
mLocation.mslAltitudeMeters
} else {
mMslAltitudeMeters
}

location = mLocation

}.launchIn(lifecycleScope)

LocationManagerUtils.getGnssStatusAsFlow(this)
.flowWithLifecycle(lifecycle, Lifecycle.State.STARTED)
.onEach {
gnssStatusOrNull = it
}
.launchIn(lifecycleScope)

}.launchIn(lifecycleScope)
}

override fun onDestroy() {
Expand Down

0 comments on commit 765231e

Please sign in to comment.