parent
b36b8e5555
commit
3c11d784b4
@ -8,18 +8,16 @@ import android.hardware.SensorEvent
|
|||||||
import android.hardware.SensorEventListener
|
import android.hardware.SensorEventListener
|
||||||
import android.hardware.SensorManager
|
import android.hardware.SensorManager
|
||||||
import android.location.Location
|
import android.location.Location
|
||||||
import android.location.LocationListener
|
|
||||||
import android.location.LocationManager
|
import android.location.LocationManager
|
||||||
import android.os.Build
|
|
||||||
import android.util.Log
|
import android.util.Log
|
||||||
import androidx.annotation.RequiresApi
|
|
||||||
import androidx.core.content.getSystemService
|
import androidx.core.content.getSystemService
|
||||||
|
import androidx.core.location.LocationListenerCompat
|
||||||
import de.mm20.launcher2.ktx.PI
|
import de.mm20.launcher2.ktx.PI
|
||||||
|
import de.mm20.launcher2.ktx.checkPermission
|
||||||
import kotlinx.coroutines.channels.awaitClose
|
import kotlinx.coroutines.channels.awaitClose
|
||||||
import kotlinx.coroutines.flow.Flow
|
import kotlinx.coroutines.flow.Flow
|
||||||
import kotlinx.coroutines.flow.callbackFlow
|
import kotlinx.coroutines.flow.callbackFlow
|
||||||
import kotlinx.coroutines.flow.channelFlow
|
import kotlinx.coroutines.flow.channelFlow
|
||||||
import de.mm20.launcher2.ktx.checkPermission
|
|
||||||
import kotlinx.coroutines.flow.combine
|
import kotlinx.coroutines.flow.combine
|
||||||
|
|
||||||
class DevicePoseProvider internal constructor(
|
class DevicePoseProvider internal constructor(
|
||||||
@ -39,7 +37,7 @@ class DevicePoseProvider internal constructor(
|
|||||||
}
|
}
|
||||||
|
|
||||||
fun getLocation(minTimeMs: Long = 1000, minDistanceM: Float = 1f) = channelFlow {
|
fun getLocation(minTimeMs: Long = 1000, minDistanceM: Float = 1f) = channelFlow {
|
||||||
val locationCallback = LocationListener {
|
val locationCallback = LocationListenerCompat {
|
||||||
lastLocation = it
|
lastLocation = it
|
||||||
updateDeclination(it)
|
updateDeclination(it)
|
||||||
trySend(it)
|
trySend(it)
|
||||||
@ -54,7 +52,9 @@ class DevicePoseProvider internal constructor(
|
|||||||
|
|
||||||
val location =
|
val location =
|
||||||
(if (hasFineAccess) this@runCatching.getLastKnownLocation(LocationManager.GPS_PROVIDER) else null)
|
(if (hasFineAccess) this@runCatching.getLastKnownLocation(LocationManager.GPS_PROVIDER) else null)
|
||||||
?: if (hasCoarseAccess) this@runCatching.getLastKnownLocation(LocationManager.NETWORK_PROVIDER) else null
|
?: if (hasCoarseAccess) this@runCatching.getLastKnownLocation(
|
||||||
|
LocationManager.NETWORK_PROVIDER
|
||||||
|
) else null
|
||||||
|
|
||||||
if (location != null) {
|
if (location != null) {
|
||||||
lastLocation = location
|
lastLocation = location
|
||||||
@ -87,42 +87,46 @@ class DevicePoseProvider internal constructor(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fun getAzimuthDegrees(samplingPeriodUs: Int = SensorManager.SENSOR_DELAY_UI): Flow<Float> = callbackFlow {
|
fun getAzimuthDegrees(samplingPeriodUs: Int = SensorManager.SENSOR_DELAY_UI): Flow<Float> =
|
||||||
val azimuthCallback = object : SensorEventListener {
|
callbackFlow {
|
||||||
override fun onAccuracyChanged(sensor: Sensor?, accuracy: Int) {}
|
val azimuthCallback = object : SensorEventListener {
|
||||||
override fun onSensorChanged(event: SensorEvent?) {
|
override fun onAccuracyChanged(sensor: Sensor?, accuracy: Int) {}
|
||||||
if (event?.sensor?.type != Sensor.TYPE_ROTATION_VECTOR)
|
override fun onSensorChanged(event: SensorEvent?) {
|
||||||
return
|
if (event?.sensor?.type != Sensor.TYPE_ROTATION_VECTOR)
|
||||||
|
return
|
||||||
|
|
||||||
val rotationMatrix = FloatArray(9)
|
val rotationMatrix = FloatArray(9)
|
||||||
val orientationAngles = FloatArray(3)
|
val orientationAngles = FloatArray(3)
|
||||||
|
|
||||||
SensorManager.getRotationMatrixFromVector(rotationMatrix, event.values)
|
SensorManager.getRotationMatrixFromVector(rotationMatrix, event.values)
|
||||||
SensorManager.getOrientation(rotationMatrix, orientationAngles)
|
SensorManager.getOrientation(rotationMatrix, orientationAngles)
|
||||||
|
|
||||||
trySend(orientationAngles[0] * 180f / Float.PI + (declination ?: 0f))
|
trySend(orientationAngles[0] * 180f / Float.PI + (declination ?: 0f))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
context
|
||||||
|
.getSystemService<SensorManager>()
|
||||||
|
?.runCatching {
|
||||||
|
this@runCatching.registerListener(
|
||||||
|
azimuthCallback,
|
||||||
|
this@runCatching.getDefaultSensor(Sensor.TYPE_ROTATION_VECTOR)
|
||||||
|
?: return@runCatching,
|
||||||
|
samplingPeriodUs
|
||||||
|
)
|
||||||
|
}?.onFailure {
|
||||||
|
Log.e("DevicePoseProvider", "Failed to register ROTATION_VECTOR listener", it)
|
||||||
|
}
|
||||||
|
|
||||||
|
awaitClose {
|
||||||
|
context.getSystemService<SensorManager>()?.unregisterListener(azimuthCallback)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
context
|
fun getHeadingToDegrees(
|
||||||
.getSystemService<SensorManager>()
|
headingEastwardDegrees: Float,
|
||||||
?.runCatching {
|
samplingPeriodUs: Int = SensorManager.SENSOR_DELAY_UI
|
||||||
this@runCatching.registerListener(
|
): Flow<Float> = combine(
|
||||||
azimuthCallback,
|
|
||||||
this@runCatching.getDefaultSensor(Sensor.TYPE_ROTATION_VECTOR)
|
|
||||||
?: return@runCatching,
|
|
||||||
samplingPeriodUs
|
|
||||||
)
|
|
||||||
}?.onFailure {
|
|
||||||
Log.e("DevicePoseProvider", "Failed to register ROTATION_VECTOR listener", it)
|
|
||||||
}
|
|
||||||
|
|
||||||
awaitClose {
|
|
||||||
context.getSystemService<SensorManager>()?.unregisterListener(azimuthCallback)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fun getHeadingToDegrees(headingEastwardDegrees: Float, samplingPeriodUs: Int = SensorManager.SENSOR_DELAY_UI): Flow<Float> = combine(
|
|
||||||
getAzimuthDegrees(samplingPeriodUs),
|
getAzimuthDegrees(samplingPeriodUs),
|
||||||
callbackFlow {
|
callbackFlow {
|
||||||
val upsideDownCallback = object : SensorEventListener {
|
val upsideDownCallback = object : SensorEventListener {
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user