From 31ad748796d3d481fadef26012c4f7fd50f140bc Mon Sep 17 00:00:00 2001 From: johan12345 Date: Sun, 15 Aug 2021 15:49:23 +0200 Subject: [PATCH] use car hardware location data if available --- .../net/vonforst/evmap/auto/CarAppService.kt | 61 +++++++++++++------ 1 file changed, 44 insertions(+), 17 deletions(-) diff --git a/app/src/google/java/net/vonforst/evmap/auto/CarAppService.kt b/app/src/google/java/net/vonforst/evmap/auto/CarAppService.kt index e5eb297d..44ecc04b 100644 --- a/app/src/google/java/net/vonforst/evmap/auto/CarAppService.kt +++ b/app/src/google/java/net/vonforst/evmap/auto/CarAppService.kt @@ -6,15 +6,19 @@ import android.content.pm.ApplicationInfo import android.content.pm.PackageManager import android.location.Location import android.os.IBinder +import androidx.car.app.CarContext import androidx.car.app.Screen import androidx.car.app.Session -import androidx.car.app.model.* +import androidx.car.app.hardware.CarHardwareManager +import androidx.car.app.hardware.info.CarHardwareLocation +import androidx.car.app.hardware.info.CarSensors import androidx.car.app.validation.HostValidator +import androidx.car.app.versioning.CarAppApiLevels import androidx.core.content.ContextCompat -import androidx.lifecycle.* +import androidx.lifecycle.Lifecycle +import androidx.lifecycle.LifecycleObserver +import androidx.lifecycle.OnLifecycleEvent import androidx.localbroadcastmanager.content.LocalBroadcastManager -import kotlinx.coroutines.* -import net.vonforst.evmap.* interface LocationAwareScreen { @@ -45,6 +49,8 @@ class EVMapSession(val cas: CarAppService) : Session(), LifecycleObserver { } private var location: Location? = null private var locationService: CarLocationService? = null + private val hardwareMan = + carContext.getCarService(CarContext.HARDWARE_SERVICE) as CarHardwareManager private val serviceConnection = object : ServiceConnection { override fun onServiceConnected(name: ComponentName, ibinder: IBinder) { @@ -75,29 +81,50 @@ class EVMapSession(val cas: CarAppService) : Session(), LifecycleObserver { private val locationReceiver = object : BroadcastReceiver() { override fun onReceive(context: Context, intent: Intent) { val location = intent.getParcelableExtra(CarLocationService.EXTRA_LOCATION) as Location? - val mapScreen = this@EVMapSession.mapScreen - if (location != null && mapScreen != null) { - mapScreen.updateLocation(location) - } - this@EVMapSession.location = location + updateLocation(location) } } + private fun updateLocation(location: Location?) { + val mapScreen = mapScreen + if (location != null && mapScreen != null) { + mapScreen.updateLocation(location) + } + this.location = location + } + + private fun onCarHardwareLocationReceived(loc: CarHardwareLocation) { + updateLocation(loc.location.value) + } + @OnLifecycleEvent(Lifecycle.Event.ON_START) fun bindLocationService() { if (!locationPermissionGranted()) return - cas.bindService( - Intent(cas, CarLocationService::class.java), - serviceConnection, - Context.BIND_AUTO_CREATE - ) + if (carContext.carAppApiLevel >= CarAppApiLevels.LEVEL_3) { + val exec = ContextCompat.getMainExecutor(carContext) + hardwareMan.carSensors.addCarHardwareLocationListener( + CarSensors.UPDATE_RATE_NORMAL, + exec, + ::onCarHardwareLocationReceived + ) + } else { + cas.bindService( + Intent(cas, CarLocationService::class.java), + serviceConnection, + Context.BIND_AUTO_CREATE + ) + } } @OnLifecycleEvent(Lifecycle.Event.ON_STOP) private fun unbindLocationService() { - locationService?.let { service -> - service.removeLocationUpdates() - cas.unbindService(serviceConnection) + if (carContext.carAppApiLevel >= CarAppApiLevels.LEVEL_3) { + locationService?.let { service -> + service.removeLocationUpdates() + cas.unbindService(serviceConnection) + } + } else { + hardwareMan.carSensors.removeCarHardwareLocationListener(::onCarHardwareLocationReceived) } }