Compare commits

...

42 Commits

Author SHA1 Message Date
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
77 changed files with 628 additions and 263 deletions

View File

@@ -1,6 +1,8 @@
<resources>
<string name="google_maps_key" templateMergeStrategy="preserve" translatable="false">ci</string>
<string name="mapbox_key" translatable="false">ci</string>
<string name="jawg_key" translatable="false">ci</string>
<string name="arcgis_key" translatable="false">ci</string>
<string name="goingelectric_key" translatable="false">ci</string>
<string name="chargeprice_key" translatable="false">ci</string>
<string name="openchargemap_key" translatable="false">ci</string>

View File

@@ -30,6 +30,8 @@ jobs:
OPENCHARGEMAP_API_KEY: ${{ secrets.OPENCHARGEMAP_API_KEY }}
CHARGEPRICE_API_KEY: ${{ secrets.CHARGEPRICE_API_KEY }}
MAPBOX_API_KEY: ${{ secrets.MAPBOX_API_KEY }}
JAWG_API_KEY: ${{ secrets.JAWG_API_KEY }}
ARCGIS_API_KEY: ${{ secrets.ARCGIS_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 }}

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

@@ -24,7 +24,8 @@ Features
- Android Auto & Android Automotive OS integration
- No ads, fully open source
- Compatible with Android 5.0 and above
- Can use Google Maps or Mapbox (OpenStreetMap) as map backends - the version available on F-Droid only uses Mapbox.
- Can use Google Maps or OpenStreetMap as map backends - the version available on F-Droid only uses
OSM.
Screenshots
-----------
@@ -42,12 +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`.
- The `foss` variants only use Mapbox data and should run on most Android devices, even without
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.
@@ -75,5 +78,23 @@ You can use our [Weblate page](https://hosted.weblate.org/projects/evmap/) to he
into new languages.
<a href="https://hosted.weblate.org/engage/evmap/">
<img src="https://hosted.weblate.org/widgets/evmap/-/open-graph.png" width="500" alt="Translation status" />
<img src="https://hosted.weblate.org/widgets/evmap/-/open-graph.png" width="400" alt="Translation status" />
</a>
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 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

@@ -12,14 +12,16 @@ plugins {
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 = 224
versionName = "1.9.3"
testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner"
}
@@ -46,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") {
@@ -146,6 +157,28 @@ android {
if (mapboxKey != null) {
resValue("string", "mapbox_key", mapboxKey)
}
var jawgKey =
System.getenv("JAWG_API_KEY") ?: project.findProperty("JAWG_API_KEY")?.toString()
if (jawgKey == null && project.hasProperty("JAWG_API_KEY_ENCRYPTED")) {
jawgKey = decode(
project.findProperty("JAWG_API_KEY_ENCRYPTED").toString(),
"FmK.d,-f*p+rD+WK!eds"
)
}
if (jawgKey != null) {
resValue("string", "jawg_key", jawgKey)
}
var arcgisKey =
System.getenv("ARCGIS_API_KEY") ?: project.findProperty("ARCGIS_API_KEY")?.toString()
if (arcgisKey == null && project.hasProperty("ARCGIS_API_KEY_ENCRYPTED")) {
arcgisKey = decode(
project.findProperty("ARCGIS_API_KEY_ENCRYPTED").toString(),
"FmK.d,-f*p+rD+WK!eds"
)
}
if (arcgisKey != null) {
resValue("string", "arcgis_key", jawgKey)
}
var chargepriceKey =
System.getenv("CHARGEPRICE_API_KEY") ?: project.findProperty("CHARGEPRICE_API_KEY")
?.toString()
@@ -196,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") {}
@@ -203,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
}
@@ -222,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")
@@ -253,39 +306,26 @@ 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.erfansn:locale-config-x:1.0.0")
// 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 = "4854581f72"
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-mapbox:$anyMapsVersion") {
exclude(group = "com.mapbox.mapboxsdk", module = "mapbox-android-accounts")
exclude(group = "com.mapbox.mapboxsdk", module = "mapbox-android-telemetry")
exclude(group = "com.google.android.gms", module = "play-services-location")
exclude(group = "com.mapbox.mapboxsdk", module = "mapbox-android-core")
}
// original version of mapbox-android-core
googleImplementation("com.mapbox.mapboxsdk:mapbox-android-core:2.0.1")
// patched version that removes build-time dependency on GMS (-> no Google location services)
fossImplementation("com.github.ev-map:mapbox-events-android:a21c324501")
implementation("com.mapbox.mapboxsdk:mapbox-android-sdk") {
exclude(group = "com.mapbox.mapboxsdk", module = "mapbox-android-accounts")
exclude(group = "com.mapbox.mapboxsdk", module = "mapbox-android-telemetry")
version {
strictly("9.1.0-SNAPSHOT")
}
implementation("com.github.ev-map.AnyMaps:anymaps-maplibre:$anyMapsVersion") {
// duplicates classes from mapbox-sdk-services
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
@@ -296,7 +336,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")
@@ -311,7 +351,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")
@@ -328,7 +368,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

@@ -2,5 +2,5 @@
<resources>
<string name="donations_info" formatted="false">Pomohla vám EVMap? Podpořte její vývoj zasláním finančního daru vývojáři.</string>
<string name="donate_paypal">Přispět pomocí PayPalu</string>
<string name="data_sources_hint">Mapová data v aplikaci poskytuje služba OpenStreetMap (Mapbox).</string>
<string name="data_sources_hint">Mapová data v aplikaci poskytuje služba OpenStreetMap.</string>
</resources>

View File

@@ -2,5 +2,5 @@
<resources>
<string name="donations_info" formatted="false">Findest du EVMap nützlich? Unterstütze die Weiterentwicklung der App mit einer Spende an den Entwickler.</string>
<string name="donate_paypal">Mit PayPal spenden</string>
<string name="data_sources_hint">Die Kartendaten für die App stammen von OpenStreetMap (Mapbox).</string>
<string name="data_sources_hint">Die Kartendaten für die App stammen von OpenStreetMap.</string>
</resources>

View File

@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string name="donations_info" formatted="false">Trouvez-vous EVMap utile \? Soutenez son développement en envoyant un don au développeur.</string>
<string name="data_sources_hint">Les données cartographiques de l\'application sont fournies par OpenStreetMap (Mapbox).</string>
<string name="data_sources_hint">Les données cartographiques de l\'application sont fournies par OpenStreetMap.</string>
<string name="donate_paypal">Faire un don avec PayPal</string>
</resources>

View File

@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string name="donate_paypal">Doner med PayPal</string>
<string name="data_sources_hint">Kartdata i programmet tilbys av OpenStreetMap (Mapbox).</string>
<string name="data_sources_hint">Kartdata i programmet tilbys av OpenStreetMap.</string>
<string name="donations_info" formatted="false">Synes du EVMap er nyttig\? Støtt utviklingen ved å sende en slant til utvikleren.</string>
</resources>

View File

@@ -2,5 +2,5 @@
<resources>
<string name="donations_info" formatted="false">Vond je EVMap nuttig\? Je kan de ontwikkeling ondersteunen door een donatie te sturen naar de ontwikkelaar.</string>
<string name="donate_paypal">Doneer via PayPal</string>
<string name="data_sources_hint">De kaartgegevens zijn afkomstig van OpenStreetMap (Mapbox).</string>
<string name="data_sources_hint">De kaartgegevens zijn afkomstig van OpenStreetMap.</string>
</resources>

View File

@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string name="data_sources_hint">Os dados do mapa são fornecidos pelo OpenStreetMap (Mapbox).</string>
<string name="data_sources_hint">Os dados do mapa são fornecidos pelo OpenStreetMap.</string>
<string name="donate_paypal">Doar com o PayPal</string>
<string name="donations_info" formatted="false">Acha que o EVMap é útil\? Apoie a manutenção e desenvolvimento com uma doação para o desenvolvedor da app.</string>
</resources>

View File

@@ -2,5 +2,5 @@
<resources>
<string name="donations_info" formatted="false">Crezi ca EVMap este util? Sprijina dezvoltarea printr-o donatie pentru dezvoltator.</string>
<string name="donate_paypal">Doneaza cu PayPal</string>
<string name="data_sources_hint">Hartile din aplicatie sunt furnizate de OpenStreetMap (Mapbox).</string>
<string name="data_sources_hint">Hartile din aplicatie sunt furnizate de OpenStreetMap.</string>
</resources>

View File

@@ -2,5 +2,5 @@
<resources>
<string name="donations_info" formatted="false">Do you find EVMap useful? Support its development by sending a donation to the developer.</string>
<string name="donate_paypal">Donate with PayPal</string>
<string name="data_sources_hint">Map data in the app is provided by OpenStreetMap (Mapbox).</string>
<string name="data_sources_hint">Map data in the app is provided by OpenStreetMap.</string>
</resources>

View File

@@ -3,5 +3,5 @@
<string name="donations_info" formatted="false">Pomohla vám EVMap? Podpořte její vývoj posláním finančního daru vývojáři.
\n
\nGoogle si z každého daru strhne 15 %.</string>
<string name="data_sources_hint">V nastavení můžete také pro mapová data přepínat mezi službami Mapy Google a OpenStreetMap (Mapbox).</string>
<string name="data_sources_hint">V nastavení můžete také pro mapová data přepínat mezi službami Mapy Google a OpenStreetMap.</string>
</resources>

View File

@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string name="donations_info" formatted="false">Findest du EVMap nützlich? Unterstütze die Weiterentwicklung der App mit einer Spende an den Entwickler.\n\nGoogle zieht von der Spende 15% Gebühren ab.</string>
<string name="data_sources_hint">In den Einstellungen kannst du auch zwischen Google Maps und OpenStreetMap (Mapbox) für die Kartendaten wechseln.</string>
<string name="data_sources_hint">In den Einstellungen kannst du auch zwischen Google Maps und OpenStreetMap für die Kartendaten wechseln.</string>
</resources>

View File

@@ -3,5 +3,5 @@
<string name="donations_info" formatted="false">Trouvez-vous EVMap utile \? Soutenez son développement en envoyant un don au développeur.
\n
\nGoogle prend 15% sur chaque don.</string>
<string name="data_sources_hint">Dans les paramètres, vous pouvez également choisir entre Google Maps et OpenStreetMap (Mapbox) pour les données cartographiques.</string>
<string name="data_sources_hint">Dans les paramètres, vous pouvez également choisir entre Google Maps et OpenStreetMap pour les données cartographiques.</string>
</resources>

View File

@@ -3,5 +3,5 @@
<string name="donations_info" formatted="false">Synes du EVMap er nyttig\? Støtt utviklingen ved å sende penger til utvikleren.
\n
\nGoogle tar 15% av alle donasjoner.</string>
<string name="data_sources_hint">I innstillingene kan du også bytte mellom Google Maps og OpenStreetMap (Mapbox) for kartdata.</string>
<string name="data_sources_hint">I innstillingene kan du også bytte mellom Google Maps og OpenStreetMap for kartdata.</string>
</resources>

View File

@@ -3,5 +3,5 @@
<string name="donations_info" formatted="false">Vind je EVMap nuttig\? Je kan de ontwikkeling steunen via een donatie aan de ontwikkelaar.
\n
\nGoogle houdt 15% in van elke donatie.</string>
<string name="data_sources_hint">In de instellingen kan je ook wisselen tussen Google Maps en OpenStreetMap (Mapbox) voor de kaartgegevens.</string>
<string name="data_sources_hint">In de instellingen kan je ook wisselen tussen Google Maps en OpenStreetMap voor de kaartgegevens.</string>
</resources>

View File

@@ -3,5 +3,5 @@
<string name="donations_info" formatted="false">Acha que o EVMap é útil\? Apoie a manutenção e desenvolvimento com uma doação para o desenvolvedor da app.
\n
\nA Google cobra 15% de cada doação.</string>
<string name="data_sources_hint">Também pode mudar entre o Google Maps e OpenStreetMap (Mapbox) nas definições da app.</string>
<string name="data_sources_hint">Também pode mudar entre o Google Maps e OpenStreetMap nas definições da app.</string>
</resources>

View File

@@ -2,7 +2,7 @@
<resources>
<string-array name="pref_map_provider_names">
<item>@string/pref_provider_google_maps</item>
<item>@string/pref_provider_osm_mapbox</item>
<item>@string/pref_provider_osm</item>
</string-array>
<string-array name="pref_map_provider_values" translatable="false">
<item>google</item>

View File

@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string name="donations_info" formatted="false">Do you find EVMap useful? Support its development by sending a donation to the developer.\n\nGoogle takes 15% off every donation.</string>
<string name="data_sources_hint">In the settings you can also switch between Google Maps and OpenStreetMap (Mapbox) for the map data.</string>
<string name="data_sources_hint">In the settings you can also switch between Google Maps and OpenStreetMap for the map data.</string>
</resources>

View File

@@ -47,6 +47,14 @@
android:name="com.mapbox.ACCESS_TOKEN"
android:value="@string/mapbox_key" />
<meta-data
android:name="io.jawg.ACCESS_TOKEN"
android:value="@string/jawg_key" />
<meta-data
android:name="com.arcgis.ACCESS_TOKEN"
android:value="@string/arcgis_key" />
<activity
android:name=".MapsActivity"
android:label="@string/app_name"
@@ -339,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

@@ -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

@@ -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

@@ -113,8 +113,7 @@ class MapboxAutocompleteProvider(val context: Context) : AutocompleteProvider {
override fun getAttributionString(): Int = R.string.powered_by_mapbox
override fun getAttributionImage(dark: Boolean): Int =
if (dark) com.mapbox.mapboxsdk.R.drawable.mapbox_logo_icon else R.drawable.mapbox_logo
override fun getAttributionImage(dark: Boolean): Int = R.drawable.mapbox_logo
}
private fun BoundingBox.toLatLngBounds(): LatLngBounds {

View File

@@ -225,12 +225,12 @@ class MapFragment : Fragment(), OnMapReadyCallback, MapsActivity.FragmentCallbac
mapFragment = MapFragment()
mapFragment!!.priority = arrayOf(
when (provider) {
"mapbox" -> MapFragment.MAPBOX
"mapbox" -> MapFragment.MAPLIBRE
"google" -> MapFragment.GOOGLE
else -> null
},
MapFragment.GOOGLE,
MapFragment.MAPBOX
MapFragment.MAPLIBRE
)
childFragmentManager
.beginTransaction()
@@ -275,7 +275,7 @@ class MapFragment : Fragment(), OnMapReadyCallback, MapsActivity.FragmentCallbac
// set map padding so that compass is not obstructed by toolbar
mapTopPadding = systemWindowInsetTop + (48 * density).toInt() + (16 * density).toInt()
// if we actually use map.setPadding here, Mapbox will re-trigger onApplyWindowInsets
// if we actually use map.setPadding here, MapLibre will re-trigger onApplyWindowInsets
// and cause an infinite loop. So we rely on onMapReady being called later than
// onApplyWindowInsets.
@@ -864,6 +864,7 @@ class MapFragment : Fragment(), OnMapReadyCallback, MapsActivity.FragmentCallbac
if (photo == photos[position] && imageCacheKey != null) {
placeholderMemoryCacheKey(imageCacheKey)
}
allowHardware(false)
}
}
.withTransitionFrom(view as ImageView)
@@ -1052,6 +1053,9 @@ class MapFragment : Fragment(), OnMapReadyCallback, MapsActivity.FragmentCallbac
val context = this.context ?: return
chargerIconGenerator = ChargerIconGenerator(context, map.bitmapDescriptorFactory)
vm.mapTrafficSupported.value =
mapFragment?.let { AnyMap.Feature.TRAFFIC_LAYER in it.supportedFeatures } ?: false
if (BuildConfig.FLAVOR.contains("google") && mapFragment!!.priority[0] == MapFragment.GOOGLE) {
// Google Maps: icons can be generated in background thread
lifecycleScope.launch {
@@ -1060,7 +1064,7 @@ class MapFragment : Fragment(), OnMapReadyCallback, MapsActivity.FragmentCallbac
}
}
} else {
// Mapbox: needs to be run on main thread
// MapLibre: needs to be run on main thread
chargerIconGenerator.preloadCache()
}

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,6 +34,31 @@ 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")

View File

@@ -3,8 +3,9 @@ package net.vonforst.evmap.ui
import android.content.Context
import androidx.appcompat.app.AppCompatDelegate
import androidx.core.os.LocaleListCompat
import net.vonforst.evmap.R
import com.github.erfansn.localeconfigx.configuredLocales
import net.vonforst.evmap.storage.PreferenceDataSource
import java.util.Locale
fun updateNightMode(prefs: PreferenceDataSource) {
@@ -33,8 +34,11 @@ fun getAppLocale(context: Context): String? {
"default"
} else {
val arr = Array(locales.size()) { locales.get(it)!!.toLanguageTag() }
val choices =
context.resources.getStringArray(R.array.pref_language_values).joinToString(",")
LocaleListCompat.forLanguageTags(choices).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

@@ -3,7 +3,16 @@ package net.vonforst.evmap.viewmodel
import android.app.Application
import android.graphics.Point
import android.os.Parcelable
import androidx.lifecycle.*
import androidx.lifecycle.AndroidViewModel
import androidx.lifecycle.LiveData
import androidx.lifecycle.MediatorLiveData
import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.SavedStateHandle
import androidx.lifecycle.distinctUntilChanged
import androidx.lifecycle.liveData
import androidx.lifecycle.map
import androidx.lifecycle.switchMap
import androidx.lifecycle.viewModelScope
import com.car2go.maps.AnyMap
import com.car2go.maps.Projection
import com.car2go.maps.model.LatLng
@@ -24,7 +33,17 @@ import net.vonforst.evmap.api.openchargemap.OCMConnection
import net.vonforst.evmap.api.openchargemap.OCMReferenceData
import net.vonforst.evmap.api.stringProvider
import net.vonforst.evmap.autocomplete.PlaceWithBounds
import net.vonforst.evmap.model.*
import net.vonforst.evmap.model.ChargeLocation
import net.vonforst.evmap.model.Chargepoint
import net.vonforst.evmap.model.ChargepointListItem
import net.vonforst.evmap.model.FILTERS_DISABLED
import net.vonforst.evmap.model.FILTERS_FAVORITES
import net.vonforst.evmap.model.Favorite
import net.vonforst.evmap.model.FavoriteWithDetail
import net.vonforst.evmap.model.FilterValue
import net.vonforst.evmap.model.FilterValues
import net.vonforst.evmap.model.getMultipleChoiceValue
import net.vonforst.evmap.model.getSliderValue
import net.vonforst.evmap.storage.AppDatabase
import net.vonforst.evmap.storage.ChargeLocationsRepository
import net.vonforst.evmap.storage.EncryptedPreferenceDataStore
@@ -282,6 +301,12 @@ class MapViewModel(application: Application, private val state: SavedStateHandle
}
}
val mapTrafficSupported: MutableLiveData<Boolean> by lazy {
MutableLiveData<Boolean>().apply {
value = false
}
}
val mapTrafficEnabled: MutableLiveData<Boolean> by lazy {
MutableLiveData<Boolean>().apply {
value = prefs.mapTrafficEnabled

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

@@ -80,6 +80,7 @@
android:layout_marginEnd="16dp"
android:text="@string/map_details"
android:textAppearance="@style/TextAppearance.Material3.TitleSmall"
app:goneUnless="@{vm.mapTrafficSupported}"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.0"
app:layout_constraintStart_toStartOf="parent"
@@ -94,6 +95,7 @@
android:layout_marginEnd="16dp"
android:text="@string/map_traffic"
android:checked="@={vm.mapTrafficEnabled}"
app:goneUnless="@{vm.mapTrafficSupported}"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/textView23" />

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,19 +258,8 @@
<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>
<string name="about_contributors">Mitwirkende</string>
<string name="about_contributors_text">Dank an alle Mitwirkenden für ihre Beiträge von Code und Übersetzungen für EVMap:</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>
@@ -383,4 +371,5 @@
<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,19 +258,8 @@
<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>
<string name="about_contributors">Contributors</string>
<string name="about_contributors_text">Thanks to all contributors for their coding and translation contributions to EVMap:</string>

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")
@@ -26,9 +26,6 @@ allprojects {
mavenCentral()
//noinspection JcenterRepositoryObsolete
maven { setUrl("https://jitpack.io") }
maven {
setUrl("https://raw.githubusercontent.com/ev-map/mapbox-gl-native-android/mvn")
}
}
}

View File

@@ -17,6 +17,12 @@ be put into the app in the form of a resource file called `apikeys.xml` under
<string name="mapbox_key" translatable="false">
insert your Mapbox key here
</string>
<string name="jawg_key" translatable="false">
insert your Jawg Maps key here
</string>
<string name="arcgis_key" translatable="false">
insert your ArcGIS Maps key here
</string>
<string name="goingelectric_key" translatable="false">
insert your GoingElectric key here
</string>
@@ -52,10 +58,12 @@ Map providers
The different Map SDKs are wrapped by our [fork](https://github.com/ev-map/AnyMaps) of the
[AnyMaps](https://github.com/sharenowTech/AnyMaps) library to provide a common API. The `google`
build flavor of the app includes both Google Maps and Mapbox and allows the user to switch between
the two, while the `foss` flavor only includes the Mapbox SDK.
build flavor of the app includes both Google Maps and OpenStreetMap (vector tiles from
[Jawg Maps](https://www.jawg.io/en/) through [MapLibre](https://maplibre.org/)) and allows the user
to switch between the two, while the `foss` flavor only includes OSM.
> ⚠️ When testing the app using the Android Emulator, we recommend using Google Maps and not Mapbox, as the latter has
> ⚠️ When testing the app using the Android Emulator, we recommend using Google Maps and not
> OSM/MapLibre, as the latter has
[issues displaying the markers](https://github.com/mapbox/mapbox-gl-native/issues/10829). It works fine on real Android devices.
### Google Maps
@@ -77,9 +85,39 @@ the two, while the `foss` flavor only includes the Mapbox SDK.
</details>
### Jawg Maps
[Dynamic Maps](https://www.jawg.io/docs/apidocs/maps/)
<details>
<summary>How to obtain an API key</summary>
1. [Sign up](https://www.jawg.io/lab) for a Jawg account
2. Under [Access Tokens](https://www.jawg.io/lab/access-tokens), copy your default access token or
create a new one. Do not restrict it to a specific origin (this setting is not compatible with
Android apps).
</details>
### ArcGIS
[World Imagery basemap](https://www.arcgis.com/home/item.html?id=10df2279f9684e4a9f6a7f08febac2a9)
*We use this for the satellite map, as [Jawg's](https://blog.jawg.io/satellite-imaging/) satellite
style does not have global coverage.*
<details>
<summary>How to obtain an API key</summary>
1. [Sign up](https://developers.arcgis.com/dashboard/) for an ArcGIS developer account
2. In the dashboard, copy your default API key or create a new one. It has to have access to the
"Basemaps" service.
</details>
### Mapbox
[Maps SDK for Android](https://docs.mapbox.com/android/maps)
[Geocoding API](https://docs.mapbox.com/api/search/geocoding/)
*previously we also used Mapbox's Maps SDK, but this has now been switched to Jawg Maps.*
<details>
<summary>How to obtain an API key</summary>
@@ -91,7 +129,6 @@ the two, while the `foss` flavor only includes the Mapbox SDK.
</details>
Charging station databases
--------------------------

View File

@@ -5,7 +5,7 @@ Funkce:
- Zobrazuje všechny nabíjecí stanice z komunitou spravovaných databází GoingElectric.de a Open Charge Map.
- Informace o dostupnosti v reálném čase (pouze v Evropě)
- Integrované srovnání cen pomocí Chargeprice.app (pouze v Evropě)
- Mapové podklady z OpenStreetMap (Mapbox)
- Mapové podklady z OpenStreetMap
- Vyhledávání míst
- Pokročilé možnosti filtrování, včetně uložených profilů filtrů
- Seznam oblíbených, také s informacemi o dostupnosti

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

@@ -5,7 +5,7 @@ Funktionen:
- Anzeige der Stromtankstellen aus den Stromtankstellenverzeichnissen von GoingElectric.de und Open Charge Map
- Echtzeit-Verfügbarkeitsanzeige für viele Ladesäulen (nur in Europa)
- Integrierter Preisvergleich für die jeweilige Ladesäule mit Chargeprice.app (nur in Europa)
- Kartendaten von OpenStreetMap (Mapbox)
- Kartendaten von OpenStreetMap
- Suche nach Orten
- Erweiterte Filterfunktionen, Filterprofile speichern
- Favoritenliste, auch mit Anzeige der Verfügbarkeit

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

@@ -5,7 +5,7 @@ Features:
- Shows all charging stations from the community-maintained GoingElectric.de and Open Charge Map directories
- Realtime availability information (only in Europe)
- Integrated price comparison using Chargeprice.app (only in Europe)
- Map data from OpenStreetMap (Mapbox)
- Map data from OpenStreetMap
- Search for places
- Advanced filtering options, including saved filter profiles
- Favorites list, also with availability information

View File

Binary file not shown.

Before

Width:  |  Height:  |  Size: 24 KiB

After

Width:  |  Height:  |  Size: 14 KiB

View File

@@ -5,7 +5,7 @@ Caractéristiques :
- Affiche toutes les stations de recharge des répertoires GoingElectric.de et Open Charge Map gérés par la communauté.
- Informations sur la disponibilité en temps réel (uniquement en Europe)
- Comparaison des prix intégrée grâce à Chargeprice.app (uniquement en Europe)
- Données cartographiques provenant d'OpenStreetMap (Mapbox)
- Données cartographiques provenant d'OpenStreetMap
- Recherche de lieux
- Options de filtrage avancées, y compris les profils de filtrage enregistrés
- Liste de favoris, avec également des informations sur la disponibilité

View File

@@ -5,7 +5,7 @@ Du finner info om ladestasjoner i hele verden og sanntidsinfo for mange av dem s
- Materiell design
- Sanntidsinfo (kun i Europa)
- Integrert sammenligningsinfo ved bruk av Chargeprice.app (kun i Europa)
- Kartdata fra OpenStreetMap (Mapbox)
- Kartdata fra OpenStreetMap
- Søk etter steder
- Avanserte filtreringsvalg, inkludert lagrede filterprofiler
- Favorittliste, som også har tilgjengelighetsinfo

View File

@@ -5,7 +5,7 @@ Kenmerken:
- Toont alle laadpunten van de GoingElectric.de en Open Charge Map databanken
- Real-time status (enkel in Europa)
- Geïntegreerde prijsvergelijking via Chargeprice.app (enkel in Europe)
- Kaartgegevens van OpenStreetMap (Mapbox)
- Kaartgegevens van OpenStreetMap
- Zoek naar locaties
- Geavanceerde filtermogelijkheden, inclusief bewaarde filterprofielen
- Lijst van favorieten, met statusinformatie

View File

@@ -5,7 +5,7 @@ Destaques:
- Mostra todas as estações de carregamento dos diretórios GoingElectric.de e Open Charge Map mantidos pela comunidade
- Informação de disponibilidade em tempo real (apenas na Europa)
- Comparação de preços integrada usando o Chargeprice.app (apenas na Europa)
- Informação do mapa via OpenStreetMap (Mapbox)
- Informação do mapa via OpenStreetMap
- Pesquise lugares
- Opções de filtragem avançadas, incluindo filtros de pesquisa que podem ser guardados
- Lista de favoritos, também com informações de disponibilidade

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