Compare commits

..

50 Commits

Author SHA1 Message Date
johan12345
0c5bd69205 Release 1.9.4 2024-06-21 00:25:13 +02:00
johan12345
72e98cf611 fix NoSuchElementExceptions in intent handling 2024-06-21 00:23:37 +02:00
johan12345
0fefffda2f update MapLibre
may help with #351
2024-06-21 00:19:38 +02:00
johan12345
49e555ef04 switch to fork of locale-config-x
fixes crash #352 until https://github.com/erfansn/locale-config-x/pull/2 is merged
2024-06-21 00:00:42 +02:00
johan12345
d6d1e915ee updated TeslaGuestApi 2024-06-19 00:19:36 +02:00
johan12345
546d7a11ce maybe fix rare NPE in GoingElectricAPI 2024-06-16 17:54:59 +02:00
johan12345
4849944c23 Release 1.9.3 2024-06-05 20:32:10 +02:00
johan12345
77b38661dd fix b9354e77: use correct exception type 2024-06-05 19:05:57 +02:00
johan12345
3723ee161b update AnyMaps
fixes issue where satellite map would not load correctly under some conditions
2024-06-04 21:41:26 +02:00
johan12345
1d3efe5295 update AnyMaps
fixes #346 through a5b09b5fda
2024-06-04 21:17:53 +02:00
johan12345
f011944135 fix lint error 2024-05-30 17:28:38 +02:00
johan12345
1d81bb5d37 Simplify currency handling
removes the need to translate all the currency names
2024-05-30 17:15:06 +02:00
johan12345
e8adb759a6 Simplify locale handling
using Locale Config X library
https://github.com/erfansn/locale-config-x
2024-05-30 16:52:02 +02:00
johan12345
f4384b4b60 update Android Gradle plugin 2024-05-30 13:10:20 +02:00
johan12345
1d63e37467 Release 1.9.2 2024-05-29 21:25:04 +02:00
johan12345
b5b0254bdd Coil: disable hardware acceleration for gallery images
https://github.com/coil-kt/coil/issues/159
2024-05-29 21:19:19 +02:00
johan12345
6514197920 upgrade dependencies 2024-05-29 21:06:30 +02:00
johan12345
4c5388350f upgrade car app library to stable 1.4.0 2024-05-29 20:33:32 +02:00
johan12345
20e9e43f0d upgrade coil library 2024-05-29 20:20:55 +02:00
johan12345
541646dda9 fix missing catch HttpException 2024-05-29 20:16:53 +02:00
johan12345
b9354e77a9 AAOS: fix crash when no navigation app is installed 2024-05-29 20:09:31 +02:00
johan12345
65fa54ef36 CarInfoWrapper: fix NPE 2024-05-29 19:57:29 +02:00
johan12345
6e419849b1 update sponsors 2024-05-25 16:38:33 +02:00
johan12345
c4c6f09a05 update sponsors 2024-05-25 16:23:24 +02:00
johan12345
3b602c03c4 update sponsors 2024-05-25 16:21:39 +02:00
Hosted Weblate
012e5d7362 Translated using Weblate (Portuguese)
Currently translated at 100.0% (367 of 367 strings)

Co-authored-by: Asmodeus <colligare1Asmodeum@gmail.com>
Co-authored-by: Hosted Weblate <hosted@weblate.org>
Translate-URL: https://hosted.weblate.org/projects/evmap/android/pt/
Translation: EVMap/Android
2024-05-25 13:17:28 +02:00
johan12345
4f5007ca0d fix czech string CDATA 2024-05-25 13:17:24 +02:00
Hosted Weblate
b40a74aa37 Translated using Weblate (Czech)
Currently translated at 100.0% (367 of 367 strings)

Translated using Weblate (Czech)

Currently translated at 100.0% (366 of 366 strings)

Co-authored-by: Fjuro <fjuro@alius.cz>
Co-authored-by: Hosted Weblate <hosted@weblate.org>
Translate-URL: https://hosted.weblate.org/projects/evmap/android/cs/
Translation: EVMap/Android
2024-05-25 13:16:40 +02:00
johan12345
ce172bd4b0 Release 1.9.1 2024-05-25 13:07:22 +02:00
johan12345
b3bbca576f revert to MapLibre 10.x
fixes #345
2024-05-25 12:59:34 +02:00
johan12345
72ccd99c1f re-release 1.9.0 for Play Store 2024-05-24 23:09:37 +02:00
johan12345
dd5c8659df fix declaration of car app category in manifest 2024-05-24 23:08:13 +02:00
johan12345
8f7f9e5a09 re-release 1.9.0 for Play Store
Car App Library alpha version is not accepted
2024-05-21 23:38:33 +02:00
johan12345
8256981b8d workaround for car app library crash with invalid speed units 2024-05-21 23:38:33 +02:00
johan12345
5649ef202f fix Android Auto version check 2024-05-21 23:38:33 +02:00
johan12345
ed9c729684 Revert "update car app library to 1.7.0-alpha02"
This reverts commit d540faa179.
2024-05-21 22:14:55 +02:00
johan12345
add66811ae Export licenses to CSV
needed for Faurecia Aptoide store
2024-05-20 23:10:26 +02:00
johan12345
2df5710910 Release 1.9.0 2024-05-20 22:04:09 +02:00
johan12345
a513a8d6d4 fix source sets for releaseAutomotivePackageName build type 2024-05-20 22:04:09 +02:00
johan12345
a55e4df62d hide Tesla referral link
referral program has ended
2024-05-20 21:08:18 +02:00
johan12345
d540faa179 update car app library to 1.7.0-alpha02 2024-05-20 20:39:29 +02:00
johan12345
3d69d3e50c update AGP 2024-05-20 00:18:39 +02:00
johan12345
fce27f0c19 add SVG for Play Store icon 2024-05-20 00:18:07 +02:00
johan12345
da3b9643bc add build type with different package name for fossAutomotive
needed for Faurecia Aptoide
2024-05-20 00:16:21 +02:00
johan12345
b690d9744d update Play Store icon according to new specs
https://developer.android.com/distribute/google-play/resources/icon-design-specifications
2024-05-20 00:16:21 +02:00
johan12345
70387ec350 fix docs in README 2024-05-19 17:55:47 +02:00
johan12345
5a331df232 add Jawg Maps sponsor logo 2024-05-19 17:53:20 +02:00
johan12345
5dc5e1f43f Migrate Mapbox -> MapLibre
Use Jawg Maps for basemap, ArcGIS for satellite maps

fixes #141
refs #169, #197

hide traffic checkbox if traffic is not supported by map
2024-05-19 17:53:20 +02:00
Hosted Weblate
360e7767bd Translated using Weblate (Portuguese)
Currently translated at 100.0% (366 of 366 strings)

Co-authored-by: Celso Azevedo <mail@celsoazevedo.com>
Co-authored-by: Hosted Weblate <hosted@weblate.org>
Translate-URL: https://hosted.weblate.org/projects/evmap/android/pt/
Translation: EVMap/Android
2024-05-08 22:27:16 +02:00
Jean-Baptiste
5f0c9fd31d Enable automatic per app language (#340)
* Enable automatic per app language

* fix getAppLocale

---------

Co-authored-by: johan12345 <johan.forstner@gmail.com>
2024-05-08 22:19:09 +02:00
56 changed files with 544 additions and 281 deletions

View File

@@ -34,3 +34,5 @@ jobs:
run: ./gradlew test${{ matrix.buildvariant }}DebugUnitTest --no-daemon
- name: Run Android Lint
run: ./gradlew lint${{ matrix.buildvariant }}Debug --no-daemon
- name: Check licenses
run: ./gradlew exportLibraryDefinitions --no-daemon

3
.gitignore vendored
View File

@@ -12,4 +12,5 @@ apikeys.xml
/app/**/*.apk
/_img/connectors/*.ai
api-7125266970515251116-798419-8e2dda660c80.json
output-metadata.json
output-metadata.json
licenses_*.csv

View File

@@ -43,13 +43,14 @@ EVMap uses and put them into the app in the form of a resource file called `apik
`app/src/main/res/values`. You can find more information on which API keys are necessary for which
features and how they can be obtained in our [documentation page](doc/api_keys.md).
There are three different build flavors, `googleNormal`, `fossNormal` and `googleAutomotive`.
There are four different build flavors, `googleNormal`, `fossNormal`, `googleAutomotive`, and
`fossAutomotive`.
- The `foss` variants only use OSM data and should run on most Android devices, even without
Google Play Services.
- `fossNormal` is intended to run on smartphones and tablets, and also includes the Android
Auto app for use on the car display (however for that to work, the Android Auto app is
necessary, which in turn does require Google Play Services).
Auto app for use on the car display (however Android Auto may not work if the app is not
installed from Google Play, see https://github.com/ev-map/EVMap/issues/319).
- `fossAutomotive` can be installed directly on
[Android Automotive OS (AAOS)](https://source.android.com/docs/automotive/start/what_automotive)
headunits without Google services.
@@ -83,6 +84,17 @@ into new languages.
Sponsors
--------
Many users currently support the development EVMap with their donations. You can find more
information on the [Donate page](https://ev-map.app/donate/) on the EVMap website.
<a href="https://www.jawg.io"><img src="https://www.jawg.io/static/Blue@10x-9cdc4596e4e59acbd9ead55e9c28613e.png" alt="JawgMaps" height="58"/></a><br>
Since mid 2024, **JawgMaps** provides their OpenStreetMap vector map tiles service to EVMap for
free, i.e. the background map displayed in the app if OpenStreetMap is selected as the data source.
Since May 2024, **JawgMaps** provides their OpenStreetMap vector map tiles service to EVMap for
free, i.e. the background map displayed in the app if OpenStreetMap is selected as the data source.
<a href="https://chargeprice.app"><img src="https://raw.githubusercontent.com/ev-map/EVMap/master/_img/powered_by_chargeprice.svg" alt="Powered by Chargeprice" height="58"/></a><br>
Since April 2021, **Chargeprice.app** provide their price comparison API at a greatly reduced
price for EVMap. This data is used in EVMap's price comparison feature.
<a href="https://fronyx.io/"><img src="https://github.com/ev-map/EVMap/blob/master/_img/powered_by_fronyx.svg" alt="Powered by Fronyx" height="68"/></a><br>
Since September 2022, for certain charging stations, **Fronyx** provide us free access to their API
for availability predictions.

View File

Binary file not shown.

Before

Width:  |  Height:  |  Size: 24 KiB

After

Width:  |  Height:  |  Size: 14 KiB

View File

@@ -0,0 +1,73 @@
<?xml version="1.0" encoding="UTF-8"?>
<svg id="Ebene_2" data-name="Ebene 2" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512">
<defs>
<style>
.cls-1 {
fill: #00e676;
}
.cls-1, .cls-2, .cls-3, .cls-4, .cls-5, .cls-6, .cls-7, .cls-8 {
stroke-width: 0px;
}
.cls-2 {
fill: rgba(255, 255, 255, .2);
}
.cls-3 {
fill: #ffb300;
}
.cls-4 {
fill: #000;
isolation: isolate;
opacity: .45;
}
.cls-5 {
fill: #fff;
}
.cls-6 {
fill: #90a4ae;
}
.cls-7 {
fill: #546e7a;
}
.cls-8 {
fill: rgba(62, 39, 35, .2);
}
</style>
</defs>
<g id="Layer_1" data-name="Layer 1">
<g>
<rect class="cls-5" width="512" height="512" />
<g>
<g>
<path class="cls-3"
d="M159.42,338.98l-6.43-56.15-9.81,1.01,6.43,56.15,9.81-1.01ZM194.26,334.92l-6.43-56.15-9.81,1.01,6.43,56.15,9.81-1.01Z" />
<path class="cls-6"
d="M212.53,411.37c-3.04,3.72-5.41,6.09-5.75,6.43-8.79,7.1-15.9,9.13-21.65,6.43-10.15-5.07-9.47-24.02-9.13-26.05l7.1.34c-.34,5.41.68,16.91,5.41,19.28,2.71,1.35,7.44-.34,13.53-5.41h0s19.62-19.62,15.56-35.18c-4.74-18.6,16.91-45.33,24.02-54.46l1.01-1.01,5.75,4.4-1.01,1.35c-21.99,27.06-24.35,40.93-22.66,48.03,3.38,13.53-5.75,28.08-12.18,35.85Z" />
<path class="cls-6"
d="M137.78,338.3l2.71,23,21.31,14.21,28.75-3.04,17.59-18.6-2.71-23-67.65,7.44Z" />
<path class="cls-7"
d="M190.21,372.47l-28.75,3.04,6.09,25.37,22.66-2.71v-25.71h0ZM210.84,311.58l2.37,20.97-82.53,9.47-2.37-20.97,82.53-9.47Z" />
</g>
<g>
<g>
<path class="cls-1"
d="M275.45,80.22c-59.19,0-107.23,48.03-107.23,107.23,0,80.84,90.31,123.12,101.14,238.47.34,3.38,3.04,5.75,6.43,5.75s6.09-2.37,6.43-5.75c10.82-115.34,101.14-157.63,101.14-238.47-.68-59.53-48.71-107.23-107.9-107.23Z" />
<path class="cls-2"
d="M275.45,82.58c58.86,0,106.55,47.36,107.23,105.87v-1.01c0-59.19-48.03-107.23-107.23-107.23s-107.23,47.69-107.23,107.23v1.01c.68-58.52,48.37-105.87,107.23-105.87h0Z" />
<path class="cls-8"
d="M281.87,423.21c-.34,3.38-3.04,5.75-6.43,5.75s-6.09-2.37-6.43-5.75c-10.49-115.01-100.12-157.29-100.8-237.12v1.69c0,80.84,90.31,123.12,101.14,238.47.34,3.38,3.04,5.75,6.43,5.75s6.09-2.37,6.43-5.75c10.82-115.34,101.14-157.63,101.14-238.47v-1.69c-1.35,79.83-90.99,122.11-101.48,237.12h0Z" />
</g>
<path class="cls-4"
d="M250.75,135.01v64.94h17.59v53.11l41.27-71.03h-23.68l23.68-47.36c.34.34-58.86.34-58.86.34Z" />
</g>
</g>
</g>
</g>
</svg>

After

Width:  |  Height:  |  Size: 3.1 KiB

View File

@@ -0,0 +1,23 @@
import subprocess
import json
build_types = ["fossNormalRelease", "fossAutomotiveRelease"]
for build_type in build_types:
result = subprocess.run(["gradlew.bat", f"generateLibraryDefinitions{build_type.capitalize()}"],
capture_output=True)
data = json.load(
open(f"app/build/generated/aboutLibraries/{build_type}/res/raw/aboutlibraries.json"))
with open(f"licenses_{build_type}.csv", "w") as f:
f.write("component_name;license_title;license_url;public_repository;copyrights\n")
for lib in data["libraries"]:
license = data["licenses"][lib["licenses"][0]] if len(lib["licenses"]) > 0 else None
license_name = license["name"] if license is not None else " "
license_url = license["url"] if license is not None else " "
copyrights = ", ".join([dev["name"] for dev in lib["developers"] if "name" in dev])
if copyrights == "":
copyrights = " "
repo_url = lib['scm']['url'] if 'scm' in lib else ''
f.write(f"{lib['name']};{license_name};{license_url};\"{copyrights}\";{repo_url}\n")

View File

@@ -10,21 +10,20 @@ plugins {
id("com.mikepenz.aboutlibraries.plugin")
}
val supportedLocales = "en,de,fr,nb-rNO,nl,pt,ro,cs"
android {
useLibrary("android.car")
defaultConfig {
applicationId = "net.vonforst.evmap"
compileSdk = 34
minSdk = 21
targetSdk = 34
// NOTE: always increase versionCode by 2 since automotive flavor uses versionCode + 1
versionCode = 212
versionName = "1.8.2"
versionCode = 226
versionName = "1.9.4"
testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner"
resourceConfigurations += supportedLocales.split(",")
buildConfigField("String", "supportedLocales", "\"$supportedLocales\"")
}
signingConfigs {
@@ -49,12 +48,21 @@ android {
)
signingConfig = signingConfigs.getByName("release")
}
create("releaseAutomotivePackageName") {
// Faurecia Aptoide requires the automotive variant to use a separate package name
initWith(getByName("release"))
applicationIdSuffix = ".automotive"
}
debug {
applicationIdSuffix = ".debug"
isDebuggable = true
}
}
sourceSets {
getByName("releaseAutomotivePackageName").setRoot("src/release")
}
flavorDimensions += listOf("dependencies", "automotive")
productFlavors {
create("foss") {
@@ -100,6 +108,9 @@ android {
disable += listOf("NullSafeMutableLiveData")
warning += listOf("MissingTranslation")
}
androidResources {
generateLocaleConfig = true
}
testOptions {
unitTests {
@@ -218,6 +229,22 @@ android {
}
}
androidComponents {
beforeVariants { variantBuilder ->
if (variantBuilder.buildType == "releaseAutomotivePackageName"
&& !variantBuilder.productFlavors.containsAll(
listOf(
"automotive" to "automotive",
"dependencies" to "foss"
)
)
) {
// releaseAutomotivePackageName type is only needed for fossAutomotive
variantBuilder.enable = false
}
}
}
configurations {
create("googleNormalImplementation") {}
create("googleAutomotiveImplementation") {}
@@ -225,10 +252,14 @@ configurations {
aboutLibraries {
allowedLicenses = arrayOf(
"Apache-2.0", "mit", "BSD-2-Clause",
"Apache-2.0", "mit", "BSD-2-Clause", "BSD-3-Clause", "EPL-1.0",
"asdkl", // Android SDK
"Dual OpenSSL and SSLeay License", // Android NDK OpenSSL
"Google Maps Platform Terms of Service" // Google Maps SDK
"Google Maps Platform Terms of Service", // Google Maps SDK
"provided without support or warranty", // org.json
"Unicode/ICU License", // icu4j
"Bouncy Castle Licence", // bcprov
"CDDL + GPLv2 with classpath exception", // javax.annotation-api
)
strictMode = com.mikepenz.aboutlibraries.plugin.StrictMode.FAIL
}
@@ -244,29 +275,29 @@ dependencies {
val testGoogleImplementation by configurations
implementation("org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlinVersion")
implementation("androidx.appcompat:appcompat:1.6.1")
implementation("androidx.core:core-ktx:1.12.0")
implementation("androidx.appcompat:appcompat:1.7.0")
implementation("androidx.core:core-ktx:1.13.1")
implementation("androidx.core:core-splashscreen:1.0.1")
implementation("androidx.activity:activity-ktx:1.8.2")
implementation("androidx.fragment:fragment-ktx:1.6.2")
implementation("androidx.activity:activity-ktx:1.9.0")
implementation("androidx.fragment:fragment-ktx:1.7.1")
implementation("androidx.cardview:cardview:1.0.0")
implementation("androidx.preference:preference-ktx:1.2.1")
implementation("com.google.android.material:material:1.11.0")
implementation("com.google.android.material:material:1.12.0")
implementation("androidx.constraintlayout:constraintlayout:2.1.4")
implementation("androidx.recyclerview:recyclerview:1.3.2")
implementation("androidx.browser:browser:1.7.0")
implementation("androidx.browser:browser:1.8.0")
implementation("androidx.swiperefreshlayout:swiperefreshlayout:1.1.0")
implementation("androidx.security:security-crypto:1.1.0-alpha06")
implementation("androidx.work:work-runtime-ktx:2.9.0")
implementation("com.github.ev-map:CustomBottomSheetBehavior:e48f73ea7b")
implementation("com.squareup.retrofit2:retrofit:2.9.0")
implementation("com.squareup.retrofit2:converter-moshi:2.9.0")
implementation("com.squareup.okhttp3:okhttp:4.11.0")
implementation("com.squareup.okhttp3:okhttp-urlconnection:4.11.0")
implementation("com.squareup.okhttp3:okhttp:4.12.0")
implementation("com.squareup.okhttp3:okhttp-urlconnection:4.12.0")
implementation("com.squareup.moshi:moshi-kotlin:1.15.0")
implementation("com.squareup.moshi:moshi-adapters:1.15.0")
implementation("com.markomilos.jsonapi:jsonapi-retrofit:1.1.0")
implementation("io.coil-kt:coil:2.4.0")
implementation("io.coil-kt:coil:2.6.0")
implementation("com.github.ev-map:StfalconImageViewer:5082ebd392")
implementation("com.mikepenz:aboutlibraries-core:$aboutLibsVersion")
implementation("com.mikepenz:aboutlibraries:$aboutLibsVersion")
@@ -275,22 +306,29 @@ dependencies {
implementation("com.google.guava:guava:29.0-android")
implementation("com.github.pengrad:mapscaleview:1.6.0")
implementation("com.github.romandanylyk:PageIndicatorView:b1bad589b5")
implementation("com.github.ev-map:locale-config-x:e9e56b4111")
// Android Auto
val carAppVersion = "1.4.0-rc02"
val carAppVersion = "1.4.0"
implementation("androidx.car.app:app:$carAppVersion")
normalImplementation("androidx.car.app:app-projected:$carAppVersion")
automotiveImplementation("androidx.car.app:app-automotive:$carAppVersion")
// AnyMaps
val anyMapsVersion = "c087b3e7c2"
val anyMapsVersion = "1e00650bc7"
implementation("com.github.ev-map.AnyMaps:anymaps-base:$anyMapsVersion")
googleImplementation("com.github.ev-map.AnyMaps:anymaps-google:$anyMapsVersion")
googleImplementation("com.google.android.gms:play-services-maps:18.2.0")
implementation("com.github.ev-map.AnyMaps:anymaps-maplibre:$anyMapsVersion")
implementation("com.github.ev-map.AnyMaps:anymaps-maplibre:$anyMapsVersion") {
// duplicates classes from mapbox-sdk-services
exclude("org.maplibre.gl", "android-sdk-geojson")
}
implementation("org.maplibre.gl:android-sdk:10.3.2-pre2") {
exclude("org.maplibre.gl", "android-sdk-geojson")
}
// Google Places
googleImplementation("com.google.android.libraries.places:places:3.3.0")
googleImplementation("com.google.android.libraries.places:places:3.5.0")
googleImplementation("org.jetbrains.kotlinx:kotlinx-coroutines-play-services:1.7.3")
// Mapbox Geocoding
@@ -301,7 +339,7 @@ dependencies {
implementation("androidx.navigation:navigation-ui-ktx:$navVersion")
// viewmodel library
val lifecycle_version = "2.6.2"
val lifecycle_version = "2.8.1"
implementation("androidx.lifecycle:lifecycle-viewmodel-ktx:$lifecycle_version")
implementation("androidx.lifecycle:lifecycle-livedata-ktx:$lifecycle_version")
@@ -316,7 +354,7 @@ dependencies {
implementation("com.github.EV-map:android-spatialite:e5495c83ad") // version with minSdk increased to 21 & FORTIFY_SOURCE enabled
// billing library
val billing_version = "6.1.0"
val billing_version = "7.0.0"
googleImplementation("com.android.billingclient:billing:$billing_version")
googleImplementation("com.android.billingclient:billing-ktx:$billing_version")
@@ -333,7 +371,7 @@ dependencies {
// testing
testImplementation("junit:junit:4.13.2")
testImplementation("com.squareup.okhttp3:mockwebserver:4.11.0")
testImplementation("com.squareup.okhttp3:mockwebserver:4.12.0")
//noinspection GradleDependency
testImplementation("org.json:json:20080701")
testImplementation("org.robolectric:robolectric:4.11.1")

View File

@@ -0,0 +1,171 @@
import android.car.Car
import android.car.VehiclePropertyIds
import android.car.VehicleUnit
import android.car.hardware.CarPropertyValue
import android.car.hardware.property.CarPropertyManager
import android.car.hardware.property.CarPropertyManager.CarPropertyEventCallback
import androidx.annotation.OptIn
import androidx.car.app.CarContext
import androidx.car.app.annotations.ExperimentalCarApi
import androidx.car.app.hardware.CarHardwareManager
import androidx.car.app.hardware.common.CarUnit
import androidx.car.app.hardware.common.CarValue
import androidx.car.app.hardware.common.OnCarDataAvailableListener
import androidx.car.app.hardware.info.CarInfo
import androidx.car.app.hardware.info.EnergyLevel
import androidx.car.app.hardware.info.EnergyProfile
import androidx.car.app.hardware.info.EvStatus
import androidx.car.app.hardware.info.Mileage
import androidx.car.app.hardware.info.Model
import androidx.car.app.hardware.info.Speed
import androidx.car.app.hardware.info.TollCard
import java.util.concurrent.Executor
val CarContext.patchedCarInfo: CarInfo
get() = CarInfoWrapper(this)
class CarInfoWrapper(ctx: CarContext) : CarInfo {
private val wrapped =
(ctx.getCarService(CarContext.HARDWARE_SERVICE) as CarHardwareManager).carInfo
private val carPropertyManager = try {
val car = Car.createCar(ctx)
car.getCarManager(Car.PROPERTY_SERVICE) as CarPropertyManager
} catch (e: NoClassDefFoundError) {
null
}
private val callbacks = mutableMapOf<OnCarDataAvailableListener<*>, CarPropertyEventCallback>()
override fun fetchModel(executor: Executor, listener: OnCarDataAvailableListener<Model>) =
wrapped.fetchModel(executor, listener)
override fun fetchEnergyProfile(
executor: Executor,
listener: OnCarDataAvailableListener<EnergyProfile>
) = wrapped.fetchEnergyProfile(executor, listener)
override fun addTollListener(
executor: Executor,
listener: OnCarDataAvailableListener<TollCard>
) = wrapped.addTollListener(executor, listener)
override fun removeTollListener(listener: OnCarDataAvailableListener<TollCard>) =
wrapped.removeTollListener(listener)
override fun addEnergyLevelListener(
executor: Executor,
listener: OnCarDataAvailableListener<EnergyLevel>
) = wrapped.addEnergyLevelListener(executor, listener)
override fun removeEnergyLevelListener(listener: OnCarDataAvailableListener<EnergyLevel>) =
wrapped.removeEnergyLevelListener(listener)
override fun addSpeedListener(executor: Executor, listener: OnCarDataAvailableListener<Speed>) {
// TODO: This is a emporary workaround until Car App Library 1.7.0 is released - previous versions would crash if the car reported an invalid speed display unit
carPropertyManager ?: return
val callback = object : CarPropertyEventCallback {
private var speedRaw: CarPropertyValue<Float>? = null
private var speedDisplay: CarPropertyValue<Float>? = null
private var speedUnit: CarPropertyValue<Int>? = null
override fun onChangeEvent(value: CarPropertyValue<*>?) {
when (value?.propertyId) {
VehiclePropertyIds.PERF_VEHICLE_SPEED -> speedRaw =
value as CarPropertyValue<Float>?
VehiclePropertyIds.PERF_VEHICLE_SPEED_DISPLAY -> speedDisplay =
value as CarPropertyValue<Float>?
VehiclePropertyIds.VEHICLE_SPEED_DISPLAY_UNITS -> speedUnit =
value as CarPropertyValue<Int>?
}
executor.execute {
listener.onCarDataAvailable(Speed.Builder().apply {
speedRaw?.let {
setRawSpeedMetersPerSecond(
CarValue(
it.value,
it.timestamp,
if (it.value != null) CarValue.STATUS_SUCCESS else CarValue.STATUS_UNKNOWN
)
)
}
speedDisplay?.let {
setDisplaySpeedMetersPerSecond(
CarValue(
it.value,
it.timestamp,
if (it.value != null) CarValue.STATUS_SUCCESS else CarValue.STATUS_UNKNOWN
)
)
}
speedUnit?.let {
val unit = when (it.value) {
VehicleUnit.METER_PER_SEC -> CarUnit.METERS_PER_SEC
VehicleUnit.MILES_PER_HOUR -> CarUnit.MILES_PER_HOUR
VehicleUnit.KILOMETERS_PER_HOUR -> CarUnit.KILOMETERS_PER_HOUR
else -> null
}
setSpeedDisplayUnit(
CarValue(
unit,
it.timestamp,
if (unit != null) CarValue.STATUS_SUCCESS else CarValue.STATUS_UNKNOWN
)
)
}
}.build())
}
}
override fun onErrorEvent(propertyId: Int, areaId: Int) {
listener.onCarDataAvailable(
Speed.Builder()
.setRawSpeedMetersPerSecond(CarValue(null, 0, CarValue.STATUS_UNKNOWN))
.setDisplaySpeedMetersPerSecond(CarValue(null, 0, CarValue.STATUS_UNKNOWN))
.setSpeedDisplayUnit(CarValue(null, 0, CarValue.STATUS_UNKNOWN))
.build()
)
}
}
carPropertyManager.registerCallback(
callback,
VehiclePropertyIds.PERF_VEHICLE_SPEED,
CarPropertyManager.SENSOR_RATE_NORMAL
)
carPropertyManager.registerCallback(
callback,
VehiclePropertyIds.PERF_VEHICLE_SPEED_DISPLAY,
CarPropertyManager.SENSOR_RATE_NORMAL
)
carPropertyManager.registerCallback(
callback,
VehiclePropertyIds.VEHICLE_SPEED_DISPLAY_UNITS,
CarPropertyManager.SENSOR_RATE_NORMAL
)
}
override fun removeSpeedListener(listener: OnCarDataAvailableListener<Speed>) {
val callback = callbacks[listener] ?: return
carPropertyManager?.unregisterCallback(callback)
}
override fun addMileageListener(
executor: Executor,
listener: OnCarDataAvailableListener<Mileage>
) = wrapped.addMileageListener(executor, listener)
override fun removeMileageListener(listener: OnCarDataAvailableListener<Mileage>) =
wrapped.removeMileageListener(listener)
@OptIn(ExperimentalCarApi::class)
override fun addEvStatusListener(
executor: Executor,
listener: OnCarDataAvailableListener<EvStatus>
) = wrapped.addEvStatusListener(executor, listener)
@OptIn(ExperimentalCarApi::class)
override fun removeEvStatusListener(listener: OnCarDataAvailableListener<EvStatus>) =
wrapped.removeEvStatusListener(listener)
}

View File

@@ -41,8 +41,7 @@
android:label="@string/app_name"
android:roundIcon="@mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="@style/AppTheme"
android:localeConfig="@xml/locales_config">
android:theme="@style/AppTheme">
<meta-data
android:name="com.mapbox.ACCESS_TOKEN"
@@ -348,9 +347,8 @@
android:exported="true"
android:foregroundServiceType="location">
<intent-filter>
<action
android:name="androidx.car.app.CarAppService"
android:category="androidx.car.app.category.POI" />
<action android:name="androidx.car.app.CarAppService" />
<category android:name="androidx.car.app.category.POI" />
</intent-filter>
<intent-filter>
<action android:name="android.intent.action.VIEW" />

View File

@@ -3,7 +3,11 @@ package net.vonforst.evmap
import android.app.Activity
import android.app.Application
import android.os.Build
import androidx.work.*
import androidx.work.Configuration
import androidx.work.Constraints
import androidx.work.ExistingPeriodicWorkPolicy
import androidx.work.PeriodicWorkRequestBuilder
import androidx.work.WorkManager
import net.vonforst.evmap.storage.CleanupCacheWorker
import net.vonforst.evmap.storage.PreferenceDataSource
import net.vonforst.evmap.ui.updateAppLocale
@@ -24,7 +28,7 @@ class EvMapApplication : Application(), Configuration.Provider {
// Convert to new AppCompat storage for app language
val lang = prefs.language
if (lang != null && lang !in listOf("", "default")) {
if (lang != null) {
updateAppLocale(lang)
prefs.language = null
}

View File

@@ -136,7 +136,7 @@ class MapsActivity : AppCompatActivity(),
.createPendingIntent()
}
} else if (intent?.scheme == "https" && intent?.data?.host == "www.goingelectric.de") {
val id = intent.data?.pathSegments?.last()?.toLongOrNull()
val id = intent.data?.pathSegments?.lastOrNull()?.toLongOrNull()
if (id != null) {
if (prefs.dataSource != "goingelectric") {
prefs.dataSource = "goingelectric"
@@ -157,7 +157,7 @@ class MapsActivity : AppCompatActivity(),
}
} else if (intent?.scheme == "https" && intent?.data?.host in listOf("openchargemap.org", "map.openchargemap.io")) {
val id = when (intent.data?.host) {
"openchargemap.org" -> intent.data?.pathSegments?.last()?.toLongOrNull()
"openchargemap.org" -> intent.data?.pathSegments?.lastOrNull()?.toLongOrNull()
"map.openchargemap.io" -> intent.data?.getQueryParameter("id")?.toLongOrNull()
else -> null
}

View File

@@ -17,6 +17,7 @@ import android.text.SpannedString
import android.text.TextUtils
import android.text.style.StyleSpan
import net.vonforst.evmap.storage.PreferenceDataSource
import java.util.Currency
import java.util.Locale
fun Bundle.optDouble(name: String): Double? {
@@ -139,4 +140,6 @@ fun PackageManager.isAppInstalled(packageName: String): Boolean {
} catch (e: PackageManager.NameNotFoundException) {
false
}
}
}
fun currencyDisplayName(code: String) = "${Currency.getInstance(code).displayName} ($code)"

View File

@@ -9,7 +9,6 @@ import androidx.core.text.buildSpannedString
import net.vonforst.evmap.R
import net.vonforst.evmap.api.availability.tesla.Pricing
import net.vonforst.evmap.api.availability.tesla.Rates
import net.vonforst.evmap.api.availability.tesla.TeslaChargingOwnershipGraphQlApi
import net.vonforst.evmap.bold
import net.vonforst.evmap.joinToSpannedString
import net.vonforst.evmap.model.ChargeCard

View File

@@ -12,7 +12,6 @@ import androidx.recyclerview.widget.ListAdapter
import androidx.recyclerview.widget.RecyclerView
import coil.load
import coil.memory.MemoryCache
import net.vonforst.evmap.BuildConfig
import net.vonforst.evmap.R
import net.vonforst.evmap.model.ChargerPhoto
@@ -71,7 +70,7 @@ class GalleryAdapter(context: Context, val itemClickListener: ItemClickListener?
memoryKeys[item.id] = metadata.memoryCacheKey
}
)
allowHardware(!BuildConfig.DEBUG)
allowHardware(false)
}
}
}

View File

@@ -52,32 +52,31 @@ class TeslaGuestAvailabilityDetector(
val (detailsA, guestPricing) = coroutineScope {
val details = async {
api.getChargingSiteDetails(
TeslaChargingGuestGraphQlApi.GetChargingSiteDetailsRequest(
TeslaChargingGuestGraphQlApi.GetChargingSiteInformationVariables(
api.getSiteDetails(
TeslaChargingGuestGraphQlApi.GetSiteDetailsRequest(
TeslaChargingGuestGraphQlApi.GetSiteDetailsVariables(
TeslaChargingGuestGraphQlApi.Identifier(
TeslaChargingGuestGraphQlApi.ChargingSiteIdentifier(
trtId
trtId, TeslaChargingGuestGraphQlApi.Experience.ADHOC
)
),
TeslaChargingGuestGraphQlApi.Experience.ADHOC
)
)
).data.site ?: throw AvailabilityDetectorException("no candidates found.")
).data.chargingNetwork?.site
?: throw AvailabilityDetectorException("no candidates found.")
}
val guestPricing = async {
api.getChargingSiteDetails(
TeslaChargingGuestGraphQlApi.GetChargingSiteDetailsRequest(
TeslaChargingGuestGraphQlApi.GetChargingSiteInformationVariables(
api.getSiteDetails(
TeslaChargingGuestGraphQlApi.GetSiteDetailsRequest(
TeslaChargingGuestGraphQlApi.GetSiteDetailsVariables(
TeslaChargingGuestGraphQlApi.Identifier(
TeslaChargingGuestGraphQlApi.ChargingSiteIdentifier(
trtId
trtId, TeslaChargingGuestGraphQlApi.Experience.GUEST
)
),
TeslaChargingGuestGraphQlApi.Experience.GUEST
)
)
).data.site?.pricing
).data.chargingNetwork?.site?.pricing
}
details to guestPricing
}
@@ -103,12 +102,9 @@ class TeslaGuestAvailabilityDetector(
"charger has unknown connectors"
)
val chargerDetails = details.chargersAvailable.chargerDetails
val chargers = details.chargers.associateBy { it.id }
var detailsSorted = chargerDetails
.sortedBy { chargers[it.id]?.labelLetter }
.sortedBy { chargers[it.id]?.labelNumber }
var detailsSorted = details.chargerList
.sortedBy { c -> c.labelLetter }
.sortedBy { c -> c.labelNumber }
if (detailsSorted.size != scV2Connectors.sumOf { it.count } + scV3Connectors.sumOf { it.count }) {
// apparently some connectors are missing in Tesla data
@@ -120,7 +116,7 @@ class TeslaGuestAvailabilityDetector(
detailsSorted + List(numMissing) {
TeslaChargingGuestGraphQlApi.ChargerDetail(
ChargerAvailability.UNKNOWN,
""
"", ""
)
}
} else {
@@ -151,7 +147,7 @@ class TeslaGuestAvailabilityDetector(
}
val statusMap = detailsMap.mapValues { it.value.map { it.availability.toStatus() } }
val labelsMap = detailsMap.mapValues { it.value.map { chargers[it.id]?.label } }
val labelsMap = detailsMap.mapValues { it.value.map { it.label } }
val pricing = details.pricing.copy(memberRates = guestPricing.await()?.userRates)

View File

@@ -1,12 +1,8 @@
package net.vonforst.evmap.api.availability.tesla
import com.squareup.moshi.Json
import com.squareup.moshi.JsonAdapter
import com.squareup.moshi.JsonClass
import com.squareup.moshi.JsonReader
import com.squareup.moshi.JsonWriter
import com.squareup.moshi.Moshi
import com.squareup.moshi.Types
import okhttp3.CacheControl
import okhttp3.OkHttpClient
import retrofit2.Retrofit
@@ -15,7 +11,6 @@ import retrofit2.http.Body
import retrofit2.http.GET
import retrofit2.http.POST
import retrofit2.http.Query
import java.lang.reflect.Type
import java.util.concurrent.TimeUnit
interface TeslaCuaApi {
@@ -71,24 +66,22 @@ interface TeslaCuaApi {
interface TeslaChargingGuestGraphQlApi {
@POST("graphql")
suspend fun getChargingSiteDetails(
@Body request: GetChargingSiteDetailsRequest,
@Query("operationName") operationName: String = "getGuestChargingSiteDetails"
suspend fun getSiteDetails(
@Body request: GetSiteDetailsRequest,
@Query("operationName") operationName: String = "GetSiteDetails"
): GetChargingSiteDetailsResponse
@JsonClass(generateAdapter = true)
data class GetChargingSiteDetailsRequest(
override val variables: GetChargingSiteInformationVariables,
override val operationName: String = "getGuestChargingSiteDetails",
data class GetSiteDetailsRequest(
override val variables: GetSiteDetailsVariables,
override val operationName: String = "GetSiteDetails",
override val query: String =
"\n query getGuestChargingSiteDetails(\$identifier: ChargingSiteIdentifierInput!, \$deviceLocale: String!, \$experience: ChargingExperienceEnum!) {\n site(\n identifier: \$identifier\n deviceLocale: \$deviceLocale\n experience: \$experience\n ) {\n activeOutages\n address {\n countryCode\n }\n chargers {\n id\n label\n }\n chargersAvailable {\n chargerDetails {\n id\n availability\n }\n }\n holdAmount {\n holdAmount\n currencyCode\n }\n maxPowerKw\n name\n programType\n publicStallCount\n id\n pricing(experience: \$experience) {\n userRates {\n activePricebook {\n charging {\n uom\n rates\n buckets {\n start\n end\n }\n bucketUom\n currencyCode\n programType\n vehicleMakeType\n touRates {\n enabled\n activeRatesByTime {\n startTime\n endTime\n rates\n }\n }\n }\n parking {\n uom\n rates\n buckets {\n start\n end\n }\n bucketUom\n currencyCode\n programType\n vehicleMakeType\n touRates {\n enabled\n activeRatesByTime {\n startTime\n endTime\n rates\n }\n }\n }\n congestion {\n uom\n rates\n buckets {\n start\n end\n }\n bucketUom\n currencyCode\n programType\n vehicleMakeType\n touRates {\n enabled\n activeRatesByTime {\n startTime\n endTime\n rates\n }\n }\n }\n }\n }\n }\n }\n}\n "
"\n query GetSiteDetails(\$siteId: SiteIdInput!) {\n chargingNetwork {\n site(siteId: \$siteId) {\n address {\n countryCode\n }\n chargerList {\n id\n label\n availability\n }\n holdAmount {\n amount\n currencyCode\n }\n maxPowerKw\n name\n programType\n publicStallCount\n trtId\n pricing {\n userRates {\n activePricebook {\n charging {\n ...ChargingRate\n }\n parking {\n ...ChargingRate\n }\n congestion {\n ...ChargingRate\n }\n }\n }\n }\n }\n }\n}\n \n fragment ChargingRate on ChargingUserRate {\n uom\n rates\n buckets {\n start\n end\n }\n bucketUom\n currencyCode\n programType\n vehicleMakeType\n touRates {\n enabled\n activeRatesByTime {\n startTime\n endTime\n rates\n }\n }\n}\n "
) : GraphQlRequest()
@JsonClass(generateAdapter = true)
data class GetChargingSiteInformationVariables(
val identifier: Identifier,
val experience: Experience,
val deviceLocale: String = "de-DE",
data class GetSiteDetailsVariables(
val siteId: Identifier,
)
enum class Experience {
@@ -97,22 +90,22 @@ interface TeslaChargingGuestGraphQlApi {
@JsonClass(generateAdapter = true)
data class Identifier(
val siteId: ChargingSiteIdentifier
val byTrtId: ChargingSiteIdentifier
)
@JsonClass(generateAdapter = true)
data class ChargingSiteIdentifier(
val id: Long,
val siteType: SiteType = SiteType.SUPERCHARGER
val trtId: Long,
val chargingExperience: Experience,
val programType: String = "PTSCH",
val locale: String = "de-DE",
)
enum class SiteType {
@Json(name = "SITE_TYPE_SUPERCHARGER")
SUPERCHARGER
}
@JsonClass(generateAdapter = true)
data class GetChargingSiteDetailsResponse(val data: GetChargingSiteDetailsResponseDataNetwork)
@JsonClass(generateAdapter = true)
data class GetChargingSiteDetailsResponse(val data: GetChargingSiteDetailsResponseData)
data class GetChargingSiteDetailsResponseDataNetwork(val chargingNetwork: GetChargingSiteDetailsResponseData?)
@JsonClass(generateAdapter = true)
data class GetChargingSiteDetailsResponseData(val site: ChargingSiteInformation?)
@@ -120,9 +113,8 @@ interface TeslaChargingGuestGraphQlApi {
@JsonClass(generateAdapter = true)
data class ChargingSiteInformation(
val activeOutages: List<Outage>?,
val chargers: List<ChargerId>,
val chargersAvailable: ChargersAvailable,
val id: Long,
val chargerList: List<ChargerDetail>,
val trtId: Long,
val maxPowerKw: Int,
val name: String,
val pricing: Pricing,
@@ -130,9 +122,10 @@ interface TeslaChargingGuestGraphQlApi {
)
@JsonClass(generateAdapter = true)
data class ChargerId(
val id: String,
data class ChargerDetail(
val availability: ChargerAvailability,
val label: String?,
val id: String
) {
val labelNumber
get() = label?.replace(Regex("""\D"""), "")?.toInt()
@@ -140,15 +133,6 @@ interface TeslaChargingGuestGraphQlApi {
get() = label?.replace(Regex("""\d"""), "")
}
@JsonClass(generateAdapter = true)
data class ChargersAvailable(val chargerDetails: List<ChargerDetail>)
@JsonClass(generateAdapter = true)
data class ChargerDetail(
val availability: ChargerAvailability,
val id: String
)
companion object {
fun create(
client: OkHttpClient,

View File

@@ -452,7 +452,10 @@ class GoingElectricApiWrapper(
if (responses.map { it.isSuccessful }.all { it }
&& plugsResponse.body()!!.status == STATUS_OK
&& chargeCardsResponse.body()!!.status == STATUS_OK
&& networksResponse.body()!!.status == STATUS_OK) {
&& networksResponse.body()!!.status == STATUS_OK
&& plugsResponse.body()!!.result != null
&& chargeCardsResponse.body()!!.result != null
&& networksResponse.body()!!.result != null) {
Resource.success(
GEReferenceData(
plugsResponse.body()!!.result!!,

View File

@@ -244,6 +244,8 @@ class OpenChargeMapApiWrapper(
return Resource.success(ChargepointList(result, data.size < 499))
} catch (e: IOException) {
return Resource.error(e.message, null)
} catch (e: HttpException) {
return Resource.error(e.message, null)
}
}

View File

@@ -13,6 +13,7 @@ import android.text.SpannableStringBuilder
import android.text.Spanned
import androidx.car.app.CarContext
import androidx.car.app.CarToast
import androidx.car.app.HostException
import androidx.car.app.Screen
import androidx.car.app.constraints.ConstraintManager
import androidx.car.app.model.Action
@@ -549,7 +550,13 @@ class ChargerDetailScreen(ctx: CarContext, val chargerSparse: ChargeLocation) :
CarContext.ACTION_NAVIGATE,
Uri.parse("geo:${coord.lat},${coord.lng}")
)
carContext.startCarApp(intent)
try {
carContext.startCarApp(intent)
} catch (e: HostException) {
CarToast.makeText(carContext, R.string.no_maps_app_found, CarToast.LENGTH_SHORT).show()
} catch (ignored: SecurityException) {
}
}
private fun loadCharger() {

View File

@@ -43,6 +43,7 @@ import net.vonforst.evmap.api.availability.tesla.TeslaOwnerApi
import net.vonforst.evmap.api.chargeprice.ChargepriceApi
import net.vonforst.evmap.api.chargeprice.ChargepriceCar
import net.vonforst.evmap.api.chargeprice.ChargepriceTariff
import net.vonforst.evmap.currencyDisplayName
import net.vonforst.evmap.fragment.oauth.OAuthLoginFragment
import net.vonforst.evmap.fragment.oauth.OAuthLoginFragmentArgs
import net.vonforst.evmap.getPackageInfoCompat
@@ -486,10 +487,9 @@ class ChargepriceSettingsScreen(ctx: CarContext) : Screen(ctx) {
addItem(Row.Builder().apply {
setTitle(carContext.getString(R.string.pref_chargeprice_currency))
val names =
carContext.resources.getStringArray(R.array.pref_chargeprice_currency_names)
val values =
carContext.resources.getStringArray(R.array.pref_chargeprice_currency_values)
carContext.resources.getStringArray(R.array.pref_chargeprice_currencies)
val names = values.map(::currencyDisplayName)
val index = values.indexOf(prefs.chargepriceCurrency)
addText(if (index >= 0) names[index] else "")
@@ -629,8 +629,8 @@ class SelectCurrencyScreen(ctx: CarContext) : MultiSelectSearchScreen<Pair<Strin
override fun getLabel(it: Pair<String, String>): String = it.first
override suspend fun loadData(): List<Pair<String, String>> {
val names = carContext.resources.getStringArray(R.array.pref_chargeprice_currency_names)
val values = carContext.resources.getStringArray(R.array.pref_chargeprice_currency_values)
val values = carContext.resources.getStringArray(R.array.pref_chargeprice_currencies)
val names = values.map(::currencyDisplayName)
return names.zip(values)
}
}

View File

@@ -14,7 +14,11 @@ import androidx.car.app.CarToast
import androidx.car.app.Screen
import androidx.car.app.constraints.ConstraintManager
import androidx.car.app.hardware.common.CarUnit
import androidx.car.app.model.*
import androidx.car.app.model.CarColor
import androidx.car.app.model.CarIcon
import androidx.car.app.model.Distance
import androidx.car.app.model.MessageTemplate
import androidx.car.app.model.Template
import androidx.car.app.versioning.CarAppApiLevels
import androidx.core.content.ContextCompat
import androidx.core.graphics.drawable.IconCompat
@@ -26,7 +30,7 @@ import net.vonforst.evmap.getPackageInfoCompat
import net.vonforst.evmap.kmPerMile
import net.vonforst.evmap.shouldUseImperialUnits
import net.vonforst.evmap.ydPerMile
import java.util.*
import java.util.Locale
import kotlin.math.roundToInt
fun carAvailabilityColor(status: List<ChargepointStatus>): CarColor {
@@ -207,7 +211,9 @@ fun supportsCarApiLevel3(ctx: CarContext): Boolean {
val version = getAndroidAutoVersion(ctx)
// Android Auto 6.7 is required. 6.6 reports supporting API Level 3,
// but crashes when using it. See: https://issuetracker.google.com/issues/199509584
if (version[0] < "6" || version[0] == "6" && version[1] < "7") {
val major = version[0].toIntOrNull() ?: return false
val minor = version[1].toIntOrNull() ?: return false
if (major < 6 || major < 6 && minor < 7) {
return false
}
}

View File

@@ -6,9 +6,18 @@ import android.os.Handler
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.*
import androidx.car.app.model.*
import androidx.car.app.hardware.info.CarSensors
import androidx.car.app.hardware.info.Compass
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.model.Action
import androidx.car.app.model.CarColor
import androidx.car.app.model.CarIcon
import androidx.car.app.model.GridItem
import androidx.car.app.model.GridTemplate
import androidx.car.app.model.ItemList
import androidx.car.app.model.Template
import androidx.core.content.ContextCompat
import androidx.core.graphics.drawable.IconCompat
import androidx.lifecycle.DefaultLifecycleObserver
@@ -18,14 +27,14 @@ import net.vonforst.evmap.R
import net.vonforst.evmap.ui.CompassNeedle
import net.vonforst.evmap.ui.Gauge
import net.vonforst.evmap.utils.formatDecimal
import patchedCarInfo
import kotlin.math.min
import kotlin.math.roundToInt
@androidx.car.app.annotations.ExperimentalCarApi
class VehicleDataScreen(ctx: CarContext, val session: EVMapSession) : Screen(ctx),
LocationAwareScreen, DefaultLifecycleObserver {
private val carInfo =
(ctx.getCarService(CarContext.HARDWARE_SERVICE) as CarHardwareManager).carInfo
private val carInfo = carContext.patchedCarInfo
private val carSensors = carContext.patchedCarSensors
private var model: Model? = null
private var energyLevel: EnergyLevel? = null

View File

@@ -864,6 +864,7 @@ class MapFragment : Fragment(), OnMapReadyCallback, MapsActivity.FragmentCallbac
if (photo == photos[position] && imageCacheKey != null) {
placeholderMemoryCacheKey(imageCacheKey)
}
allowHardware(false)
}
}
.withTransitionFrom(view as ImageView)

View File

@@ -8,7 +8,9 @@ import android.text.style.RelativeSizeSpan
import android.view.View
import androidx.fragment.app.viewModels
import androidx.preference.CheckBoxPreference
import androidx.preference.ListPreference
import net.vonforst.evmap.R
import net.vonforst.evmap.currencyDisplayName
import net.vonforst.evmap.ui.MultiSelectDialogPreference
import net.vonforst.evmap.viewmodel.SettingsViewModel
import net.vonforst.evmap.viewmodel.viewModelFactory
@@ -73,6 +75,11 @@ class ChargepriceSettingsFragment : BaseSettingsFragment() {
}
}
updateNativeIntegrationState()
val currencyPreference = findPreference<ListPreference>("chargeprice_currency")!!
currencyPreference.entries = currencyPreference.entryValues.map {
currencyDisplayName(it.toString()).replaceFirstChar { it.uppercase() }
}.toTypedArray()
}
private fun updateNativeIntegrationState() {

View File

@@ -9,9 +9,11 @@ import android.provider.Settings
import androidx.preference.CheckBoxPreference
import androidx.preference.ListPreference
import androidx.preference.Preference
import com.github.erfansn.localeconfigx.configuredLocales
import net.vonforst.evmap.R
import net.vonforst.evmap.isAppInstalled
import net.vonforst.evmap.ui.getAppLocale
import net.vonforst.evmap.ui.map
import net.vonforst.evmap.ui.updateAppLocale
import net.vonforst.evmap.ui.updateNightMode
@@ -23,11 +25,7 @@ class UiSettingsFragment : BaseSettingsFragment() {
override fun onCreatePreferences(savedInstanceState: Bundle?, rootKey: String?) {
setPreferencesFromResource(R.xml.settings_ui, rootKey)
langPref = findPreference("language")!!
langPref.setOnPreferenceChangeListener { _, newValue ->
updateAppLocale(newValue as String)
true
}
setupLangPref()
val appLinkPref = findPreference<Preference>("applink_associate")!!
appLinkPref.isVisible = Build.VERSION.SDK_INT >= Build.VERSION_CODES.S
@@ -36,12 +34,37 @@ class UiSettingsFragment : BaseSettingsFragment() {
immediateNavPref.isVisible = isGoogleMapsInstalled()
}
private fun setupLangPref() {
langPref = findPreference("language")!!
val configuredLocales = requireContext().configuredLocales
val numLocalesByLang = configuredLocales.map { it.language }.groupingBy { it }.eachCount()
val localeNames = configuredLocales.map {
val name = if (numLocalesByLang[it.language]!! > 1) {
it.getDisplayName(it)
} else {
it.getDisplayLanguage(it)
}
name.replaceFirstChar { c -> c.uppercase(it) }
}
val localeTags = configuredLocales.map { it.toLanguageTag() }
langPref.entries =
(listOf(getString(R.string.pref_language_device_default)) + localeNames).toTypedArray()
langPref.entryValues =
(listOf("default") + localeTags).toTypedArray()
langPref.setOnPreferenceChangeListener { _, newValue ->
updateAppLocale(newValue as String)
true
}
}
private fun isGoogleMapsInstalled() =
requireContext().packageManager.isAppInstalled("com.google.android.apps.maps")
override fun onResume() {
super.onResume()
langPref.value = getAppLocale()
langPref.value = getAppLocale(requireContext())
immediateNavPref.isVisible = isGoogleMapsInstalled()
}

View File

@@ -1,9 +1,12 @@
package net.vonforst.evmap.ui
import android.content.Context
import androidx.appcompat.app.AppCompatDelegate
import androidx.core.os.LocaleListCompat
import net.vonforst.evmap.BuildConfig
import com.github.erfansn.localeconfigx.configuredLocales
import net.vonforst.evmap.storage.PreferenceDataSource
import java.util.Locale
fun updateNightMode(prefs: PreferenceDataSource) {
AppCompatDelegate.setDefaultNightMode(
@@ -25,13 +28,17 @@ fun updateAppLocale(language: String) {
)
}
fun getAppLocale(): String? {
fun getAppLocale(context: Context): String? {
val locales = AppCompatDelegate.getApplicationLocales()
return if (locales.isEmpty) {
"default"
} else {
val arr = Array(locales.size()) { locales.get(it)!!.toLanguageTag() }
LocaleListCompat.forLanguageTags(BuildConfig.supportedLocales).getFirstMatch(arr)
?.toLanguageTag()
val choices = context.configuredLocales
choices.getFirstMatch(arr)?.toLanguageTag()
}
}
inline fun <R> LocaleListCompat.map(transform: (Locale) -> R): List<R> = List(size()) {
transform(get(it)!!)
}

View File

@@ -53,6 +53,7 @@
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/referral_tesla"
android:visibility="gone"
app:icon="@drawable/ic_tesla" />
<Button

View File

@@ -0,0 +1 @@
unqualifiedResLocale=en-US

View File

@@ -199,8 +199,6 @@
<string name="autocomplete_connection_error">Nepodařilo se načíst návrhy</string>
<string name="pref_language_device_default">Podle zařízení</string>
<string name="pref_darkmode_device_default">Podle zařízení</string>
<string name="pref_chargeprice_currency_sek">Švédská koruna (SEK)</string>
<string name="pref_chargeprice_currency_usd">Americký dolar (USD)</string>
<string name="pref_provider_google_maps">Mapy Google</string>
<string name="pref_provider_osm_mapbox">OpenStreetMap (Mapbox)</string>
<string name="about_contributors">Přispěvatelé</string>
@@ -351,16 +349,6 @@
<string name="chargeprice_faq_link">https://ev-map.app/faq/#price-comparison-feature</string>
<string name="pref_darkmode_always_on">vždy zapnut</string>
<string name="pref_darkmode_always_off">vždy vypnut</string>
<string name="pref_chargeprice_currency_chf">Švýcarský frank (CHF)</string>
<string name="pref_chargeprice_currency_czk">Česká koruna (CZK)</string>
<string name="pref_chargeprice_currency_dkk">Dánská koruna (DKK)</string>
<string name="pref_chargeprice_currency_eur">Euro (EUR)</string>
<string name="pref_chargeprice_currency_gbp">Britská libra (GBP)</string>
<string name="pref_chargeprice_currency_huf">Maďarský forint (HUF)</string>
<string name="pref_chargeprice_currency_hrk">Chorvatská kuna (HRK)</string>
<string name="pref_chargeprice_currency_isk">Islandská koruna (ISK)</string>
<string name="pref_chargeprice_currency_nok">Norská koruna (NOK)</string>
<string name="pref_chargeprice_currency_pln">Polský zlotý (PLN)</string>
<string name="chargeprice_header_other_tariffs">Ostatní plány</string>
<string name="charger_website">Webové stránky</string>
<string name="compass">Kompas</string>
@@ -383,4 +371,5 @@
<string name="pref_chargeprice_native_integration">Porovnání cen v EVMap</string>
<string name="pref_chargeprice_native_integration_on">Data o cenách budou zobrazena přímo v EVMap</string>
<string name="pref_chargeprice_native_integration_off">Tlačítko porovnání cen bude odkazovat na aplikaci nebo web Chargeprice</string>
<string name="pref_provider_osm">OpenStreetMap</string>
</resources>

View File

@@ -258,18 +258,6 @@
<string name="pref_darkmode_device_default">Geräteeinstellung verwenden</string>
<string name="pref_darkmode_always_on">immer an</string>
<string name="pref_darkmode_always_off">immer aus</string>
<string name="pref_chargeprice_currency_chf">Schweizer Franken (CHF)</string>
<string name="pref_chargeprice_currency_czk">Tschechische Krone (CZK)</string>
<string name="pref_chargeprice_currency_dkk">Dänische Krone (DKK)</string>
<string name="pref_chargeprice_currency_eur">Euro (EUR)</string>
<string name="pref_chargeprice_currency_gbp">Britisches Pfund (GBP)</string>
<string name="pref_chargeprice_currency_hrk">Kroatische Kuna (HRK)</string>
<string name="pref_chargeprice_currency_huf">Ungarischer Forint (HUF)</string>
<string name="pref_chargeprice_currency_isk">Isländische Krone (ISK)</string>
<string name="pref_chargeprice_currency_nok">Norwegische Krone (NOK)</string>
<string name="pref_chargeprice_currency_pln">Polnischer Złoty (PLN)</string>
<string name="pref_chargeprice_currency_sek">Schwedische Krone (SEK)</string>
<string name="pref_chargeprice_currency_usd">US-Dollar (USD)</string>
<string name="pref_provider_google_maps">Google Maps</string>
<string name="pref_provider_osm">OpenStreetMap</string>
<string name="pref_provider_osm_mapbox">OpenStreetMap (Mapbox)</string>

View File

@@ -128,9 +128,6 @@
<string name="pref_darkmode_device_default">Utiliser le réglage de l\'appareil</string>
<string name="pref_darkmode_always_on">toujours allumé</string>
<string name="pref_darkmode_always_off">toujours éteint</string>
<string name="pref_chargeprice_currency_czk">Couronne tchèque (CZK)</string>
<string name="pref_chargeprice_currency_dkk">Couronne danoise (DKK)</string>
<string name="pref_chargeprice_currency_eur">Euro (EUR)</string>
<string name="show_more">plus…</string>
<string name="fav_remove">Retirer des favoris</string>
<string name="amenities">Commodités</string>
@@ -230,9 +227,6 @@
<item quantity="other">(seront mis en évidence dans la comparaison des prix)</item>
</plurals>
<string name="deleted_recent_search_results">Les résultats de recherche récents ont été supprimés</string>
<string name="pref_chargeprice_currency_gbp">Livre sterling (GBP)</string>
<string name="pref_chargeprice_currency_isk">Couronne islandaise (ISK)</string>
<string name="pref_chargeprice_currency_nok">Couronne norvégienne (NOK)</string>
<string name="settings_charger_data">Stations de recharge</string>
<string name="got_it">J\'ai compris</string>
<string name="powered_by_mapbox">propulsé par Mapbox</string>
@@ -246,15 +240,9 @@
<string name="settings_data_sources">Sources de données</string>
<string name="data_sources_description">Veuillez choisir une source de données pour les stations de recharge. Vous pourrez la modifier ultérieurement dans les paramètres de l\'application.</string>
<string name="pref_search_provider_info">Les données pour la recherche de lieux, en particulier celles de Google Maps, sont relativement coûteuses à récupérer. Veuillez envisager de faire un don via \"À propos\" -&gt; \"Faire un don\".</string>
<string name="pref_chargeprice_currency_hrk">Kuna croate (HRK)</string>
<string name="help">Aide</string>
<string name="pref_chargeprice_allow_unbalanced_load_summary">Autoriser la charge en courant alternatif monophasé de plus de 4,5 kW</string>
<string name="pref_chargeprice_currency_huf">Forint hongrois (HUF)</string>
<string name="pref_chargeprice_currency_pln">Złoty polonais (PLN)</string>
<string name="pref_map_rotate_gestures_on">Utilisez deux doigts pour faire pivoter la carte</string>
<string name="pref_chargeprice_currency_chf">Franc suisse (CHF)</string>
<string name="pref_chargeprice_currency_usd">Dollar américain (USD)</string>
<string name="pref_chargeprice_currency_sek">Couronne suédoise (SEK)</string>
<string name="cost_detail_charging"><b>Recharge %s</b></string>
<string name="cost_detail_parking"><b>Stationnement %s</b></string>
<string name="navigate">Naviguer vers</string>

View File

@@ -84,10 +84,6 @@
<string name="got_it">Skjønner</string>
<string name="settings_data_sources">Datakilder</string>
<string name="pref_search_delete_recent">Slett nylige søkeresultater</string>
<string name="pref_chargeprice_currency_eur">Euro (EUR)</string>
<string name="pref_chargeprice_currency_nok">Norske kroner (NOK)</string>
<string name="pref_chargeprice_currency_gbp">Britiske pund (GBP)</string>
<string name="pref_chargeprice_currency_sek">Svenske kroner (SEK)</string>
<string name="realtime_data_loading">Sjekker sanntidsstatus …</string>
<string name="realtime_data_source">Kilde for sanntidsstatus (beta): %s</string>
<string name="realtime_data_unavailable">Sanntidsstatus utilgjengelig</string>
@@ -183,16 +179,9 @@
<string name="deleted_recent_search_results">Nylige søkeresultater slettet</string>
<string name="autocomplete_connection_error">Kunne ikke laste inn forslag</string>
<string name="pref_language_device_default">Enhetsforvalg</string>
<string name="pref_chargeprice_currency_chf">Sveitserfranc (CHF)</string>
<string name="pref_chargeprice_currency_czk">Tsjekkiske kroner (CZK)</string>
<string name="pref_chargeprice_currency_dkk">Danske kroner (DKK)</string>
<string name="pref_chargeprice_currency_hrk">Kroatiske kroner (HRK)</string>
<string name="pref_map_rotate_gestures_on">Bruk to fingre for å rotere kartet</string>
<string name="pref_map_rotate_gestures_off">Rotasjon avslått (nord er alltid oppover)</string>
<string name="refresh_live_data">oppdater sanntidsstatus</string>
<string name="pref_chargeprice_currency_isk">Islandske kroner (ISK)</string>
<string name="pref_chargeprice_currency_pln">Polske zloty (PLN)</string>
<string name="pref_chargeprice_currency_usd">Amerikanske dollar (USD)</string>
<string name="filters_deactivated">Filtre deaktivert</string>
<string name="pref_navigate_use_maps_off">Navigasjonsknapp åpner kartprogrammet med laderposisjon</string>
<string name="show_more">flere …</string>
@@ -217,7 +206,6 @@
<string name="filter_exclude_faults">Utelat ladere med rapporterte feil</string>
<string name="plug_cee_blau">CEE blå</string>
<string name="filter_open_247">Døgnåpent</string>
<string name="pref_chargeprice_currency_huf">Ungarske forint (HUF)</string>
<string name="donation_dialog_detail">EVMap er fri programvare. Kodebidrag mottas med takk. Overvei å gi din støtte gjennom GitHub-sponsorer for å dekke løpende utgifter.</string>
<string name="pref_chargeprice_allow_unbalanced_load_summary">Tillat enfaselading over 4.5 kW</string>
<string name="connectors">Tilkobling</string>

View File

@@ -5,7 +5,6 @@
<string name="pref_search_provider_info">Gegevens opzoeken is duur, vooral via Google Maps. Overweeg aub om een donatie te doen via “Over” -&gt; “Doneer”.</string>
<string name="data_source_openchargemap_desc">Werelddekkend, met variabele kwaliteit. Beschrijving in Engels of lokale taal. Onderhouden door de gebruikers. Ook open overheidswege eens in sommige landen (bv. Noord-Amerika, UK, Frankrijk, Noorwegen).</string>
<string name="pref_darkmode_always_off">altijd uit</string>
<string name="pref_chargeprice_currency_eur">Euro (EUR)</string>
<string name="chargeprice_select_car_first">Kiest eerst je voertuig model in de instellingen</string>
<string name="chargeprice_no_compatible_connectors">Geen compatibele connectoren aan dit laadstation</string>
<string name="license">Licentie</string>
@@ -228,17 +227,6 @@
<string name="pref_language_device_default">Standaardtaal van toestel</string>
<string name="pref_darkmode_device_default">Standaardinstelling van toestel</string>
<string name="pref_darkmode_always_on">altijd aan</string>
<string name="pref_chargeprice_currency_chf">Zwitserse Frank (CHF)</string>
<string name="pref_chargeprice_currency_czk">Tsjechische koruna (CZK)</string>
<string name="pref_chargeprice_currency_dkk">Deense kroon (DKK)</string>
<string name="pref_chargeprice_currency_gbp">Britse Pond (GBP)</string>
<string name="pref_chargeprice_currency_hrk">Kroatische Kuna (HRK)</string>
<string name="pref_chargeprice_currency_huf">Hongaarse Forint (HUF)</string>
<string name="pref_chargeprice_currency_isk">IJslandse Kroon (ISK)</string>
<string name="pref_chargeprice_currency_nok">Noorse Kroon (NOK)</string>
<string name="pref_chargeprice_currency_pln">Poolse Złoty (PLN)</string>
<string name="pref_chargeprice_currency_sek">Zweedse Kroon (SEK)</string>
<string name="pref_chargeprice_currency_usd">Amerikaanse Dollar (USD)</string>
<string name="pref_provider_google_maps">Google Maps</string>
<string name="edit_filter_profile">“%s” editeren</string>
<string name="compass">Kompas</string>

View File

@@ -177,11 +177,6 @@
<string name="pref_language_device_default">Língua do dispositivo</string>
<string name="pref_darkmode_device_default">Padrão do dispositivo</string>
<string name="pref_darkmode_always_on">Sempre ligado</string>
<string name="pref_chargeprice_currency_chf">Franco suíço (CHF)</string>
<string name="pref_chargeprice_currency_czk">Coroa checa (CZK)</string>
<string name="pref_chargeprice_currency_dkk">Coroa dinamarquesa (DKK)</string>
<string name="pref_chargeprice_currency_eur">Euro (EUR)</string>
<string name="pref_chargeprice_currency_gbp">Libra esterlina (GBP)</string>
<string name="chargeprice_header_my_tariffs">Os meus planos</string>
<string name="chargeprice_header_other_tariffs">Outros planos</string>
<string name="developer_options">Opções de desenvolvedor</string>
@@ -287,13 +282,6 @@
<string name="welcome_1">Encontre carregadores elétricos perto de si</string>
<string name="close">Fechar</string>
<string name="edit_filter_profile">Editar “%s”</string>
<string name="pref_chargeprice_currency_hrk">Cuna croata (HRK)</string>
<string name="pref_chargeprice_currency_huf">Florim húngaro (HUF)</string>
<string name="pref_chargeprice_currency_isk">Coroa islandesa (ISK)</string>
<string name="pref_chargeprice_currency_nok">Coroa norueguesa (NOK)</string>
<string name="pref_chargeprice_currency_pln">Złoty polaco (PLN)</string>
<string name="pref_chargeprice_currency_sek">Coroa sueca (SEK)</string>
<string name="pref_chargeprice_currency_usd">Dólar americano (USD)</string>
<string name="pref_provider_google_maps">Google Maps</string>
<string name="pref_provider_osm_mapbox">OpenStreetMap (Mapbox)</string>
<string name="about_contributors">Contribuidores</string>
@@ -380,4 +368,8 @@
<string name="status_faulted">Fora de serviço</string>
<string name="status_since">%1$s desde %2$s</string>
<string name="status_unknown">Estado Desconhecido</string>
<string name="pref_chargeprice_native_integration">Comparação de preços no EVMap</string>
<string name="pref_chargeprice_native_integration_on">Os preços serão exibidos diretamente no EVMap</string>
<string name="pref_chargeprice_native_integration_off">O botão de comparação de preços abrirá a app ou site do Chargeprice</string>
<string name="pref_provider_osm">OpenStreetMap</string>
</resources>

View File

@@ -259,18 +259,6 @@
<string name="pref_darkmode_device_default">Implicit dispozitiv</string>
<string name="pref_darkmode_always_on">permanent</string>
<string name="pref_darkmode_always_off">dezactivat</string>
<string name="pref_chargeprice_currency_chf">Franci elvetieni (CHF)</string>
<string name="pref_chargeprice_currency_czk">Coroane cehe (CZK)</string>
<string name="pref_chargeprice_currency_dkk">Coroane daneze (DKK)</string>
<string name="pref_chargeprice_currency_eur">Euro (EUR)</string>
<string name="pref_chargeprice_currency_gbp">Lire sterline (GBP)</string>
<string name="pref_chargeprice_currency_hrk">Croatian kuna (HRK)</string>
<string name="pref_chargeprice_currency_huf">Forinti maghiari (HUF)</string>
<string name="pref_chargeprice_currency_isk">Coroane islandeze (ISK)</string>
<string name="pref_chargeprice_currency_nok">Coroane norvegiene (NOK)</string>
<string name="pref_chargeprice_currency_pln">Zloti polonezi (PLN)</string>
<string name="pref_chargeprice_currency_sek">Coroane suedeze (SEK)</string>
<string name="pref_chargeprice_currency_usd">Dolari americani (USD)</string>
<string name="pref_provider_google_maps">Google Maps</string>
<string name="pref_provider_osm_mapbox">OpenStreetMap (Mapbox)</string>
<string name="about_contributors">Contribuitori</string>

View File

@@ -1,27 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string-array name="pref_language_names">
<item>@string/pref_language_device_default</item>
<item>@string/pref_language_en</item>
<item>@string/pref_language_de</item>
<item>@string/pref_language_cs</item>
<item>@string/pref_language_fr</item>
<item>@string/pref_language_nb_rNO</item>
<item>@string/pref_language_nl</item>
<item>@string/pref_language_pt</item>
<item>@string/pref_language_ro</item>
</string-array>
<string-array name="pref_language_values" translatable="false">
<item>default</item>
<item>en</item>
<item>de</item>
<item>cs</item>
<item>fr</item>
<item>nb-NO</item>
<item>nl</item>
<item>pt</item>
<item>ro</item>
</string-array>
<string-array name="pref_darkmode_names">
<item>@string/pref_darkmode_device_default</item>
<item>@string/pref_darkmode_always_on</item>
@@ -32,21 +10,7 @@
<item>on</item>
<item>off</item>
</string-array>
<string-array name="pref_chargeprice_currency_names">
<item>@string/pref_chargeprice_currency_chf</item>
<item>@string/pref_chargeprice_currency_czk</item>
<item>@string/pref_chargeprice_currency_dkk</item>
<item>@string/pref_chargeprice_currency_eur</item>
<item>@string/pref_chargeprice_currency_gbp</item>
<item>@string/pref_chargeprice_currency_hrk</item>
<item>@string/pref_chargeprice_currency_huf</item>
<item>@string/pref_chargeprice_currency_isk</item>
<item>@string/pref_chargeprice_currency_nok</item>
<item>@string/pref_chargeprice_currency_pln</item>
<item>@string/pref_chargeprice_currency_sek</item>
<item>@string/pref_chargeprice_currency_usd</item>
</string-array>
<string-array name="pref_chargeprice_currency_values" translatable="false">
<string-array name="pref_chargeprice_currencies" translatable="false">
<item>CHF</item>
<item>CZK</item>
<item>DKK</item>

View File

@@ -10,14 +10,6 @@
<string name="chargeprice_api_url">https://api.chargeprice.app/v1/</string>
<string name="fronyx_url">https://fronyx.io/</string>
<string name="website_url">https://ev-map.app</string>
<string name="pref_language_en">English</string>
<string name="pref_language_de">Deutsch</string>
<string name="pref_language_fr">Français</string>
<string name="pref_language_nb_rNO">Norsk Bokmål</string>
<string name="pref_language_nl">Nederlands</string>
<string name="pref_language_pt">Português</string>
<string name="pref_language_ro">Romana</string>
<string name="pref_language_cs">Czech</string>
<string name="about_contributors_list">
Danilo Bargen\n
Altonss\n

View File

@@ -258,18 +258,6 @@
<string name="pref_darkmode_device_default">Device default</string>
<string name="pref_darkmode_always_on">always on</string>
<string name="pref_darkmode_always_off">always off</string>
<string name="pref_chargeprice_currency_chf">Swiss franc (CHF)</string>
<string name="pref_chargeprice_currency_czk">Czech koruna (CZK)</string>
<string name="pref_chargeprice_currency_dkk">Danish krone (DKK)</string>
<string name="pref_chargeprice_currency_eur">Euro (EUR)</string>
<string name="pref_chargeprice_currency_gbp">Pound sterling (GBP)</string>
<string name="pref_chargeprice_currency_hrk">Croatian kuna (HRK)</string>
<string name="pref_chargeprice_currency_huf">Hungarian forint (HUF)</string>
<string name="pref_chargeprice_currency_isk">Icelandic króna (ISK)</string>
<string name="pref_chargeprice_currency_nok">Norwegian krone (NOK)</string>
<string name="pref_chargeprice_currency_pln">Polish złoty (PLN)</string>
<string name="pref_chargeprice_currency_sek">Swedish krona (SEK)</string>
<string name="pref_chargeprice_currency_usd">US dollar (USD)</string>
<string name="pref_provider_google_maps">Google Maps</string>
<string name="pref_provider_osm">OpenStreetMap</string>
<string name="pref_provider_osm_mapbox">OpenStreetMap (Mapbox)</string>

View File

@@ -1,7 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<locale-config xmlns:android="http://schemas.android.com/apk/res/android">
<locale android:name="en" />
<locale android:name="de" />
<locale android:name="fr" />
<locale android:name="nb-NO" />
</locale-config>

View File

@@ -18,8 +18,7 @@
<ListPreference
android:key="chargeprice_currency"
android:title="@string/pref_chargeprice_currency"
android:entries="@array/pref_chargeprice_currency_names"
android:entryValues="@array/pref_chargeprice_currency_values"
android:entryValues="@array/pref_chargeprice_currencies"
android:defaultValue="EUR"
app:useSimpleSummaryProvider="true" />
<CheckBoxPreference

View File

@@ -4,8 +4,6 @@
android:key="language"
android:persistent="false"
android:title="@string/pref_language"
android:entries="@array/pref_language_names"
android:entryValues="@array/pref_language_values"
android:defaultValue="default"
android:summary="%s" />
<ListPreference

View File

@@ -0,0 +1,6 @@
import androidx.car.app.CarContext
import androidx.car.app.hardware.CarHardwareManager
import androidx.car.app.hardware.info.CarInfo
val CarContext.patchedCarInfo: CarInfo
get() = (this.getCarService(CarContext.HARDWARE_SERVICE) as CarHardwareManager).carInfo

View File

@@ -1,16 +1,16 @@
// Top-level build file where you can add configuration options common to all sub-projects/modules.
buildscript {
val kotlinVersion by extra("1.9.10")
val kotlinVersion by extra("1.9.24")
val aboutLibsVersion by extra("10.9.1")
val navVersion by extra("2.7.5")
val navVersion by extra("2.7.7")
repositories {
google()
mavenCentral()
gradlePluginPortal()
}
dependencies {
classpath("com.android.tools.build:gradle:8.2.2")
classpath("com.android.tools.build:gradle:8.4.1")
classpath("org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlinVersion")
classpath("com.mikepenz.aboutlibraries.plugin:aboutlibraries-plugin:$aboutLibsVersion")
classpath("androidx.navigation:navigation-safe-args-gradle-plugin:$navVersion")

View File

@@ -0,0 +1,7 @@
Änderungen:
- OpenStreetMap-Karten: Wechsel der Datenquelle von Mapbox zu Jawg Maps
Fehler behoben:
- App-Shortcuts repariert
- Anzeigefehler behoben
- Abstürze behoben

View File

@@ -0,0 +1,2 @@
Fehler behoben:
- Unterstützung für Geräte mit OpenGL ES 2.0 wiederhergestellt

View File

@@ -0,0 +1,2 @@
Fehler behoben:
- Abstürze behoben

View File

@@ -0,0 +1,3 @@
Fehler behoben:
- Probleme mit OpenStreetMap behoben
- Abstürze behoben

View File

@@ -0,0 +1,2 @@
Fehler behoben:
- Abstürze behoben

View File

Binary file not shown.

Before

Width:  |  Height:  |  Size: 24 KiB

After

Width:  |  Height:  |  Size: 14 KiB

View File

@@ -0,0 +1,7 @@
Changes:
- OpenStreetMap maps: Change data source from Mapbox to Jawg Maps
Bugfixes:
- Fixed app shortcuts
- Fixed display errors
- Fixed crashes

View File

@@ -0,0 +1,2 @@
Bugfixes:
- Restored support for devices with OpenGL ES 2.0

View File

@@ -0,0 +1,2 @@
Bugfixes:
- Fixed crashes

View File

@@ -0,0 +1,3 @@
Bugfixes:
- Fixed problems with OpenStreetMap
- Fixed crashes

View File

@@ -0,0 +1,2 @@
Bugfixes:
- Fixed crashes

View File

Binary file not shown.

Before

Width:  |  Height:  |  Size: 24 KiB

After

Width:  |  Height:  |  Size: 14 KiB

View File

@@ -1,6 +1,6 @@
#Sat Aug 06 15:33:46 CEST 2022
distributionBase=GRADLE_USER_HOME
distributionUrl=https\://services.gradle.org/distributions/gradle-8.4-bin.zip
distributionUrl=https\://services.gradle.org/distributions/gradle-8.6-bin.zip
distributionPath=wrapper/dists
zipStorePath=wrapper/dists
zipStoreBase=GRADLE_USER_HOME