Compare commits

..

10 Commits

Author SHA1 Message Date
johan12345
9222dec613 Release 1.6.9 2023-09-14 20:26:08 +02:00
johan12345
71c36fbc8f MapFragment: Change default map location behavior
Only jump back to current location on app restart if we were previously looking at the current location (and have location permission enabled). Otherwise stay at the last viewed location.

This seems to be the same as what e.g. the Google Maps app does.

#191
2023-09-14 20:16:41 +02:00
johan12345
830477e664 Automotive FilterScreen: fix possible crash when profile is deleted 2023-09-13 22:44:23 +02:00
johan12345
3ce91a9c50 ChargerDetailScreen: fix nullability issue 2023-09-10 12:39:19 +02:00
johan12345
a3b2b94b25 ACRA: switch -normal build variants to use HTTP sending as well 2023-09-06 21:51:50 +02:00
johan12345
a7770e1c1b fix Github Actions build 2023-09-03 18:34:24 +02:00
johan12345
fcd51307cb Release 1.6.8 2023-09-03 18:11:57 +02:00
johan12345
ba4a9c29b2 ACRA: keep key-value format for email reports 2023-09-03 18:11:24 +02:00
johan12345
3463177ad2 EnBW: avoid endless loop introduced by d636cde7 2023-09-02 23:25:42 +02:00
johan12345
09deaf5080 AA/AAOS: add general info & amenities
(if room available)
2023-09-02 22:27:45 +02:00
12 changed files with 94 additions and 98 deletions

View File

@@ -32,6 +32,7 @@ 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 194
versionName "1.6.7"
versionCode 200
versionName "1.6.9"
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
resConfigs supportedLocales.split(',')
@@ -253,7 +253,6 @@ dependencies {
// ACRA (crash reporting)
def acraVersion = "5.11.1"
implementation("ch.acra:acra-mail:$acraVersion")
implementation("ch.acra:acra-http:$acraVersion")
implementation("ch.acra:acra-dialog:$acraVersion")
implementation("ch.acra:acra-limiter:$acraVersion")

View File

@@ -11,7 +11,6 @@ import net.vonforst.evmap.ui.updateNightMode
import org.acra.config.dialog
import org.acra.config.httpSender
import org.acra.config.limiter
import org.acra.config.mailSender
import org.acra.data.StringFormat
import org.acra.ktx.initAcra
import org.acra.sender.HttpSender
@@ -37,21 +36,14 @@ class EvMapApplication : Application(), Configuration.Provider {
initAcra {
buildConfigClass = BuildConfig::class.java
// Vehicles often don't have an email app, so use HTTP to send instead
reportFormat = StringFormat.JSON
if (BuildConfig.FLAVOR_automotive == "automotive") {
// Vehicles often don't have an email app, so use HTTP to send instead
httpSender {
uri = getString(R.string.acra_backend_url)
val creds = getString(R.string.acra_credentials).split(":")
basicAuthLogin = creds[0]
basicAuthPassword = creds[1]
httpMethod = HttpSender.Method.POST
}
} else {
mailSender {
mailTo = "evmap+crashreport@vonforst.net"
}
httpSender {
uri = getString(R.string.acra_backend_url)
val creds = getString(R.string.acra_credentials).split(":")
basicAuthLogin = creds[0]
basicAuthPassword = creds[1]
httpMethod = HttpSender.Method.POST
}
dialog {

View File

@@ -105,20 +105,19 @@ class EnBwAvailabilityDetector(client: OkHttpClient, baseUrl: String? = null) :
var markers =
api.getMarkers(lng - coordRange, lng + coordRange, lat - coordRange, lat + coordRange)
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)
}
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,10 +10,8 @@ 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
@@ -50,10 +48,7 @@ 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
@@ -73,8 +68,6 @@ 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
@@ -86,45 +79,6 @@ 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 ->
@@ -146,28 +100,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 {
@@ -336,6 +290,18 @@ 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
}
@@ -417,8 +383,10 @@ class ChargerDetailScreen(ctx: CarContext, val chargerSparse: ChargeLocation) :
} else {
append(nameForPlugType(carContext.stringProvider(), cp.type))
}
append(" ")
append(cp.formatPower())
cp.formatPower()?.let {
append(" ")
append(it)
}
}
availability?.status?.get(cp)?.let { status ->
chargepointsText.append(

View File

@@ -41,7 +41,9 @@ class FilterScreen(ctx: CarContext, val session: EVMapSession) : Screen(ctx) {
if (filterStatus in listOf(FILTERS_DISABLED, FILTERS_FAVORITES, FILTERS_CUSTOM)) {
page = 0
} else {
page = paginateProfiles(it).indexOfFirst { it.any { it.id == filterStatus } }
val index =
paginateProfiles(it).indexOfFirst { it.any { it.id == filterStatus } }
page = index.takeUnless { it == -1 } ?: 0
}
invalidate()
}

View File

@@ -1043,7 +1043,7 @@ class MapFragment : Fragment(), OnMapReadyCallback, MapsActivity.FragmentCallbac
binding.search.requestFocus()
binding.search.setSelection(locationName.length)
}
if (context.checkAnyLocationPermission()) {
if (context.checkAnyLocationPermission() && prefs.currentMapMyLocationEnabled) {
enableLocation(!positionSet, false)
positionSet = true
}
@@ -1400,6 +1400,9 @@ class MapFragment : Fragment(), OnMapReadyCallback, MapsActivity.FragmentCallbac
prefs.currentMapLocation = it.bounds.center
prefs.currentMapZoom = it.zoom
}
vm.myLocationEnabled.value?.let {
prefs.currentMapMyLocationEnabled = it
}
}
override fun onDestroy() {

View File

@@ -291,6 +291,12 @@ class PreferenceDataSource(val context: Context) {
sp.edit().putFloat("current_map_zoom", value).apply()
}
var currentMapMyLocationEnabled: Boolean
get() = sp.getBoolean("current_map_my_location_enabled", false)
set(value) {
sp.edit().putBoolean("current_map_my_location_enabled", value).apply()
}
var privacyAccepted: Boolean
get() = sp.getBoolean("privacy_accepted", false)
set(value) {

View File

@@ -0,0 +1,8 @@
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

@@ -0,0 +1,5 @@
Verbesserungen:
- Beim Start der App wird nun der zuletzt gesehene Kartenausschnitt gezeigt
Fehler behoben:
- Abstürze behoben

View File

@@ -0,0 +1,8 @@
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

View File

@@ -0,0 +1,5 @@
Improvements:
- When starting the app, the last viewed map area will be shown
Bugfixes:
- Fixed crashes