Compare commits

..

1 Commits

Author SHA1 Message Date
johan12345
10ce6a0b5f AA/AAOS: implement TabTemplate for detail view 2023-09-02 22:21:07 +02:00
7 changed files with 80 additions and 62 deletions

View File

@@ -32,7 +32,6 @@ jobs:
MAPBOX_API_KEY: ${{ secrets.MAPBOX_API_KEY }}
GOOGLE_MAPS_API_KEY: ${{ secrets.GOOGLE_MAPS_API_KEY }}
FRONYX_API_KEY: ${{ secrets.FRONYX_API_KEY }}
ACRA_CRASHREPORT_CREDENTIALS: ${{ secrets.ACRA_CRASHREPORT_CREDENTIALS }}
KEYSTORE_PASSWORD: ${{ secrets.KEYSTORE_PASSWORD }}
KEYSTORE_ALIAS: ${{ secrets.KEYSTORE_ALIAS }}
KEYSTORE_ALIAS_PASSWORD: ${{ secrets.KEYSTORE_ALIAS_PASSWORD }}

View File

@@ -19,8 +19,8 @@ android {
minSdkVersion 21
targetSdkVersion 34
// NOTE: always increase versionCode by 2 since automotive flavor uses versionCode + 1
versionCode 198
versionName "1.6.8"
versionCode 194
versionName "1.6.7"
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
resConfigs supportedLocales.split(',')

View File

@@ -37,9 +37,10 @@ class EvMapApplication : Application(), Configuration.Provider {
initAcra {
buildConfigClass = BuildConfig::class.java
reportFormat = StringFormat.JSON
if (BuildConfig.FLAVOR_automotive == "automotive") {
// Vehicles often don't have an email app, so use HTTP to send instead
reportFormat = StringFormat.JSON
httpSender {
uri = getString(R.string.acra_backend_url)
val creds = getString(R.string.acra_credentials).split(":")
@@ -48,7 +49,6 @@ class EvMapApplication : Application(), Configuration.Provider {
httpMethod = HttpSender.Method.POST
}
} else {
reportFormat = StringFormat.KEY_VALUE_LIST
mailSender {
mailTo = "evmap+crashreport@vonforst.net"
}

View File

@@ -105,19 +105,20 @@ class EnBwAvailabilityDetector(client: OkHttpClient, baseUrl: String? = null) :
var markers =
api.getMarkers(lng - coordRange, lng + coordRange, lat - coordRange, lat + coordRange)
markers = markers.flatMap {
if (it.grouped) {
api.getMarkers(
it.viewPort.lowerLeftLon,
it.viewPort.upperRightLon,
it.viewPort.lowerLeftLat,
it.viewPort.upperRightLat
)
} else {
listOf(it)
while (markers.any { it.grouped }) {
markers = markers.flatMap {
if (it.grouped) {
api.getMarkers(
it.viewPort.lowerLeftLon,
it.viewPort.upperRightLon,
it.viewPort.lowerLeftLat,
it.viewPort.upperRightLat
)
} else {
listOf(it)
}
}
}
if (markers.any { it.grouped }) throw AvailabilityDetectorException("markers still grouped")
val nearest = markers.minByOrNull { marker ->
distanceBetween(marker.lat, marker.lon, lat, lng)

View File

@@ -10,8 +10,10 @@ import android.text.Spanned
import androidx.car.app.CarContext
import androidx.car.app.CarToast
import androidx.car.app.Screen
import androidx.car.app.annotations.ExperimentalCarApi
import androidx.car.app.constraints.ConstraintManager
import androidx.car.app.model.*
import androidx.car.app.model.TabTemplate.TabCallback
import androidx.core.graphics.drawable.IconCompat
import androidx.core.graphics.scale
import androidx.core.text.HtmlCompat
@@ -48,7 +50,10 @@ import java.time.format.FormatStyle
import kotlin.math.roundToInt
@ExperimentalCarApi
class ChargerDetailScreen(ctx: CarContext, val chargerSparse: ChargeLocation) : Screen(ctx) {
private val TAB_MAIN = "main"
var charger: ChargeLocation? = null
var photo: Bitmap? = null
private var availability: ChargeLocationStatus? = null
@@ -68,6 +73,8 @@ class ChargerDetailScreen(ctx: CarContext, val chargerSparse: ChargeLocation) :
private val maxRows = ctx.getContentLimit(ConstraintManager.CONTENT_LIMIT_TYPE_PANE)
private val largeImageSupported =
ctx.carAppApiLevel >= 4 // since API 4, Row.setImage is supported
private val tabsSupported = ctx.carAppApiLevel >= 6
private var currentTab = TAB_MAIN
private var favorite: Favorite? = null
private var favoriteUpdateJob: Job? = null
@@ -79,6 +86,45 @@ class ChargerDetailScreen(ctx: CarContext, val chargerSparse: ChargeLocation) :
override fun onGetTemplate(): Template {
if (charger == null) loadCharger()
if (tabsSupported) {
return generateTabs()
} else {
return generateMainPane()
}
}
private fun generateTabs(): TabTemplate {
return TabTemplate.Builder(object : TabCallback {
override fun onTabSelected(tabContentId: String) {
currentTab = tabContentId
invalidate()
}
}).apply {
charger?.let {
addTab(
Tab.Builder()
.setTitle(carContext.getString(R.string.general_info))
.setIcon(CarIcon.APP_ICON)
.setContentId(TAB_MAIN).build()
)
addTab(
Tab.Builder()
.setTitle("bla")
.setIcon(CarIcon.APP_ICON)
.setContentId("bla").build()
)
val contents = when (currentTab) {
TAB_MAIN -> generateMainPane()
else -> throw IllegalArgumentException("invalid tab")
}
setTabContents(TabContents.Builder(contents).build())
setActiveTabContentId(currentTab)
} ?: setLoading(true)
setHeaderAction(Action.APP_ICON)
}.build()
}
private fun generateMainPane(): PaneTemplate {
return PaneTemplate.Builder(
Pane.Builder().apply {
charger?.let { charger ->
@@ -100,28 +146,28 @@ class ChargerDetailScreen(ctx: CarContext, val chargerSparse: ChargeLocation) :
)
.setTitle(carContext.getString(R.string.navigate))
.setFlags(Action.FLAG_PRIMARY)
.setBackgroundColor(CarColor.PRIMARY)
.setOnClickListener {
navigateToCharger(charger)
}
.build())
if (ChargepriceApi.isChargerSupported(charger)) {
addAction(
Action.Builder()
.setIcon(
CarIcon.Builder(
IconCompat.createWithResource(
carContext,
R.drawable.ic_chargeprice
)
).build()
)
.setTitle(carContext.getString(R.string.auto_prices))
.setBackgroundColor(CarColor.PRIMARY)
.setOnClickListener {
navigateToCharger(charger)
}
.build())
if (ChargepriceApi.isChargerSupported(charger)) {
addAction(
Action.Builder()
.setIcon(
CarIcon.Builder(
IconCompat.createWithResource(
carContext,
R.drawable.ic_chargeprice
)
).build()
)
.setTitle(carContext.getString(R.string.auto_prices))
.setOnClickListener {
screenManager.push(ChargepriceScreen(carContext, charger))
}
.build())
}
}
} ?: setLoading(true)
}.build()
).apply {
@@ -290,18 +336,6 @@ class ChargerDetailScreen(ctx: CarContext, val chargerSparse: ChargeLocation) :
}.build())
}
}
if (rows.count() < maxRows && charger.generalInformation != null) {
rows.add(Row.Builder().apply {
setTitle(carContext.getString(R.string.general_info))
addText(charger.generalInformation)
}.build())
}
if (rows.count() < maxRows && charger.amenities != null) {
rows.add(Row.Builder().apply {
setTitle(carContext.getString(R.string.amenities))
addText(charger.amenities)
}.build())
}
return rows
}

View File

@@ -1,8 +0,0 @@
Verbesserungen:
- Neue Einstellung für Maßeinheiten
- Anpassungen für Android 14
- Android Auto: Weitere Detailbeschreibungen zu den Ladestationen
- Android Auto: Löschbutton in der Filterliste
Fehler behoben:
- Fehler beim Laden der EnBW Echtzeitdaten

View File

@@ -1,8 +0,0 @@
Improvements:
- New setting for units of measurement
- Adjustments for Android 14
- Android Auto: More detailed descriptions of chargers
- Android Auto: Delete button in filter list
Bugfixes:
- Errors loading realtime data from EnBW