From 3c5201e5ca09422e3501b90d4d1bf9caa560d2bd Mon Sep 17 00:00:00 2001 From: johan12345 Date: Sun, 6 Feb 2022 23:06:03 +0100 Subject: [PATCH] VehicleDataScreen: add heading --- .../vonforst/evmap/auto/VehicleDataScreen.kt | 39 +++++++++++++++++-- .../net/vonforst/evmap/ui/CompassNeedle.kt | 33 ++++++++++++++++ app/src/google/res/values-de/values.xml | 1 + app/src/google/res/values/values.xml | 1 + 4 files changed, 71 insertions(+), 3 deletions(-) create mode 100644 app/src/google/java/net/vonforst/evmap/ui/CompassNeedle.kt diff --git a/app/src/google/java/net/vonforst/evmap/auto/VehicleDataScreen.kt b/app/src/google/java/net/vonforst/evmap/auto/VehicleDataScreen.kt index 1d25907a..d6559cea 100644 --- a/app/src/google/java/net/vonforst/evmap/auto/VehicleDataScreen.kt +++ b/app/src/google/java/net/vonforst/evmap/auto/VehicleDataScreen.kt @@ -6,9 +6,7 @@ import android.os.Looper import androidx.car.app.CarContext import androidx.car.app.Screen import androidx.car.app.hardware.CarHardwareManager -import androidx.car.app.hardware.info.EnergyLevel -import androidx.car.app.hardware.info.Model -import androidx.car.app.hardware.info.Speed +import androidx.car.app.hardware.info.* import androidx.car.app.model.* import androidx.core.content.ContextCompat import androidx.core.graphics.drawable.IconCompat @@ -17,6 +15,7 @@ import androidx.lifecycle.LifecycleObserver import androidx.lifecycle.OnLifecycleEvent import net.vonforst.evmap.BuildConfig import net.vonforst.evmap.R +import net.vonforst.evmap.ui.CompassNeedle import net.vonforst.evmap.ui.Gauge import kotlin.math.min import kotlin.math.roundToInt @@ -26,7 +25,10 @@ class VehicleDataScreen(ctx: CarContext) : Screen(ctx), LifecycleObserver { private var model: Model? = null private var energyLevel: EnergyLevel? = null private var speed: Speed? = null + private var heading: Compass? = null private var gauge = Gauge((ctx.resources.displayMetrics.density * 128).roundToInt(), ctx) + private var compass = + CompassNeedle((ctx.resources.displayMetrics.density * 128).roundToInt(), ctx) private val maxSpeed = 160f / 3.6f // m/s, speed gauge will show max if speed is higher private val permissions = if (BuildConfig.FLAVOR_automotive == "automotive") { @@ -66,6 +68,7 @@ class VehicleDataScreen(ctx: CarContext) : Screen(ctx), LifecycleObserver { val energyLevel = energyLevel val model = model val speed = speed + val heading = heading return GridTemplate.Builder().apply { setTitle( @@ -182,6 +185,25 @@ class VehicleDataScreen(ctx: CarContext) : Screen(ctx), LifecycleObserver { } } }.build()) + addItem(GridItem.Builder().apply { + setTitle(carContext.getString(R.string.auto_heading)) + if (heading == null) { + setLoading(true) + } else { + val heading = heading.orientations.value + if (heading != null) { + setText( + "${heading[0].roundToInt()}°" + ) + + } else { + setText(carContext.getString(R.string.auto_no_data)) + } + setImage( + compass.draw(heading?.get(0)).asCarIcon() + ) + } + }.build()) }.build() ) } @@ -198,6 +220,11 @@ class VehicleDataScreen(ctx: CarContext) : Screen(ctx), LifecycleObserver { invalidate() } + private fun onCompassUpdated(compass: Compass) { + this.heading = compass + invalidate() + } + @OnLifecycleEvent(Lifecycle.Event.ON_RESUME) private fun setupListeners() { if (!permissionsGranted()) return @@ -207,6 +234,11 @@ class VehicleDataScreen(ctx: CarContext) : Screen(ctx), LifecycleObserver { val exec = ContextCompat.getMainExecutor(carContext) hardwareMan.carInfo.addEnergyLevelListener(exec, ::onEnergyLevelUpdated) hardwareMan.carInfo.addSpeedListener(exec, ::onSpeedUpdated) + hardwareMan.carSensors.addCompassListener( + CarSensors.UPDATE_RATE_NORMAL, + exec, + ::onCompassUpdated + ) hardwareMan.carInfo.fetchModel(exec) { this.model = it @@ -219,6 +251,7 @@ class VehicleDataScreen(ctx: CarContext) : Screen(ctx), LifecycleObserver { println("Removing energy level listener") hardwareMan.carInfo.removeEnergyLevelListener(::onEnergyLevelUpdated) hardwareMan.carInfo.removeSpeedListener(::onSpeedUpdated) + hardwareMan.carSensors.removeCompassListener(::onCompassUpdated) } private fun permissionsGranted(): Boolean = diff --git a/app/src/google/java/net/vonforst/evmap/ui/CompassNeedle.kt b/app/src/google/java/net/vonforst/evmap/ui/CompassNeedle.kt new file mode 100644 index 00000000..8aede7c9 --- /dev/null +++ b/app/src/google/java/net/vonforst/evmap/ui/CompassNeedle.kt @@ -0,0 +1,33 @@ +package net.vonforst.evmap.ui + +import android.content.Context +import android.graphics.Bitmap +import android.graphics.Canvas +import android.graphics.Color +import android.graphics.PorterDuff +import androidx.core.content.ContextCompat +import net.vonforst.evmap.R + +class CompassNeedle(val size: Int, ctx: Context) { + val image = ContextCompat.getDrawable(ctx, R.drawable.ic_navigation)!! + + init { + image.setTint(Color.WHITE) + image.setBounds(0, 0, size, size) + } + + fun draw(angle: Float?): Bitmap { + val bitmap = Bitmap.createBitmap(size, size, Bitmap.Config.ARGB_8888) + val canvas = Canvas(bitmap) + + canvas.drawColor(Color.TRANSPARENT, PorterDuff.Mode.CLEAR) + + if (angle != null) { + canvas.save() + canvas.rotate(-angle, size / 2f, size / 2f) + image.draw(canvas) + canvas.restore() + } + return bitmap + } +} \ No newline at end of file diff --git a/app/src/google/res/values-de/values.xml b/app/src/google/res/values-de/values.xml index fe2a74ad..42ccd5d9 100644 --- a/app/src/google/res/values-de/values.xml +++ b/app/src/google/res/values-de/values.xml @@ -27,6 +27,7 @@ Nicht verfügbar Reichweite Geschwindigkeit + Fahrtrichtung Einstellungen Android Auto-Unterstützung Auf unterstützen Autos kannst du EVMap auch mit Android Auto nutzen. Öffne dazu einfach die EVMap-App aus dem Menü von Android Auto. diff --git a/app/src/google/res/values/values.xml b/app/src/google/res/values/values.xml index 1caa2199..2a5f399f 100644 --- a/app/src/google/res/values/values.xml +++ b/app/src/google/res/values/values.xml @@ -37,6 +37,7 @@ Unavailable Range Speed + Heading Settings Android Auto support You can also use EVMap from within Android Auto on supported cars. Simply select the EVMap app in the Android Auto menu.