mirror of
https://github.com/ev-map/EVMap.git
synced 2025-12-25 16:17:45 -05:00
Compare commits
29 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
086cc51dd3 | ||
|
|
0de91bc107 | ||
|
|
3436bcd870 | ||
|
|
22c150d557 | ||
|
|
675abb5011 | ||
|
|
af2a2cfcae | ||
|
|
f74526fdd6 | ||
|
|
c5bbca0428 | ||
|
|
6167079c0e | ||
|
|
c3836a92ad | ||
|
|
dccce1a0a0 | ||
|
|
74d79640a8 | ||
|
|
0eb6ece780 | ||
|
|
ae15b13591 | ||
|
|
4962eb7268 | ||
|
|
abe360d7c2 | ||
|
|
2aa1fcf5bd | ||
|
|
221e5f49bc | ||
|
|
df6f26ad56 | ||
|
|
1210efd3b9 | ||
|
|
097be8c92b | ||
|
|
16031884ac | ||
|
|
c0b4c56eda | ||
|
|
9587ee948d | ||
|
|
890eec4419 | ||
|
|
c972c871d4 | ||
|
|
e4da902430 | ||
|
|
7a5d4b4107 | ||
|
|
80642b1731 |
@@ -1,7 +1,7 @@
|
||||
EVMap [](https://github.com/johan12345/EVMap/actions)
|
||||
EVMap [](https://github.com/ev-map/EVMap/actions)
|
||||
=====
|
||||
|
||||
<img src="https://raw.githubusercontent.com/johan12345/EVMap/master/_img/feature_graphic.svg" width=700 alt="Logo"/>
|
||||
<img src="https://raw.githubusercontent.com/ev-map/EVMap/master/_img/feature_graphic.svg" width=700 alt="Logo"/>
|
||||
|
||||
Android app to find electric vehicle charging stations.
|
||||
|
||||
@@ -28,7 +28,7 @@ Features
|
||||
Screenshots
|
||||
-----------
|
||||
|
||||
<img src="https://raw.githubusercontent.com/johan12345/EVMap/master/_img/screenshots/phone/en/mapbox/01_map.png" width=250 alt="Screenshot 1"/><img src="https://raw.githubusercontent.com/johan12345/EVMap/master/_img/screenshots/phone/en/mapbox/02_detail.png" width=250 alt="Screenshot 2"/>
|
||||
<img src="https://raw.githubusercontent.com/ev-map/EVMap/master/_img/screenshots/phone/en/mapbox/01_map.png" width=250 alt="Screenshot 1"/><img src="https://raw.githubusercontent.com/ev-map/EVMap/master/_img/screenshots/phone/en/mapbox/02_detail.png" width=250 alt="Screenshot 2"/>
|
||||
|
||||
Development setup
|
||||
-----------------
|
||||
|
||||
@@ -8,9 +8,8 @@ apply plugin: 'kotlin-parcelize'
|
||||
apply plugin: 'kotlin-kapt'
|
||||
apply plugin: 'androidx.navigation.safeargs.kotlin'
|
||||
apply plugin: 'com.mikepenz.aboutlibraries.plugin'
|
||||
apply plugin: 'de.timfreiheit.resourceplaceholders'
|
||||
|
||||
def supportedLocales = "en,de,fr,nb-rNO"
|
||||
def supportedLocales = "en,de,fr,nb-rNO,nl"
|
||||
|
||||
android {
|
||||
compileSdkVersion 33
|
||||
@@ -21,11 +20,11 @@ android {
|
||||
minSdkVersion 21
|
||||
targetSdkVersion 33
|
||||
// NOTE: always increase versionCode by 2 since automotive flavor uses versionCode + 1
|
||||
versionCode 156
|
||||
versionName "1.4.4"
|
||||
versionCode 162
|
||||
versionName "1.4.7"
|
||||
|
||||
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
|
||||
resConfigs supportedLocales.split(",")
|
||||
resConfigs supportedLocales.split(',')
|
||||
buildConfigField("String", "supportedLocales", '"' + supportedLocales + '"')
|
||||
}
|
||||
|
||||
@@ -104,9 +103,6 @@ android {
|
||||
unitTests.includeAndroidResources true
|
||||
}
|
||||
|
||||
resourcePlaceholders {
|
||||
files = ['xml/shortcuts.xml']
|
||||
}
|
||||
namespace 'net.vonforst.evmap'
|
||||
|
||||
// add API keys from environment variable if not set in apikeys.xml
|
||||
@@ -159,19 +155,19 @@ configurations {
|
||||
|
||||
dependencies {
|
||||
implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version"
|
||||
implementation 'androidx.appcompat:appcompat:1.6.0-rc01'
|
||||
implementation 'androidx.appcompat:appcompat:1.6.1'
|
||||
implementation 'androidx.core:core-ktx:1.9.0'
|
||||
implementation 'androidx.core:core-splashscreen:1.0.0'
|
||||
implementation "androidx.activity:activity-ktx:1.6.1"
|
||||
implementation "androidx.fragment:fragment-ktx:1.5.5"
|
||||
implementation 'androidx.cardview:cardview:1.0.0'
|
||||
implementation 'androidx.preference:preference-ktx:1.2.0'
|
||||
implementation 'com.google.android.material:material:1.7.0'
|
||||
implementation 'com.google.android.material:material:1.8.0'
|
||||
implementation 'androidx.constraintlayout:constraintlayout:2.1.4'
|
||||
implementation 'androidx.recyclerview:recyclerview:1.2.1'
|
||||
implementation 'androidx.browser:browser:1.4.0'
|
||||
implementation 'androidx.browser:browser:1.5.0'
|
||||
implementation 'androidx.swiperefreshlayout:swiperefreshlayout:1.1.0'
|
||||
implementation 'com.github.johan12345:CustomBottomSheetBehavior:f4f641aab5'
|
||||
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.9.0'
|
||||
@@ -180,7 +176,7 @@ dependencies {
|
||||
implementation 'com.squareup.moshi:moshi-adapters:1.13.0'
|
||||
implementation 'com.markomilos.jsonapi:jsonapi-retrofit:1.1.0'
|
||||
implementation 'io.coil-kt:coil:1.1.0'
|
||||
implementation 'com.github.johan12345:StfalconImageViewer:5082ebd392'
|
||||
implementation 'com.github.ev-map:StfalconImageViewer:5082ebd392'
|
||||
implementation "com.mikepenz:aboutlibraries-core:$about_libs_version"
|
||||
implementation "com.mikepenz:aboutlibraries:$about_libs_version"
|
||||
implementation 'com.airbnb.android:lottie:4.1.0'
|
||||
@@ -196,22 +192,24 @@ dependencies {
|
||||
googleAutomotiveImplementation "androidx.car.app:app-automotive:$carAppVersion"
|
||||
|
||||
// AnyMaps
|
||||
def anyMapsVersion = 'a9b3dd7d99'
|
||||
implementation "com.github.johan12345.AnyMaps:anymaps-base:$anyMapsVersion"
|
||||
googleImplementation "com.github.johan12345.AnyMaps:anymaps-google:$anyMapsVersion"
|
||||
def anyMapsVersion = '7fdcf50fc4'
|
||||
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.1.0'
|
||||
implementation("com.github.johan12345.AnyMaps:anymaps-mapbox:$anyMapsVersion") {
|
||||
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'
|
||||
}
|
||||
// patched version of mapbox-android-core that removes build-time dependency on GMS
|
||||
implementation 'com.github.johan12345:mapbox-events-android:a21c324501'
|
||||
// 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'
|
||||
|
||||
// Google Places
|
||||
googleImplementation 'com.google.android.libraries.places:places:2.7.0'
|
||||
googleImplementation 'org.jetbrains.kotlinx:kotlinx-coroutines-play-services:1.6.1'
|
||||
googleImplementation 'com.google.android.libraries.places:places:3.0.0'
|
||||
googleImplementation 'org.jetbrains.kotlinx:kotlinx-coroutines-play-services:1.6.4'
|
||||
|
||||
// Mapbox Geocoding
|
||||
implementation 'com.mapbox.mapboxsdk:mapbox-sdk-services:5.5.0'
|
||||
@@ -226,7 +224,7 @@ dependencies {
|
||||
implementation "androidx.lifecycle:lifecycle-livedata-ktx:$lifecycle_version"
|
||||
|
||||
// room library
|
||||
def room_version = "2.4.3"
|
||||
def room_version = "2.5.0"
|
||||
implementation "androidx.room:room-runtime:$room_version"
|
||||
kapt "androidx.room:room-compiler:$room_version"
|
||||
implementation "androidx.room:room-ktx:$room_version"
|
||||
@@ -257,12 +255,12 @@ dependencies {
|
||||
testGoogleImplementation 'org.robolectric:robolectric:4.9'
|
||||
testGoogleImplementation 'androidx.test:core:1.5.0'
|
||||
|
||||
androidTestImplementation 'androidx.test.ext:junit:1.1.4'
|
||||
androidTestImplementation 'androidx.test.espresso:espresso-core:3.5.0'
|
||||
androidTestImplementation 'androidx.test.ext:junit:1.1.5'
|
||||
androidTestImplementation 'androidx.test.espresso:espresso-core:3.5.1'
|
||||
|
||||
kapt "com.squareup.moshi:moshi-kotlin-codegen:1.13.0"
|
||||
|
||||
coreLibraryDesugaring 'com.android.tools:desugar_jdk_libs:1.2.2'
|
||||
coreLibraryDesugaring 'com.android.tools:desugar_jdk_libs:2.0.2'
|
||||
}
|
||||
|
||||
private static String decode(String s, String key) {
|
||||
|
||||
6
app/src/foss/res/values-nl/strings.xml
Normal file
6
app/src/foss/res/values-nl/strings.xml
Normal file
@@ -0,0 +1,6 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<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>
|
||||
</resources>
|
||||
@@ -206,7 +206,7 @@ class ChargepriceScreen(ctx: CarContext, val charger: ChargeLocation) : Screen(c
|
||||
}
|
||||
|
||||
private fun loadPrices(model: Model?) {
|
||||
val dataAdapter = ChargepriceApi.getDataAdapter(charger) ?: return
|
||||
val dataAdapter = ChargepriceApi.getDataAdapter(charger)
|
||||
val manufacturer = model?.manufacturer?.value
|
||||
val modelName = getVehicleModel(model?.manufacturer?.value, model?.name?.value)
|
||||
lifecycleScope.launch {
|
||||
|
||||
@@ -335,7 +335,7 @@ class MapScreen(ctx: CarContext, val session: EVMapSession) :
|
||||
availabilities[charger.id]?.second?.let { av ->
|
||||
val status = av.status.values.flatten()
|
||||
val available = availabilityText(status)
|
||||
val total = charger.chargepoints.sumBy { it.count }
|
||||
val total = charger.chargepoints.sumOf { it.count }
|
||||
|
||||
if (text.isNotEmpty()) text.append(" · ")
|
||||
text.append(
|
||||
@@ -476,7 +476,7 @@ class MapScreen(ctx: CarContext, val session: EVMapSession) :
|
||||
val location = location
|
||||
val heading = heading?.orientations?.value?.get(0)
|
||||
?: if (location?.hasBearing() == true) location.bearing else null
|
||||
return heading?.let { heading ->
|
||||
return heading?.let {
|
||||
if (!prefs.showChargersAheadAndroidAuto) return@let chargers
|
||||
|
||||
chargers?.filter {
|
||||
|
||||
@@ -46,7 +46,7 @@ class PermissionScreen(
|
||||
}
|
||||
|
||||
private fun requestPermissions() {
|
||||
carContext.requestPermissions(permissions) { granted, rejected ->
|
||||
carContext.requestPermissions(permissions) { granted, _ ->
|
||||
if (granted.containsAll(permissions)) {
|
||||
screenManager.pop()
|
||||
} else {
|
||||
|
||||
@@ -148,6 +148,7 @@ class PlaceSearchScreen(ctx: CarContext, val session: EVMapSession) : Screen(ctx
|
||||
}
|
||||
|
||||
private suspend fun loadNewList(query: String) {
|
||||
val location = location?.let { LatLng.fromLocation(it) }
|
||||
for (provider in providers) {
|
||||
try {
|
||||
recentResults.clear()
|
||||
@@ -161,7 +162,7 @@ class PlaceSearchScreen(ctx: CarContext, val session: EVMapSession) : Screen(ctx
|
||||
}
|
||||
recentResults.addAll(recentPlaces)
|
||||
resultList =
|
||||
recentPlaces.map { it.asAutocompletePlace(LatLng.fromLocation(location)) }
|
||||
recentPlaces.map { it.asAutocompletePlace(location) }
|
||||
invalidate()
|
||||
|
||||
// if we already have enough results or the query is short, stop here
|
||||
@@ -170,7 +171,7 @@ class PlaceSearchScreen(ctx: CarContext, val session: EVMapSession) : Screen(ctx
|
||||
// then search online
|
||||
val recentIds = recentPlaces.map { it.id }
|
||||
resultList = withContext(Dispatchers.IO) {
|
||||
(resultList!! + provider.autocomplete(query, LatLng.fromLocation(location))
|
||||
(resultList!! + provider.autocomplete(query, location)
|
||||
.filter { !recentIds.contains(it.id) }).take(maxItems)
|
||||
}
|
||||
invalidate()
|
||||
|
||||
@@ -15,10 +15,7 @@ import androidx.car.app.model.*
|
||||
import androidx.core.graphics.drawable.IconCompat
|
||||
import androidx.lifecycle.lifecycleScope
|
||||
import kotlinx.coroutines.launch
|
||||
import net.vonforst.evmap.BuildConfig
|
||||
import net.vonforst.evmap.EXTRA_DONATE
|
||||
import net.vonforst.evmap.MapsActivity
|
||||
import net.vonforst.evmap.R
|
||||
import net.vonforst.evmap.*
|
||||
import net.vonforst.evmap.api.chargeprice.ChargepriceApi
|
||||
import net.vonforst.evmap.api.chargeprice.ChargepriceCar
|
||||
import net.vonforst.evmap.api.chargeprice.ChargepriceTariff
|
||||
@@ -718,7 +715,7 @@ class DeveloperOptionsScreen(ctx: CarContext) : Screen(ctx) {
|
||||
val hostPackage = carContext.hostInfo?.packageName
|
||||
val hostVersion = hostPackage?.let {
|
||||
try {
|
||||
carContext.packageManager.getPackageInfo(it, 0).versionName
|
||||
carContext.packageManager.getPackageInfoCompat(it).versionName
|
||||
} catch (e: NameNotFoundException) {
|
||||
null
|
||||
}
|
||||
|
||||
@@ -19,6 +19,7 @@ import androidx.core.graphics.drawable.IconCompat
|
||||
import net.vonforst.evmap.BuildConfig
|
||||
import net.vonforst.evmap.R
|
||||
import net.vonforst.evmap.api.availability.ChargepointStatus
|
||||
import net.vonforst.evmap.getPackageInfoCompat
|
||||
import java.util.*
|
||||
import kotlin.math.roundToInt
|
||||
|
||||
@@ -196,7 +197,7 @@ fun <T> List<T>.paginate(nSingle: Int, nFirst: Int, nOther: Int, nLast: Int): Li
|
||||
}
|
||||
|
||||
fun getAndroidAutoVersion(ctx: Context): List<String> {
|
||||
val info = ctx.packageManager.getPackageInfo("com.google.android.projection.gearhead", 0)
|
||||
val info = ctx.packageManager.getPackageInfoCompat("com.google.android.projection.gearhead", 0)
|
||||
return info.versionName.split(".")
|
||||
}
|
||||
|
||||
|
||||
@@ -7,6 +7,7 @@ import android.text.style.StyleSpan
|
||||
import com.car2go.maps.google.adapter.AnyMapAdapter
|
||||
import com.car2go.maps.util.SphericalUtil
|
||||
import com.google.android.gms.common.api.ApiException
|
||||
import com.google.android.gms.common.api.CommonStatusCodes
|
||||
import com.google.android.gms.maps.model.LatLng
|
||||
import com.google.android.gms.maps.model.LatLngBounds
|
||||
import com.google.android.gms.tasks.Tasks.await
|
||||
@@ -19,6 +20,7 @@ import com.google.android.libraries.places.api.net.FindAutocompletePredictionsRe
|
||||
import com.google.android.libraries.places.api.net.PlacesStatusCodes
|
||||
import kotlinx.coroutines.tasks.await
|
||||
import net.vonforst.evmap.R
|
||||
import java.io.IOException
|
||||
import java.util.concurrent.ExecutionException
|
||||
import kotlin.math.sqrt
|
||||
|
||||
@@ -58,6 +60,13 @@ class GooglePlacesAutocompleteProvider(val context: Context) : AutocompleteProvi
|
||||
if (cause is ApiException) {
|
||||
if (cause.statusCode == PlacesStatusCodes.OVER_QUERY_LIMIT) {
|
||||
throw ApiUnavailableException()
|
||||
} else if (cause.statusCode in listOf(
|
||||
CommonStatusCodes.NETWORK_ERROR,
|
||||
CommonStatusCodes.TIMEOUT, CommonStatusCodes.RECONNECTION_TIMED_OUT,
|
||||
CommonStatusCodes.RECONNECTION_TIMED_OUT_DURING_UPDATE
|
||||
)
|
||||
) {
|
||||
throw IOException(cause)
|
||||
}
|
||||
}
|
||||
throw e
|
||||
|
||||
@@ -15,6 +15,12 @@ class DonateViewModel(application: Application) : AndroidViewModel(application),
|
||||
.setListener(this)
|
||||
.enablePendingPurchases()
|
||||
.build()
|
||||
|
||||
val products: MutableLiveData<Resource<List<DonationItem>>> by lazy {
|
||||
MutableLiveData<Resource<List<DonationItem>>>().apply {
|
||||
value = Resource.loading(null)
|
||||
}
|
||||
}
|
||||
|
||||
init {
|
||||
billingClient.startConnection(object : BillingClientStateListener {
|
||||
@@ -70,12 +76,6 @@ class DonateViewModel(application: Application) : AndroidViewModel(application),
|
||||
}
|
||||
}
|
||||
|
||||
val products: MutableLiveData<Resource<List<DonationItem>>> by lazy {
|
||||
MutableLiveData<Resource<List<DonationItem>>>().apply {
|
||||
value = Resource.loading(null)
|
||||
}
|
||||
}
|
||||
|
||||
val purchaseSuccessful = SingleLiveEvent<Nothing>()
|
||||
val purchaseFailed = SingleLiveEvent<Nothing>()
|
||||
|
||||
|
||||
@@ -36,4 +36,6 @@
|
||||
<string name="sounds_cool">den er grei</string>
|
||||
<string name="auto_chargers_ahead">Kun ladere i kjøreretningen</string>
|
||||
<string name="loading">Laster inn …</string>
|
||||
<string name="auto_multipage_goto">Side %d</string>
|
||||
<string name="auto_multipage">(%d/%d)</string>
|
||||
</resources>
|
||||
41
app/src/google/res/values-nl/strings.xml
Normal file
41
app/src/google/res/values-nl/strings.xml
Normal file
@@ -0,0 +1,41 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<resources>
|
||||
<string name="auto_chargeprice_vehicle_ambiguous">Meerdere voertuigen geselecteerd in de app komen overeen met dit voertuig (%1$s %2$s).</string>
|
||||
<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="auto_location_service">EVMap draait op Android Auto en gebruikt jouw locatie.</string>
|
||||
<string name="auto_no_chargers_found">Geen laadpunten gevonden in de omgeving</string>
|
||||
<string name="auto_no_favorites_found">Geen favorieten gevonden</string>
|
||||
<string name="open_in_app">Open in de app</string>
|
||||
<string name="opened_on_phone">Geopend op de telefoon</string>
|
||||
<string name="auto_location_permission_needed">Om EVMap op Android Auto te gebruiken, moet je toegang geven tot je locatie.</string>
|
||||
<string name="auto_vehicle_data_permission_needed">Voor deze functie heeft EVMap toegang nodig tot de gegevens van je voertuig.</string>
|
||||
<string name="grant_on_phone">Geef toestemming op telefoon</string>
|
||||
<string name="auto_chargers_closeby">Oplaadpunten in de buurt</string>
|
||||
<string name="auto_favorites">Favorieten</string>
|
||||
<string name="auto_chargers_near_location">Nabij %s</string>
|
||||
<string name="auto_fault_report_date">⚠️ Foutrapport (%s)</string>
|
||||
<string name="auto_no_refresh_possible">Verdere updates zijn niet mogelijk. Ga terug en herbegin.</string>
|
||||
<string name="auto_prices">Prijzen</string>
|
||||
<string name="auto_vehicle_data">Voertuiggegevens</string>
|
||||
<string name="auto_charging_level">Laadniveau (SoC)</string>
|
||||
<string name="auto_no_data">Niet beschikbaar</string>
|
||||
<string name="auto_range">Reikwijdte</string>
|
||||
<string name="auto_speed">Snelheid</string>
|
||||
<string name="auto_heading">Richting</string>
|
||||
<string name="auto_settings">Instellingen</string>
|
||||
<string name="welcome_android_auto">Android Auto support</string>
|
||||
<string name="welcome_android_auto_detail">Je kan EVMap ook gebruiken in Android Auto op ondersteunde voertuigen. Selecteer gewoon de EVMap app in het Android Auto menu.</string>
|
||||
<string name="sounds_cool">klinkt cool</string>
|
||||
<string name="auto_chargeprice_vehicle_unavailable">EVMap kon je voertuigtype niet bepalen.</string>
|
||||
<string name="auto_chargers_ahead">Alleen laadpunten in rijrichting</string>
|
||||
<string name="settings_android_auto_chargeprice_range">Laadbereik voor prijsvergelijking</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="selecting_all">alle items geselecteerd</string>
|
||||
<string name="selecting_none">alle items gedeselecteerd</string>
|
||||
<string name="loading">Laden…</string>
|
||||
<string name="auto_multipage_goto">Pagina %d</string>
|
||||
<string name="auto_multipage">(%d/%d)</string>
|
||||
<string name="auto_chargeprice_vehicle_unknown">Geen enkel voertuig geselecteerd in de app komt overeen met dit voertuig (%1$s %2$s).</string>
|
||||
</resources>
|
||||
5
app/src/googleAutomotive/res/values-nl/strings.xml
Normal file
5
app/src/googleAutomotive/res/values-nl/strings.xml
Normal file
@@ -0,0 +1,5 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<resources>
|
||||
<string name="grant_on_phone">Toestaan</string>
|
||||
<string name="auto_location_permission_needed">Om EVmap te gebruiken in je wagen, moet je toegang geven tot je locatie.</string>
|
||||
</resources>
|
||||
@@ -76,7 +76,7 @@ class MapsActivity : AppCompatActivity(),
|
||||
val navView = findViewById<NavigationView>(R.id.nav_view)
|
||||
navView.setupWithNavController(navController)
|
||||
|
||||
ViewCompat.setOnApplyWindowInsetsListener(navView) { v, insets ->
|
||||
ViewCompat.setOnApplyWindowInsetsListener(navView) { _, insets ->
|
||||
val header = navView.getHeaderView(0)
|
||||
header.setPadding(0, insets.getInsets(WindowInsetsCompat.Type.statusBars()).top, 0, 0)
|
||||
insets
|
||||
|
||||
@@ -1,8 +1,11 @@
|
||||
package net.vonforst.evmap
|
||||
|
||||
import android.content.Context
|
||||
import android.content.pm.PackageInfo
|
||||
import android.content.pm.PackageManager
|
||||
import android.content.res.Configuration
|
||||
import android.graphics.Typeface
|
||||
import android.os.Build
|
||||
import android.os.Bundle
|
||||
import android.text.*
|
||||
import android.text.style.StyleSpan
|
||||
@@ -72,7 +75,7 @@ fun max(a: Int?, b: Int?): Int? {
|
||||
* otherwise the non-null value or null
|
||||
*/
|
||||
return if (a != null && b != null) {
|
||||
max(a, b)
|
||||
kotlin.math.max(a, b)
|
||||
} else {
|
||||
a ?: b
|
||||
}
|
||||
@@ -88,4 +91,11 @@ const val meterPerFt = 0.3048
|
||||
|
||||
fun shouldUseImperialUnits(): Boolean {
|
||||
return Locale.getDefault().country in listOf("US", "GB", "MM", "LR")
|
||||
}
|
||||
}
|
||||
|
||||
fun PackageManager.getPackageInfoCompat(packageName: String, flags: Int = 0): PackageInfo =
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
|
||||
getPackageInfo(packageName, PackageManager.PackageInfoFlags.of(flags.toLong()))
|
||||
} else {
|
||||
@Suppress("DEPRECATION") getPackageInfo(packageName, flags)
|
||||
}
|
||||
@@ -1,7 +1,6 @@
|
||||
package net.vonforst.evmap.adapter
|
||||
|
||||
import android.view.LayoutInflater
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import androidx.databinding.DataBindingUtil
|
||||
import androidx.databinding.ViewDataBinding
|
||||
@@ -166,7 +165,7 @@ class CheckableConnectorAdapter : DataBindingAdapter<Chargepoint>() {
|
||||
root.setOnClickListener {
|
||||
root.isChecked = true
|
||||
}
|
||||
root.setOnCheckedChangeListener { v: View, checked: Boolean ->
|
||||
root.setOnCheckedChangeListener { _, checked: Boolean ->
|
||||
if (checked) {
|
||||
checkedItem = holder.bindingAdapterPosition.takeIf { it != -1 }
|
||||
root.post {
|
||||
@@ -205,7 +204,7 @@ class CheckableChargepriceCarAdapter : DataBindingAdapter<ChargepriceCar>() {
|
||||
root.setOnClickListener {
|
||||
root.isChecked = true
|
||||
}
|
||||
root.setOnCheckedChangeListener { v: View, checked: Boolean ->
|
||||
root.setOnCheckedChangeListener { _, checked: Boolean ->
|
||||
if (checked && item != checkedItem) {
|
||||
checkedItem = item
|
||||
root.post {
|
||||
|
||||
@@ -25,7 +25,7 @@ class FilterProfilesAdapter(
|
||||
super.bind(holder, item)
|
||||
|
||||
val binding = holder.binding as ItemFilterProfileBinding
|
||||
binding.handle.setOnTouchListener { v, event ->
|
||||
binding.handle.setOnTouchListener { _, event ->
|
||||
if (event?.action == MotionEvent.ACTION_DOWN) {
|
||||
dragHelper.startDrag(holder)
|
||||
}
|
||||
|
||||
@@ -71,19 +71,19 @@ abstract class BaseAvailabilityDetector(private val client: OkHttpClient) : Avai
|
||||
connectors: Map<Long, Pair<Double, String>>,
|
||||
chargepoints: List<Chargepoint>
|
||||
): Map<Chargepoint, Set<Long>> {
|
||||
var chargepoints = chargepoints
|
||||
var cpts = chargepoints
|
||||
|
||||
// iterate over each connector type
|
||||
val types = connectors.map { it.value.second }.distinct().toSet()
|
||||
val equivalentTypes = types.map { equivalentPlugTypes(it).plus(it) }.cartesianProduct()
|
||||
var geTypes = chargepoints.map { it.type }.distinct().toSet()
|
||||
var geTypes = cpts.map { it.type }.distinct().toSet()
|
||||
if (!equivalentTypes.any { it == geTypes } && geTypes.size > 1 && geTypes.contains(
|
||||
Chargepoint.SCHUKO
|
||||
)) {
|
||||
// If charger has household plugs and other plugs, try removing the household plugs
|
||||
// (common e.g. in Hamburg -> 2x Type 2 + 2x Schuko, but NM only lists Type 2)
|
||||
geTypes = geTypes.filter { it != Chargepoint.SCHUKO }.toSet()
|
||||
chargepoints = chargepoints.filter { it.type != Chargepoint.SCHUKO }
|
||||
cpts = cpts.filter { it.type != Chargepoint.SCHUKO }
|
||||
}
|
||||
if (!equivalentTypes.any { it == geTypes }) throw AvailabilityDetectorException("chargepoints do not match")
|
||||
return types.flatMap { type ->
|
||||
@@ -93,14 +93,14 @@ abstract class BaseAvailabilityDetector(private val client: OkHttpClient) : Avai
|
||||
val powers = connsOfType.map { it.value.first }.distinct().sorted()
|
||||
// find corresponding powers in GE data
|
||||
val gePowers =
|
||||
chargepoints.filter { equivalentPlugTypes(it.type).any { it == type } }
|
||||
cpts.filter { equivalentPlugTypes(it.type).any { it == type } }
|
||||
.mapNotNull { it.power }.distinct().sorted()
|
||||
|
||||
// if the distinct number of powers is the same, try to match.
|
||||
if (powers.size == gePowers.size) {
|
||||
gePowers.zip(powers).map { (gePower, power) ->
|
||||
val chargepoint =
|
||||
chargepoints.find { equivalentPlugTypes(it.type).any { it == type } && it.power == gePower }!!
|
||||
cpts.find { equivalentPlugTypes(it.type).any { it == type } && it.power == gePower }!!
|
||||
val ids = connsOfType.filter { it.value.first == power }.keys
|
||||
if (chargepoint.count != ids.size) {
|
||||
throw AvailabilityDetectorException("chargepoints do not match")
|
||||
@@ -108,7 +108,7 @@ abstract class BaseAvailabilityDetector(private val client: OkHttpClient) : Avai
|
||||
chargepoint to ids
|
||||
}
|
||||
} else if (powers.size == 1 && gePowers.size == 2
|
||||
&& chargepoints.sumOf { it.count } == connsOfType.size
|
||||
&& cpts.sumOf { it.count } == connsOfType.size
|
||||
) {
|
||||
// special case: dual charger(s) with load balancing
|
||||
// GoingElectric shows 2 different powers, NewMotion just one
|
||||
@@ -116,7 +116,7 @@ abstract class BaseAvailabilityDetector(private val client: OkHttpClient) : Avai
|
||||
var i = 0
|
||||
gePowers.map { gePower ->
|
||||
val chargepoint =
|
||||
chargepoints.find { it.type in equivalentPlugTypes(type) && it.power == gePower }!!
|
||||
cpts.find { it.type in equivalentPlugTypes(type) && it.power == gePower }!!
|
||||
val ids = allIds.subList(i, i + chargepoint.count).toSet()
|
||||
i += chargepoint.count
|
||||
chargepoint to ids
|
||||
|
||||
@@ -51,7 +51,7 @@ interface ChargecloudApi {
|
||||
)
|
||||
|
||||
companion object {
|
||||
fun create(client: OkHttpClient, baseUrl: String? = null): ChargecloudApi {
|
||||
fun create(client: OkHttpClient, baseUrl: String): ChargecloudApi {
|
||||
val retrofit = Retrofit.Builder()
|
||||
.baseUrl(baseUrl)
|
||||
.addConverterFactory(MoshiConverterFactory.create())
|
||||
|
||||
@@ -140,7 +140,7 @@ class NewMotionAvailabilityDetector(client: OkHttpClient, baseUrl: String? = nul
|
||||
connectorStatus.forEach { (connector, statusStr, evseId) ->
|
||||
val id = connector.uid
|
||||
val power = connector.electricalProperties.getPower()
|
||||
val type = when (connector.connectorType.toLowerCase(Locale.ROOT)) {
|
||||
val type = when (connector.connectorType.lowercase(Locale.ROOT)) {
|
||||
"type3" -> Chargepoint.TYPE_3
|
||||
"type2" -> Chargepoint.TYPE_2_UNKNOWN
|
||||
"type1" -> Chargepoint.TYPE_1
|
||||
|
||||
@@ -163,7 +163,7 @@ interface ChargepriceApi {
|
||||
"Spanien",
|
||||
"Großbritannien",
|
||||
"Irland",
|
||||
// additional countries found 2022/09/17, https://github.com/johan12345/EVMap/issues/234
|
||||
// additional countries found 2022/09/17, https://github.com/ev-map/EVMap/issues/234
|
||||
"Finnland",
|
||||
"Lettland",
|
||||
"Litauen",
|
||||
@@ -202,7 +202,7 @@ interface ChargepriceApi {
|
||||
"ES",
|
||||
"GB",
|
||||
"IE",
|
||||
// additional countries found 2022/09/17, https://github.com/johan12345/EVMap/issues/234
|
||||
// additional countries found 2022/09/17, https://github.com/ev-map/EVMap/issues/234
|
||||
"FI",
|
||||
"LV",
|
||||
"LT",
|
||||
|
||||
@@ -71,10 +71,10 @@ internal class JsonObjectOrFalseAdapter<T> private constructor(
|
||||
private val clazz: Class<*>
|
||||
) : JsonAdapter<T>() {
|
||||
|
||||
class Factory() : JsonAdapter.Factory {
|
||||
class Factory : JsonAdapter.Factory {
|
||||
override fun create(
|
||||
type: Type,
|
||||
annotations: Set<Annotation>?,
|
||||
annotations: Set<Annotation>,
|
||||
moshi: Moshi
|
||||
): JsonAdapter<Any>? {
|
||||
val clazz = Types.getRawType(type)
|
||||
|
||||
@@ -399,10 +399,10 @@ class GoingElectricApiWrapper(
|
||||
referenceData: ReferenceData,
|
||||
sp: StringProvider
|
||||
): List<Filter<FilterValue>> {
|
||||
val referenceData = referenceData as GEReferenceData
|
||||
val plugs = referenceData.plugs
|
||||
val networks = referenceData.networks
|
||||
val chargeCards = referenceData.chargecards
|
||||
val refData = referenceData as GEReferenceData
|
||||
val plugs = refData.plugs
|
||||
val networks = refData.networks
|
||||
val chargeCards = refData.chargecards
|
||||
|
||||
val plugMap = plugs.map { plug ->
|
||||
plug to nameForPlugType(sp, GEChargepoint.convertTypeFromGE(plug))
|
||||
|
||||
@@ -120,7 +120,7 @@ class OpenChargeMapApiWrapper(
|
||||
zoom: Float,
|
||||
filters: FilterValues?,
|
||||
): Resource<List<ChargepointListItem>> {
|
||||
val referenceData = referenceData as OCMReferenceData
|
||||
val refData = referenceData as OCMReferenceData
|
||||
|
||||
val minPower = filters?.getSliderValue("min_power")?.toDouble()
|
||||
val minConnectors = filters?.getSliderValue("min_connectors")
|
||||
@@ -160,7 +160,7 @@ class OpenChargeMapApiWrapper(
|
||||
minPower,
|
||||
connectorsVal,
|
||||
minConnectors,
|
||||
referenceData,
|
||||
refData,
|
||||
zoom
|
||||
)
|
||||
return Resource.success(result)
|
||||
@@ -176,7 +176,7 @@ class OpenChargeMapApiWrapper(
|
||||
zoom: Float,
|
||||
filters: FilterValues?
|
||||
): Resource<List<ChargepointListItem>> {
|
||||
val referenceData = referenceData as OCMReferenceData
|
||||
val refData = referenceData as OCMReferenceData
|
||||
|
||||
val minPower = filters?.getSliderValue("min_power")?.toDouble()
|
||||
val minConnectors = filters?.getSliderValue("min_connectors")
|
||||
@@ -214,7 +214,7 @@ class OpenChargeMapApiWrapper(
|
||||
minPower,
|
||||
connectorsVal,
|
||||
minConnectors,
|
||||
referenceData,
|
||||
refData,
|
||||
zoom
|
||||
)
|
||||
return Resource.success(result)
|
||||
@@ -254,11 +254,11 @@ class OpenChargeMapApiWrapper(
|
||||
referenceData: ReferenceData,
|
||||
id: Long
|
||||
): Resource<ChargeLocation> {
|
||||
val referenceData = referenceData as OCMReferenceData
|
||||
val refData = referenceData as OCMReferenceData
|
||||
try {
|
||||
val response = api.getChargepointDetail(id)
|
||||
if (response.isSuccessful && response.body()?.size == 1) {
|
||||
return Resource.success(response.body()!![0].convert(referenceData, true))
|
||||
return Resource.success(response.body()!![0].convert(refData, true))
|
||||
} else {
|
||||
return Resource.error(response.message(), null)
|
||||
}
|
||||
@@ -284,10 +284,10 @@ class OpenChargeMapApiWrapper(
|
||||
referenceData: ReferenceData,
|
||||
sp: StringProvider
|
||||
): List<Filter<FilterValue>> {
|
||||
val referenceData = referenceData as OCMReferenceData
|
||||
val refData = referenceData as OCMReferenceData
|
||||
|
||||
val operatorsMap = referenceData.operators.map { it.id.toString() to it.title }.toMap()
|
||||
val plugMap = referenceData.connectionTypes.map { it.id.toString() to it.title }.toMap()
|
||||
val operatorsMap = refData.operators.map { it.id.toString() to it.title }.toMap()
|
||||
val plugMap = refData.connectionTypes.map { it.id.toString() to it.title }.toMap()
|
||||
|
||||
return listOf(
|
||||
// supported by OCM API
|
||||
|
||||
@@ -44,8 +44,7 @@ class FavoritesFragment : Fragment() {
|
||||
private val vm: FavoritesViewModel by viewModels(factoryProducer = {
|
||||
viewModelFactory {
|
||||
FavoritesViewModel(
|
||||
requireActivity().application,
|
||||
getString(R.string.goingelectric_key)
|
||||
requireActivity().application
|
||||
)
|
||||
}
|
||||
})
|
||||
|
||||
@@ -98,6 +98,12 @@ class FilterFragment : Fragment(), MenuProvider {
|
||||
saveProfile()
|
||||
true
|
||||
}
|
||||
R.id.menu_reset -> {
|
||||
lifecycleScope.launch {
|
||||
vm.resetValues()
|
||||
}
|
||||
true
|
||||
}
|
||||
else -> false
|
||||
}
|
||||
}
|
||||
@@ -114,7 +120,7 @@ class FilterFragment : Fragment(), MenuProvider {
|
||||
|
||||
dialog.setTitle(R.string.save_as_profile)
|
||||
.setMessage(R.string.save_profile_enter_name)
|
||||
.setPositiveButton(R.string.ok) { di, button ->
|
||||
.setPositiveButton(R.string.ok) { _, _ ->
|
||||
if (input.text.isBlank()) {
|
||||
saveProfile(true)
|
||||
} else {
|
||||
@@ -124,7 +130,7 @@ class FilterFragment : Fragment(), MenuProvider {
|
||||
}
|
||||
}
|
||||
}
|
||||
.setNegativeButton(R.string.cancel) { di, button ->
|
||||
.setNegativeButton(R.string.cancel) { _, _ ->
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -188,12 +188,12 @@ class FilterProfilesFragment : Fragment() {
|
||||
|
||||
dialog.setTitle(R.string.rename)
|
||||
.setMessage(R.string.save_profile_enter_name)
|
||||
.setPositiveButton(R.string.ok) { di, button ->
|
||||
.setPositiveButton(R.string.ok) { _, _ ->
|
||||
lifecycleScope.launch {
|
||||
vm.update(fp.copy(name = input.text.toString()))
|
||||
}
|
||||
}
|
||||
.setNegativeButton(R.string.cancel) { di, button ->
|
||||
.setNegativeButton(R.string.cancel) { _, _ ->
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -91,6 +91,7 @@ import kotlin.collections.component1
|
||||
import kotlin.collections.component2
|
||||
import kotlin.collections.contains
|
||||
import kotlin.collections.set
|
||||
import kotlin.math.min
|
||||
|
||||
|
||||
class MapFragment : Fragment(), OnMapReadyCallback, MapsActivity.FragmentCallback, MenuProvider {
|
||||
@@ -197,7 +198,7 @@ class MapFragment : Fragment(), OnMapReadyCallback, MapsActivity.FragmentCallbac
|
||||
|
||||
ViewCompat.setOnApplyWindowInsetsListener(
|
||||
binding.root
|
||||
) { v, insets ->
|
||||
) { _, insets ->
|
||||
ViewCompat.onApplyWindowInsets(binding.root, insets)
|
||||
|
||||
val systemWindowInsetTop = insets.getInsets(WindowInsetsCompat.Type.statusBars()).top
|
||||
@@ -465,7 +466,7 @@ class MapFragment : Fragment(), OnMapReadyCallback, MapsActivity.FragmentCallbac
|
||||
}
|
||||
)
|
||||
}
|
||||
binding.search.onFocusChangeListener = View.OnFocusChangeListener { v, hasFocus ->
|
||||
binding.search.onFocusChangeListener = View.OnFocusChangeListener { _, hasFocus ->
|
||||
if (hasFocus) {
|
||||
binding.search.keyListener = searchKeyListener
|
||||
binding.search.text = binding.search.text // workaround to fix copy/paste
|
||||
@@ -553,7 +554,17 @@ class MapFragment : Fragment(), OnMapReadyCallback, MapsActivity.FragmentCallbac
|
||||
bottomSheetBehavior.addBottomSheetCallback(object :
|
||||
BottomSheetBehaviorGoogleMapsLike.BottomSheetCallback() {
|
||||
override fun onSlide(bottomSheet: View, slideOffset: Float) {
|
||||
|
||||
if (bottomSheetBehavior.state == STATE_HIDDEN) {
|
||||
map?.setPadding(0, mapTopPadding, 0, 0)
|
||||
} else {
|
||||
val height = binding.root.height - bottomSheet.top
|
||||
map?.setPadding(
|
||||
0,
|
||||
mapTopPadding,
|
||||
0,
|
||||
min(bottomSheetBehavior.peekHeight, height)
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
override fun onStateChanged(bottomSheet: View, newState: Int) {
|
||||
@@ -561,9 +572,9 @@ class MapFragment : Fragment(), OnMapReadyCallback, MapsActivity.FragmentCallbac
|
||||
updateBackPressedCallback()
|
||||
|
||||
if (vm.layersMenuOpen.value!! && newState !in listOf(
|
||||
BottomSheetBehaviorGoogleMapsLike.STATE_SETTLING,
|
||||
BottomSheetBehaviorGoogleMapsLike.STATE_HIDDEN,
|
||||
BottomSheetBehaviorGoogleMapsLike.STATE_COLLAPSED
|
||||
STATE_SETTLING,
|
||||
STATE_HIDDEN,
|
||||
STATE_COLLAPSED
|
||||
)
|
||||
) {
|
||||
closeLayersMenu()
|
||||
@@ -1189,6 +1200,7 @@ class MapFragment : Fragment(), OnMapReadyCallback, MapsActivity.FragmentCallbac
|
||||
)
|
||||
popup.menuInflater.inflate(R.menu.popup_filter, popup.menu)
|
||||
MenuCompat.setGroupDividerEnabled(popup.menu, true)
|
||||
popup.setForceShowIcon(true)
|
||||
popup.setOnMenuItemClickListener {
|
||||
when (it.itemId) {
|
||||
R.id.menu_edit_filters -> {
|
||||
|
||||
@@ -71,7 +71,7 @@ class MultiSelectDialog : MaterialDialogFragment() {
|
||||
binding.btnAll.visibility = if (showAllButton) View.VISIBLE else View.INVISIBLE
|
||||
|
||||
items = data.entries.toList()
|
||||
.sortedBy { it.value.toLowerCase(Locale.getDefault()) }
|
||||
.sortedBy { it.value.lowercase(Locale.getDefault()) }
|
||||
.sortedBy {
|
||||
when {
|
||||
selected.contains(it.key) && commonChoices?.contains(it.key) == true -> 0
|
||||
@@ -117,7 +117,7 @@ private fun search(
|
||||
): List<MultiSelectItem> {
|
||||
return items.filter { item ->
|
||||
// search for string within name
|
||||
text.toLowerCase(Locale.getDefault()) in item.name.toLowerCase(Locale.getDefault())
|
||||
text.lowercase(Locale.getDefault()) in item.name.lowercase(Locale.getDefault())
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -111,7 +111,7 @@ data class ChargeLocation(
|
||||
|
||||
// check if there is more than one plug for any connector type
|
||||
val chargepointsPerConnector =
|
||||
connectors.map { conn -> chargepoints.filter { it.type == conn }.sumBy { it.count } }
|
||||
connectors.map { conn -> chargepoints.filter { it.type == conn }.sumOf { it.count } }
|
||||
return chargepointsPerConnector.any { it > 1 }
|
||||
}
|
||||
|
||||
@@ -127,13 +127,13 @@ data class ChargeLocation(
|
||||
return variants.map { variant ->
|
||||
val count = chargepoints
|
||||
.filter { it.type == variant.type && it.power == variant.power }
|
||||
.sumBy { it.count }
|
||||
.sumOf { it.count }
|
||||
Chargepoint(variant.type, variant.power, count)
|
||||
}
|
||||
}
|
||||
|
||||
val totalChargepoints: Int
|
||||
get() = chargepoints.sumBy { it.count }
|
||||
get() = chargepoints.sumOf { it.count }
|
||||
|
||||
fun formatChargepoints(sp: StringProvider): String {
|
||||
return chargepointsMerged.map {
|
||||
|
||||
@@ -1,29 +1,49 @@
|
||||
package net.vonforst.evmap.storage
|
||||
|
||||
import androidx.lifecycle.liveData
|
||||
import androidx.lifecycle.LiveData
|
||||
import androidx.lifecycle.MediatorLiveData
|
||||
import androidx.lifecycle.MutableLiveData
|
||||
import androidx.room.*
|
||||
import net.vonforst.evmap.model.*
|
||||
|
||||
@Dao
|
||||
abstract class FilterValueDao {
|
||||
@Query("SELECT * FROM booleanfiltervalue WHERE profile = :profile AND dataSource = :dataSource")
|
||||
protected abstract suspend fun getBooleanFilterValues(
|
||||
protected abstract suspend fun getBooleanFilterValuesAsync(
|
||||
profile: Long,
|
||||
dataSource: String
|
||||
): List<BooleanFilterValue>
|
||||
|
||||
@Query("SELECT * FROM multiplechoicefiltervalue WHERE profile = :profile AND dataSource = :dataSource")
|
||||
protected abstract suspend fun getMultipleChoiceFilterValues(
|
||||
protected abstract suspend fun getMultipleChoiceFilterValuesAsync(
|
||||
profile: Long,
|
||||
dataSource: String
|
||||
): List<MultipleChoiceFilterValue>
|
||||
|
||||
@Query("SELECT * FROM sliderfiltervalue WHERE profile = :profile AND dataSource = :dataSource")
|
||||
protected abstract suspend fun getSliderFilterValues(
|
||||
protected abstract suspend fun getSliderFilterValuesAsync(
|
||||
profile: Long,
|
||||
dataSource: String
|
||||
): List<SliderFilterValue>
|
||||
|
||||
@Query("SELECT * FROM booleanfiltervalue WHERE profile = :profile AND dataSource = :dataSource")
|
||||
protected abstract fun getBooleanFilterValues(
|
||||
profile: Long,
|
||||
dataSource: String
|
||||
): LiveData<List<BooleanFilterValue>>
|
||||
|
||||
@Query("SELECT * FROM multiplechoicefiltervalue WHERE profile = :profile AND dataSource = :dataSource")
|
||||
protected abstract fun getMultipleChoiceFilterValues(
|
||||
profile: Long,
|
||||
dataSource: String
|
||||
): LiveData<List<MultipleChoiceFilterValue>>
|
||||
|
||||
@Query("SELECT * FROM sliderfiltervalue WHERE profile = :profile AND dataSource = :dataSource")
|
||||
protected abstract fun getSliderFilterValues(
|
||||
profile: Long,
|
||||
dataSource: String
|
||||
): LiveData<List<SliderFilterValue>>
|
||||
|
||||
@Insert(onConflict = OnConflictStrategy.REPLACE)
|
||||
protected abstract suspend fun insert(vararg values: BooleanFilterValue)
|
||||
|
||||
@@ -58,15 +78,32 @@ abstract class FilterValueDao {
|
||||
if (filterStatus == FILTERS_DISABLED || filterStatus == FILTERS_FAVORITES) {
|
||||
emptyList()
|
||||
} else {
|
||||
getBooleanFilterValues(filterStatus, dataSource) +
|
||||
getMultipleChoiceFilterValues(filterStatus, dataSource) +
|
||||
getSliderFilterValues(filterStatus, dataSource)
|
||||
getBooleanFilterValuesAsync(filterStatus, dataSource) +
|
||||
getMultipleChoiceFilterValuesAsync(filterStatus, dataSource) +
|
||||
getSliderFilterValuesAsync(filterStatus, dataSource)
|
||||
}
|
||||
|
||||
open fun getFilterValues(filterStatus: Long, dataSource: String) = liveData {
|
||||
emit(null)
|
||||
emit(getFilterValuesAsync(filterStatus, dataSource))
|
||||
}
|
||||
open fun getFilterValues(filterStatus: Long, dataSource: String): LiveData<List<FilterValue>?> =
|
||||
if (filterStatus == FILTERS_DISABLED || filterStatus == FILTERS_FAVORITES) {
|
||||
MutableLiveData(emptyList())
|
||||
} else {
|
||||
MediatorLiveData<List<FilterValue>?>().apply {
|
||||
value = null
|
||||
val sources = listOf(
|
||||
getBooleanFilterValues(filterStatus, dataSource),
|
||||
getMultipleChoiceFilterValues(filterStatus, dataSource),
|
||||
getSliderFilterValues(filterStatus, dataSource)
|
||||
)
|
||||
for (source in sources) {
|
||||
addSource(source) {
|
||||
val values = sources.map { it.value }
|
||||
if (values.all { it != null }) {
|
||||
value = values.filterNotNull().flatten()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Transaction
|
||||
open suspend fun insert(vararg values: FilterValue) {
|
||||
|
||||
@@ -211,12 +211,12 @@ class BarGraphView(context: Context, attrs: AttributeSet) : View(context, attrs)
|
||||
private fun drawBubble(canvas: Canvas, data: SortedMap<ZonedDateTime, Int>, maxValue: Int) {
|
||||
val bubbleBounds = bubbleBounds ?: return
|
||||
val graphBounds = graphBounds ?: return
|
||||
val data = data.toList()
|
||||
val d = data.toList()
|
||||
|
||||
if (data.size <= selectedBar) return
|
||||
if (d.size <= selectedBar) return
|
||||
canvas.apply {
|
||||
val center = graphBounds.left + selectedBar * (barWidth + barMargin) + barWidth * 0.5f
|
||||
val (t, v) = data[selectedBar]
|
||||
val (t, v) = d[selectedBar]
|
||||
val tformat = context.getString(
|
||||
R.string.prediction_time_colon,
|
||||
t.withZoneSameInstant(ZoneId.systemDefault()).format(timeFormat)
|
||||
|
||||
@@ -121,6 +121,7 @@ private fun activeTint(
|
||||
}
|
||||
|
||||
@BindingAdapter("data")
|
||||
@Suppress("UNCHECKED_CAST")
|
||||
fun <T> setRecyclerViewData(recyclerView: RecyclerView, items: List<T>?) {
|
||||
if (recyclerView.adapter is ListAdapter<*, *>) {
|
||||
(recyclerView.adapter as ListAdapter<T, *>).submitList(items)
|
||||
@@ -128,6 +129,7 @@ fun <T> setRecyclerViewData(recyclerView: RecyclerView, items: List<T>?) {
|
||||
}
|
||||
|
||||
@BindingAdapter("data")
|
||||
@Suppress("UNCHECKED_CAST")
|
||||
fun <T> setRecyclerViewData(recyclerView: ViewPager2, items: List<T>?) {
|
||||
if (recyclerView.adapter is ListAdapter<*, *>) {
|
||||
(recyclerView.adapter as ListAdapter<T, *>).submitList(items)
|
||||
@@ -325,10 +327,10 @@ fun distance(meters: Number?): String? {
|
||||
}
|
||||
}
|
||||
|
||||
@InverseBindingAdapter(attribute = "app:values")
|
||||
@InverseBindingAdapter(attribute = "values")
|
||||
fun getRangeSliderValue(slider: RangeSlider) = slider.values
|
||||
|
||||
@BindingAdapter("app:valuesAttrChanged")
|
||||
@BindingAdapter("valuesAttrChanged")
|
||||
fun setRangeSliderListeners(slider: RangeSlider, attrChange: InverseBindingListener) {
|
||||
slider.addOnChangeListener { _, _, _ ->
|
||||
attrChange.onChange()
|
||||
@@ -348,7 +350,7 @@ fun colorEnabled(ctx: Context, enabled: Boolean): Int {
|
||||
return color
|
||||
}
|
||||
|
||||
@BindingAdapter("app:tint")
|
||||
@BindingAdapter("tint")
|
||||
fun setImageTintList(view: ImageView, @ColorInt color: Int) {
|
||||
view.imageTintList = ColorStateList.valueOf(color)
|
||||
}
|
||||
|
||||
@@ -89,12 +89,12 @@ class RangeSliderPreference(context: Context, attrs: AttributeSet) : Preference(
|
||||
slider.valueTo = valueTo
|
||||
stepSize?.let { slider.stepSize = it }
|
||||
|
||||
slider.addOnChangeListener { slider, value, fromUser ->
|
||||
slider.addOnChangeListener { slider, _, fromUser ->
|
||||
if (fromUser && (updatesContinuously || !dragging)) {
|
||||
syncValueInternal(slider)
|
||||
}
|
||||
}
|
||||
slider.setOnTouchListener { v, event ->
|
||||
slider.setOnTouchListener { _, event ->
|
||||
when (event.actionMasked) {
|
||||
MotionEvent.ACTION_DOWN -> dragging = true
|
||||
MotionEvent.ACTION_UP -> dragging = false
|
||||
|
||||
@@ -16,7 +16,7 @@ import net.vonforst.evmap.model.FavoriteWithDetail
|
||||
import net.vonforst.evmap.storage.AppDatabase
|
||||
import net.vonforst.evmap.utils.distanceBetween
|
||||
|
||||
class FavoritesViewModel(application: Application, geApiKey: String) :
|
||||
class FavoritesViewModel(application: Application) :
|
||||
AndroidViewModel(application) {
|
||||
private var db = AppDatabase.getInstance(application)
|
||||
|
||||
@@ -69,7 +69,7 @@ class FavoritesViewModel(application: Application, geApiKey: String) :
|
||||
FavoritesListItem(
|
||||
favorite,
|
||||
totalAvailable(charger.id),
|
||||
charger.chargepoints.sumBy { it.count },
|
||||
charger.chargepoints.sumOf { it.count },
|
||||
location.value.let { loc ->
|
||||
if (loc == null) null else {
|
||||
distanceBetween(
|
||||
|
||||
@@ -92,4 +92,8 @@ class FilterViewModel(application: Application) : AndroidViewModel(application)
|
||||
prefs.filterStatus = FILTERS_DISABLED
|
||||
}
|
||||
}
|
||||
|
||||
suspend fun resetValues() {
|
||||
db.filterValueDao().deleteFilterValuesForProfile(FILTERS_CUSTOM, prefs.dataSource)
|
||||
}
|
||||
}
|
||||
@@ -7,6 +7,7 @@ import com.car2go.maps.AnyMap
|
||||
import com.car2go.maps.model.LatLng
|
||||
import com.car2go.maps.model.LatLngBounds
|
||||
import com.mahc.custombottomsheetbehavior.BottomSheetBehaviorGoogleMapsLike
|
||||
import com.squareup.moshi.JsonDataException
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.launch
|
||||
import kotlinx.coroutines.withContext
|
||||
@@ -265,6 +266,10 @@ class MapViewModel(application: Application, private val state: SavedStateHandle
|
||||
} catch (e: AvailabilityDetectorException) {
|
||||
emit(Resource.error(e.message, null))
|
||||
e.printStackTrace()
|
||||
} catch (e: JsonDataException) {
|
||||
// malformed JSON response from fronyx API
|
||||
emit(Resource.error(e.message, null))
|
||||
e.printStackTrace()
|
||||
}
|
||||
}
|
||||
} ?: liveData { emit(Resource.success(null)) }
|
||||
|
||||
@@ -13,7 +13,7 @@ import java.util.concurrent.atomic.AtomicBoolean
|
||||
@Suppress("UNCHECKED_CAST")
|
||||
inline fun <VM : ViewModel> viewModelFactory(crossinline f: () -> VM) =
|
||||
object : ViewModelProvider.Factory {
|
||||
override fun <T : ViewModel> create(aClass: Class<T>): T = f() as T
|
||||
override fun <T : ViewModel> create(modelClass: Class<T>): T = f() as T
|
||||
}
|
||||
|
||||
@Suppress("UNCHECKED_CAST")
|
||||
@@ -106,7 +106,8 @@ fun <T> throttleLatest(
|
||||
}
|
||||
}
|
||||
|
||||
public suspend fun <T> LiveData<T>.await(): T {
|
||||
@ExperimentalCoroutinesApi
|
||||
suspend fun <T> LiveData<T>.await(): T {
|
||||
return suspendCancellableCoroutine { continuation ->
|
||||
val observer = object : Observer<T> {
|
||||
override fun onChanged(value: T?) {
|
||||
@@ -124,7 +125,8 @@ public suspend fun <T> LiveData<T>.await(): T {
|
||||
}
|
||||
}
|
||||
|
||||
public suspend fun <T> LiveData<Resource<T>>.awaitFinished(): Resource<T> {
|
||||
@ExperimentalCoroutinesApi
|
||||
suspend fun <T> LiveData<Resource<T>>.awaitFinished(): Resource<T> {
|
||||
return suspendCancellableCoroutine { continuation ->
|
||||
val observer = object : Observer<Resource<T>> {
|
||||
override fun onChanged(value: Resource<T>) {
|
||||
|
||||
10
app/src/main/res/drawable/ic_filter_no.xml
Normal file
10
app/src/main/res/drawable/ic_filter_no.xml
Normal file
@@ -0,0 +1,10 @@
|
||||
<vector android:height="24dp"
|
||||
android:tint="?attr/colorControlNormal"
|
||||
android:viewportHeight="24"
|
||||
android:viewportWidth="24"
|
||||
android:width="24dp"
|
||||
xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<path
|
||||
android:fillColor="@android:color/white"
|
||||
android:pathData="M10.83,8H21V6H8.83L10.83,8zM15.83,13H18v-2h-4.17L15.83,13zM14,16.83V18h-4v-2h3.17l-3,-3H6v-2h2.17l-3,-3H3V6h0.17L1.39,4.22l1.41,-1.41l18.38,18.38l-1.41,1.41L14,16.83z" />
|
||||
</vector>
|
||||
10
app/src/main/res/drawable/ic_manage_filter_profiles.xml
Normal file
10
app/src/main/res/drawable/ic_manage_filter_profiles.xml
Normal file
@@ -0,0 +1,10 @@
|
||||
<vector android:height="24dp"
|
||||
android:tint="?attr/colorControlNormal"
|
||||
android:viewportHeight="24"
|
||||
android:viewportWidth="24"
|
||||
android:width="24dp"
|
||||
xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<path
|
||||
android:fillColor="@android:color/white"
|
||||
android:pathData="M3,10h11v2H3V10zM3,8h11V6H3V8zM3,16h7v-2H3V16zM18.01,12.87l0.71,-0.71c0.39,-0.39 1.02,-0.39 1.41,0l0.71,0.71c0.39,0.39 0.39,1.02 0,1.41l-0.71,0.71L18.01,12.87zM17.3,13.58l-5.3,5.3V21h2.12l5.3,-5.3L17.3,13.58z" />
|
||||
</vector>
|
||||
@@ -1,6 +1,12 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<menu xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto">
|
||||
<item
|
||||
android:id="@+id/menu_reset"
|
||||
android:title="@string/menu_reset"
|
||||
android:icon="@drawable/ic_filter_no"
|
||||
app:showAsAction="ifRoom" />
|
||||
|
||||
<item
|
||||
android:id="@+id/menu_save_profile"
|
||||
android:title="@string/menu_save_profile"
|
||||
|
||||
@@ -8,9 +8,11 @@
|
||||
<item
|
||||
android:id="@+id/menu_edit_filters"
|
||||
android:title="@string/menu_edit_filters"
|
||||
android:menuCategory="secondary" />
|
||||
android:menuCategory="secondary"
|
||||
android:icon="@drawable/ic_edit" />
|
||||
<item
|
||||
android:id="@+id/menu_manage_filter_profiles"
|
||||
android:title="@string/menu_manage_filter_profiles"
|
||||
android:menuCategory="secondary" />
|
||||
android:menuCategory="secondary"
|
||||
android:icon="@drawable/ic_manage_filter_profiles" />
|
||||
</menu>
|
||||
@@ -42,7 +42,7 @@
|
||||
<string name="settings_ui">Oberfläche</string>
|
||||
<string name="settings_map">Karte</string>
|
||||
<string name="copyright">Copyright</string>
|
||||
<string name="copyright_summary">©2020–2022 Johan von Forstner</string>
|
||||
<string name="copyright_summary">©2020–2023 Johan von Forstner</string>
|
||||
<string name="other">Sonstiges</string>
|
||||
<string name="privacy">Datenschutzerklärung</string>
|
||||
<string name="fav_add">Als Favorit speichern</string>
|
||||
@@ -143,6 +143,7 @@
|
||||
<string name="category_caravan_site">Wohnmobilstellplatz</string>
|
||||
<string name="menu_apply">Filter anwenden</string>
|
||||
<string name="menu_save_profile">Als Profil speichern</string>
|
||||
<string name="menu_reset">Filter zurücksetzen</string>
|
||||
<string name="no_filters">Keine Filter</string>
|
||||
<string name="filter_custom">Verändertes Filterprofil</string>
|
||||
<string name="filter_favorites">Favoriten</string>
|
||||
|
||||
@@ -154,7 +154,7 @@
|
||||
<string name="fault_report_date">Rapport d\'anomalie (dernière mise à jour : %s)</string>
|
||||
<string name="menu_report_new_charger">Nouveau chargeur</string>
|
||||
<string name="filter_connectors">Connecteurs</string>
|
||||
<string name="copyright_summary">©2020-2022 Johan von Forstner</string>
|
||||
<string name="copyright_summary">©2020–2023 Johan von Forstner</string>
|
||||
<string name="other">Autre</string>
|
||||
<string name="pref_navigate_use_maps_off">Le bouton de navigation lance l’application de cartes à l’emplacement du chargeur</string>
|
||||
<string name="settings_map">Carte</string>
|
||||
|
||||
@@ -93,7 +93,7 @@
|
||||
<string name="realtime_data_unavailable">Sanntidsstatus utilgjengelig</string>
|
||||
<string name="other">Andre</string>
|
||||
<string name="cost_detail"><b>Lading:</b> %1$s · <b>Parkering:</b> %2$s</string>
|
||||
<string name="copyright_summary">©2020–2022 Johan von Forstner</string>
|
||||
<string name="copyright_summary">©2020–2023 Johan von Forstner</string>
|
||||
<string name="pref_navigate_use_maps_on">Navigasjonsnkappen starter ruteveiledning på Google Maps</string>
|
||||
<string name="filter_free_parking">Kun ladere med gratis parkering</string>
|
||||
<string name="filter_min_power">Min. effekt</string>
|
||||
@@ -284,4 +284,16 @@
|
||||
<string name="pref_prediction_enabled">Vis bruksprognoser</string>
|
||||
<string name="pref_prediction_enabled_summary">for støttede ladere
|
||||
\n(foreløpig kun for likestrøm i Tyskland)</string>
|
||||
<string name="chargeprice_price_not_available">Pris ikke tilgjengelig</string>
|
||||
<string name="developer_mode_disabled">Utviklermodus avslått</string>
|
||||
<string name="gps">GPS</string>
|
||||
<string name="compass">Kompass</string>
|
||||
<string name="pref_applink_associate">Åpne støttede lenker</string>
|
||||
<string name="pref_applink_associate_summary">fra goingelectric.de og openchargemap.org</string>
|
||||
<string name="chargeprice_header_other_tariffs">Andre ladeabonnementer</string>
|
||||
<string name="disable_developer_mode">Skru av utviklermodus</string>
|
||||
<string name="chargeprice_header_my_tariffs">Mine ladeabonnementer</string>
|
||||
<string name="developer_options">Utvikleralternativer</string>
|
||||
<string name="data_source_switched_to">Datakilde byttet til %s</string>
|
||||
<string name="developer_mode_enabled">Utviklermodus påslått</string>
|
||||
</resources>
|
||||
299
app/src/main/res/values-nl/strings.xml
Normal file
299
app/src/main/res/values-nl/strings.xml
Normal file
@@ -0,0 +1,299 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<resources>
|
||||
<string name="data_source_goingelectric_desc">Ideaal in Duitstalige landen. Beschrijvingen in het Duits. Onderhouden door de gebruikersgemeenschap.</string>
|
||||
<string name="crash_report_text">EVMap is afgebroken. Stuur een crash rapport naar de ontwikkelaar.</string>
|
||||
<string name="pref_search_provider_info">Gegevens opzoeken is duur, vooral via Google Maps. Overweeg aub om een donatie te doen via “Over” -> “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>
|
||||
<string name="data_sources_description">Kies een gegevensbron voor laadstations. Dit kan later worden aangepast in de app-instellingen.</string>
|
||||
<string name="category_church">Kerk</string>
|
||||
<string name="welcome_2">Elk laadpunt heeft een kleur die het maximale laadvermogen weergeeft</string>
|
||||
<string name="donation_dialog_detail">EVMap is open source en gratis. Via GitHub kan iedereen bijdragen aan de app. Om de vaste kosten te helpen dragen, kan je overwegen een donatie te schenken aan de ontwikkelaar.</string>
|
||||
<string name="charging_barrierfree">Te gebruiken zonder registratie</string>
|
||||
<string name="verified_desc">Laadpunt is minstens 1x bevestigd als werkend door een lid van de %s gemeenschap</string>
|
||||
<string name="chargeprice_no_tariffs_found">Geen tarieven voor dit laadpunt op Chargeprice.app</string>
|
||||
<string name="category_hospital">Ziekenhuis</string>
|
||||
<string name="title_activity_maps">EVMap</string>
|
||||
<string name="connectors">Connectoren</string>
|
||||
<string name="no_browser_app_found">Installeer eerst een web browser</string>
|
||||
<string name="address">Adres</string>
|
||||
<string name="operator">Operator</string>
|
||||
<string name="network">Netwerk</string>
|
||||
<string name="open_247"><b>24/7 open</b></string>
|
||||
<string name="closed"><b>Gesloten</b></string>
|
||||
<string name="open_closesat"><b>Open</b> · Sluit om %s</string>
|
||||
<string name="closed_opensat"><b>Gesloten</b> · Opent om %s</string>
|
||||
<string name="closed_unfmt">Gesloten</string>
|
||||
<string name="holiday">Feestdag</string>
|
||||
<string name="cost">Kostprijs</string>
|
||||
<string name="cost_detail"><b>Laden:</b> %1$s · <b>Parkeren:</b> %2$s</string>
|
||||
<string name="cost_detail_charging"><b>%s laden</b></string>
|
||||
<string name="cost_detail_parking"><b>%s parkeren</b></string>
|
||||
<string name="charging_free">Gratis</string>
|
||||
<string name="parking_free">Gratis</string>
|
||||
<string name="amenities">Voorzieningen</string>
|
||||
<string name="general_info">Algemene informatie</string>
|
||||
<string name="realtime_data_unavailable">Real-time status niet beschikbaar</string>
|
||||
<string name="realtime_data_loading">Real-time status opvragen…</string>
|
||||
<string name="source">Bron: %s</string>
|
||||
<string name="search">Zoek</string>
|
||||
<string name="menu_map">Kaart</string>
|
||||
<string name="menu_favs">Favorieten</string>
|
||||
<string name="menu_filter">Filter</string>
|
||||
<string name="not_implemented">nog niet geïmplementeerd</string>
|
||||
<string name="about">Over</string>
|
||||
<string name="version">Versie</string>
|
||||
<string name="github_link_title">Broncode</string>
|
||||
<string name="oss_licenses">Licenties</string>
|
||||
<string name="settings">Instellingen</string>
|
||||
<string name="settings_ui">Interface</string>
|
||||
<string name="settings_map">Kaart</string>
|
||||
<string name="copyright">Copyright</string>
|
||||
<string name="copyright_summary">©2020–2023 Johan von Forstner</string>
|
||||
<string name="other">Andere</string>
|
||||
<string name="privacy">Privacy</string>
|
||||
<string name="pref_navigate_use_maps_off">Navigatieknop opent de kaart app met de locatie van het laadstation</string>
|
||||
<string name="coordinates">Coördinaten</string>
|
||||
<string name="share">Deel</string>
|
||||
<string name="filter_free">Allen gratis laadpunten</string>
|
||||
<string name="filter_min_power">Minimaal vermogen</string>
|
||||
<string name="filter_free_parking">Alleen laadpunten met gratis parking</string>
|
||||
<string name="filter_min_connectors">Minimaal aantal connecteren</string>
|
||||
<string name="filter_connectors">Connectoren</string>
|
||||
<string name="plug_type_3">Type 3A</string>
|
||||
<string name="plug_schuko">Schuko</string>
|
||||
<string name="plug_chademo">CHAdeMO</string>
|
||||
<string name="plug_cee_rot">CEE Red</string>
|
||||
<string name="plug_roadster_hpc">Tesla Roadster (2008) HPC</string>
|
||||
<string name="all">allemaal</string>
|
||||
<string name="none">geen</string>
|
||||
<string name="show_more">meer…</string>
|
||||
<string name="favorites_empty_state">Opgeslagen laadpunten verschijnen hier</string>
|
||||
<string name="donate">Doneer</string>
|
||||
<string name="donation_successful">Dank u ❤️</string>
|
||||
<string name="donation_failed">Er ging iets mis 😕</string>
|
||||
<string name="map_type_normal">Default</string>
|
||||
<string name="map_type_satellite">Satelliet</string>
|
||||
<string name="map_type_terrain">Terrein</string>
|
||||
<string name="map_traffic">Verkeer</string>
|
||||
<string name="faq">Veelgestelde vragen</string>
|
||||
<string name="menu_filters_active">Actieve filters</string>
|
||||
<string name="filters_activated">Filters geactiveerd</string>
|
||||
<string name="filters_deactivated">Filters gedeactiveerd</string>
|
||||
<string name="menu_edit_filters">Pas filters aan</string>
|
||||
<string name="menu_manage_filter_profiles">Beheer filterprofielen</string>
|
||||
<string name="go_to_chargeprice">Vergelijk prijzen</string>
|
||||
<string name="fault_report">Foutenrapport</string>
|
||||
<string name="fault_report_date">Foutenrapport (laatste update: %s)</string>
|
||||
<string name="filter_networks">Netwerken</string>
|
||||
<string name="filter_operators">Operatoren</string>
|
||||
<string name="filter_chargecards">Betaalmethoden</string>
|
||||
<string name="all_selected">Alle geselecteerd</string>
|
||||
<string name="number_selected">%d geselecteerd</string>
|
||||
<string name="edit">aanpassen</string>
|
||||
<string name="cancel">Afbreken</string>
|
||||
<string name="ok">OK</string>
|
||||
<string name="pref_language">App-taal</string>
|
||||
<string name="pref_darkmode">Donkere modus</string>
|
||||
<string name="connection_error">Laadstations konden niet worden geladen</string>
|
||||
<string name="location_error">Kon locatie niet bepalen. Controleer de instellingen</string>
|
||||
<string name="retry">Opnieuw</string>
|
||||
<string name="filter_open_247">24/7 beschikbaar</string>
|
||||
<string name="filter_barrierfree">Te gebruiken zonder registratie</string>
|
||||
<string name="filter_exclude_faults">Sluit laadstations uit met gerapporteerde fouten</string>
|
||||
<string name="categories">Categorieën</string>
|
||||
<string name="category_car_dealership">Autoverdeler</string>
|
||||
<string name="category_service_on_motorway">Herstelzone (op snelweg)</string>
|
||||
<string name="category_service_off_motorway">Herstelzone (niet langs de snelweg)</string>
|
||||
<string name="category_railway_station">Treinstation</string>
|
||||
<string name="category_shopping_mall">Winkelcentrum</string>
|
||||
<string name="category_holiday_home">Vakantiewoning</string>
|
||||
<string name="category_airport">Luchthaven</string>
|
||||
<string name="category_amusement_park">Attractiepark</string>
|
||||
<string name="category_hotel">Hotel</string>
|
||||
<string name="category_cinema">Bioscoop</string>
|
||||
<string name="category_museum">Museum</string>
|
||||
<string name="category_parking_multi">Parkeergarage</string>
|
||||
<string name="category_parking">Parking</string>
|
||||
<string name="category_private_charger">Privé-laadpunt</string>
|
||||
<string name="category_rest_area">Rustplaats</string>
|
||||
<string name="category_restaurant">Restaurant</string>
|
||||
<string name="category_swimming_pool">Zwembad</string>
|
||||
<string name="category_supermarket">Supermarkt</string>
|
||||
<string name="category_petrol_station">Benzinestation</string>
|
||||
<string name="category_parking_underground">Ondergrondse parking</string>
|
||||
<string name="category_zoo">Zoo</string>
|
||||
<string name="category_caravan_site">Staanplaats voor caravans</string>
|
||||
<string name="menu_apply">Pas filters toe</string>
|
||||
<string name="menu_save_profile">Bewaar als profiel</string>
|
||||
<string name="menu_reset">Reset filters</string>
|
||||
<string name="no_filters">Geen filters</string>
|
||||
<string name="filter_custom">Aangepaste filter</string>
|
||||
<string name="filter_favorites">Favorieten</string>
|
||||
<string name="reorder">herorden</string>
|
||||
<string name="delete">Verwijder</string>
|
||||
<string name="save_as_profile">Bewaar als profiel</string>
|
||||
<string name="save_profile_enter_name">Geef de naam van het filterprofiel:</string>
|
||||
<string name="filterprofiles_empty_state">Je hebt geen bewaarde filterprofielen</string>
|
||||
<string name="welcome_to_evmap">Welkom bij EVMap</string>
|
||||
<string name="welcome_1">Zoek EV laadpunten in je omgeving</string>
|
||||
<string name="welcome_2_title">Een kwestie van power</string>
|
||||
<string name="welcome_2_detail">Dit vind je ook in “Over” → “Veelgestelde vragen”</string>
|
||||
<string name="donation_dialog_title">Bedankt om EVMap te gebruiken</string>
|
||||
<string name="chargeprice_donation_dialog_title">Jij bent een echte koopjeszoeker!</string>
|
||||
<string name="chargeprice_donation_dialog_detail">Blijkbaar maak je dankbaar gebruik van de prijsvergelijkingen. Met een donatie kan je de kosten voor deze data helpen dragen.</string>
|
||||
<string name="deleted_filterprofile">“%s” verwijderd</string>
|
||||
<string name="undo">Ongedaan maken</string>
|
||||
<string name="rename">Hernoem</string>
|
||||
<plurals name="charge_cards_compatible_num">
|
||||
<item quantity="one">%d compatibele betaalmethode</item>
|
||||
<item quantity="other">%d compatibele betaalmethodes</item>
|
||||
</plurals>
|
||||
<string name="navigate">Navigeer naar hier</string>
|
||||
<string name="verified">geverifieerd</string>
|
||||
<string name="charge_price_format">%1$.2f %2$s</string>
|
||||
<string name="charge_price_average_format">⌀ %1$.2f %2$s/kWh</string>
|
||||
<string name="charge_price_kwh_format">%1$.2f %2$s/kWh</string>
|
||||
<string name="chargeprice_select_connector">Kies connector</string>
|
||||
<string name="chargeprice_provider_customer_tariff">Alleen voor eigen klanten</string>
|
||||
<string name="edit_on_goingelectric_info">Log aub in op GoingElectric.de als deze pagina leeg is</string>
|
||||
<string name="percent_format">%.0f%%</string>
|
||||
<string name="chargeprice_session_fee">kostprijs sessie</string>
|
||||
<string name="chargeprice_per_kwh">per kWh</string>
|
||||
<string name="chargeprice_per_minute">per min</string>
|
||||
<string name="chargeprice_blocking_fee">Kostprijs blokkeren >%s</string>
|
||||
<string name="powered_by_chargeprice">powered by Chargeprice</string>
|
||||
<string name="settings_chargeprice">Prijsvergelijking</string>
|
||||
<string name="pref_my_vehicle">Mijn voertuigen</string>
|
||||
<string name="pref_chargeprice_no_base_fee">Sluit plannen uit met maandelijkse kost</string>
|
||||
<string name="pref_chargeprice_show_provider_customer_tariffs">Neem plannen op die enkel voor klanten gelden</string>
|
||||
<string name="chargeprice_battery_range_from">Laden vanaf</string>
|
||||
<string name="chargeprice_battery_range_to">tot</string>
|
||||
<string name="chargeprice_vehicle">Voertuig</string>
|
||||
<string name="chargeprice_price_not_available">Prijs niet beschikbaar</string>
|
||||
<string name="pref_chargeprice_show_provider_customer_tariffs_summary">Sommige energieleveranciers bieden speciale plannen voor hun klanten</string>
|
||||
<string name="close">Sluiten</string>
|
||||
<string name="chargeprice_title">Prijzen</string>
|
||||
<string name="chargeprice_connection_error">Kon prijzen niet laden</string>
|
||||
<string name="pref_chargeprice_currency">Valuta</string>
|
||||
<string name="pref_my_tariffs">Mijn laadplannen</string>
|
||||
<plurals name="pref_my_tariffs_summary">
|
||||
<item quantity="one">(wordt aangeduid in de prijsvergelijking)</item>
|
||||
<item quantity="other">(worden aangeduid in de prijsvergelijking)</item>
|
||||
</plurals>
|
||||
<string name="chargeprice_all_tariffs_selected">alle plannen geselecteerd</string>
|
||||
<string name="settings_charger_data">Laadstations</string>
|
||||
<string name="pref_data_source">Databron</string>
|
||||
<plurals name="chargeprice_some_tariffs_selected">
|
||||
<item quantity="one">%d plan geselecteerd</item>
|
||||
<item quantity="other">%d plannen geselecteerd</item>
|
||||
</plurals>
|
||||
<string name="unknown_operator">Onbekende operator</string>
|
||||
<string name="data_source_goingelectric">GoingElectric.de</string>
|
||||
<string name="data_source_openchargemap">OpenChargeMap</string>
|
||||
<string name="chargeprice_base_fee">Abonnementskost: %1$.2f %2$s/maand</string>
|
||||
<string name="chargeprice_min_spend">Minimale kost: %1$.2f %2$s/maand</string>
|
||||
<string name="chargeprice_battery_range">Laden van %1$.0f%% tot %2$.0f%%</string>
|
||||
<string name="chargeprice_stats">(%1$.0f kWh, ca. %2$s, ⌀ %3$.0f kW)</string>
|
||||
<string name="next">volgende</string>
|
||||
<string name="get_started">Starten</string>
|
||||
<string name="got_it">Begrepen</string>
|
||||
<string name="lets_go">Laten we beginnen</string>
|
||||
<string name="crash_report_comment_prompt">Je kan hieronder commentaar geven:</string>
|
||||
<string name="powered_by_mapbox">powered by Mapbox</string>
|
||||
<string name="pref_search_provider">Zoekprovider</string>
|
||||
<string name="donate_desc">Ondersteun de EVMap ontwikkeling via een eenmalige donatie</string>
|
||||
<string name="github_sponsors_desc">Ondersteun EVMap op GitHub Spinsors</string>
|
||||
<string name="github_sponsors">GitHub Sponsors</string>
|
||||
<string name="unnamed_filter_profile">Naamloos filterprofiel</string>
|
||||
<string name="privacy_link">https://evmap.vonforst.net/en/privacy.html</string>
|
||||
<string name="faq_link">https://evmap.vonforst.net/en/faq.html</string>
|
||||
<string name="chargeprice_faq_link">https://evmap.vonforst.net/en/chargeprice_faq.html</string>
|
||||
<string name="required">verplicht</string>
|
||||
<string name="pref_search_delete_recent">Verwijder recente zoekresultaten</string>
|
||||
<string name="deleted_recent_search_results">Recente zoekresultaten zijn verwijderd</string>
|
||||
<string name="settings_data_sources">Gegevensbronnen</string>
|
||||
<string name="help">Help</string>
|
||||
<string name="settings_android_auto">Android Auto</string>
|
||||
<string name="pref_chargeprice_allow_unbalanced_load">Ongebalanceerd laden toelaten</string>
|
||||
<string name="pref_chargeprice_allow_unbalanced_load_summary">Eenfasig AC laden toelaten met meer dan 4.5 kW</string>
|
||||
<string name="pref_map_rotate_gestures_enabled">Kaartrotatie</string>
|
||||
<string name="pref_map_rotate_gestures_on">Gebruik twee vingers om de kaart te draaien</string>
|
||||
<string name="pref_map_rotate_gestures_off">Rotatie afzetten (noorden naar boven)</string>
|
||||
<string name="refresh_live_data">vernieuw de real-time status</string>
|
||||
<string name="autocomplete_connection_error">Suggesties konden niet worden geladen</string>
|
||||
<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>
|
||||
<string name="gps">GPS</string>
|
||||
<string name="pref_provider_osm_mapbox">OpenStreetMap (Mapbox)</string>
|
||||
<string name="about_contributors">Bijdragers</string>
|
||||
<string name="about_contributors_text">Dank aan iedereen die heeft bijgedragen aan de code en vertaling van EVMap:</string>
|
||||
<string name="utilization_prediction">Voorspeld verbruik</string>
|
||||
<string name="prediction_help">De voorspelling is gebaseerd op factoren zoals weekdag, tijdstip en gebruik in het verleden, zodat je zwaar bezette laders kan vermijden. Geen garantie, uiteraard.</string>
|
||||
<string name="prediction_time_colon">%s:</string>
|
||||
<string name="pref_prediction_enabled">Toon voorspeld gebruik</string>
|
||||
<string name="pref_prediction_enabled_summary">voor ondersteunde laders
|
||||
\n(momenteel enkel DC in Duitsland)</string>
|
||||
<string name="prediction_only">(enkel %s)</string>
|
||||
<string name="prediction_dc_plugs_only">DC aansluitingen</string>
|
||||
<string name="data_source_switched_to">Gegevensbron gewijzigd naar %s</string>
|
||||
<string name="pref_applink_associate">Open ondersteunde links</string>
|
||||
<string name="pref_applink_associate_summary">van going electric.de en openchargemap.org</string>
|
||||
<string name="chargeprice_header_my_tariffs">Mijn plannen</string>
|
||||
<string name="chargeprice_header_other_tariffs">Andere plannen</string>
|
||||
<string name="developer_mode_enabled">Ontwillekaarsmodus geactiveerd</string>
|
||||
<string name="developer_options">Ontwikkelaarsopties</string>
|
||||
<string name="disable_developer_mode">Ontwikkelaarsmodus uitzetten</string>
|
||||
<string name="developer_mode_disabled">Ontwikkelaarsmodus uitgezet</string>
|
||||
<plurals name="prediction_number_available">
|
||||
<item quantity="one">%1$d/%2$d beschkbaar</item>
|
||||
<item quantity="other">%1$d/%2$d beschikbaar</item>
|
||||
</plurals>
|
||||
<string name="app_name">EVMap</string>
|
||||
<string name="no_maps_app_found">Installeer eerst een navigatie-app</string>
|
||||
<string name="hours">Openingsuren</string>
|
||||
<string name="charging_paid">Betalend</string>
|
||||
<string name="parking_paid">Betalend</string>
|
||||
<string name="realtime_data_source">Real-time status bron (beta): %s</string>
|
||||
<string name="pref_navigate_use_maps">Onmiddellijke navigatie</string>
|
||||
<string name="fav_remove">Verwijder uit favorieten</string>
|
||||
<string name="pref_navigate_use_maps_on">Navigatieknop start routebegeleiding met Google Maps</string>
|
||||
<string name="fav_add">Bewaar als favoriet</string>
|
||||
<string name="goingelectric_forum">Forumthread op GoingElectric.de</string>
|
||||
<string name="plug_type_2">Type 2</string>
|
||||
<string name="plug_supercharger">Tesla Supercharger</string>
|
||||
<string name="plug_cee_blau">CEE Blue</string>
|
||||
<string name="plug_ccs">CCS</string>
|
||||
<string name="plug_type_1">Type 1</string>
|
||||
<string name="menu_report_new_charger">Nieuw laadpunt</string>
|
||||
<string name="show_less">minder…</string>
|
||||
<string name="map_type">Kaarttype</string>
|
||||
<string name="map_details">Kaartdetails</string>
|
||||
<string name="edit_at_datasource">aanpassen op %s</string>
|
||||
<string name="charge_cards">Betaalmethoden</string>
|
||||
<string name="pref_map_provider">Kaartaanbieder</string>
|
||||
<string name="twitter">Twitter</string>
|
||||
<string name="contact">Contact</string>
|
||||
<string name="and_n_others">en %d andere</string>
|
||||
<string name="category_camping">Kampeerplaats</string>
|
||||
<string name="category_public_authorities">Publieke instanties</string>
|
||||
</resources>
|
||||
@@ -6,6 +6,7 @@
|
||||
<item>@string/pref_language_de</item>
|
||||
<item>@string/pref_language_fr</item>
|
||||
<item>@string/pref_language_nb_rNO</item>
|
||||
<item>@string/pref_language_nl</item>
|
||||
</string-array>
|
||||
<string-array name="pref_language_values" translatable="false">
|
||||
<item>default</item>
|
||||
@@ -13,6 +14,7 @@
|
||||
<item>de</item>
|
||||
<item>fr</item>
|
||||
<item>nb-NO</item>
|
||||
<item>nl</item>
|
||||
</string-array>
|
||||
<string-array name="pref_darkmode_names">
|
||||
<item>@string/pref_darkmode_device_default</item>
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
<resources>
|
||||
<string name="shared_element_picture">picture</string>
|
||||
<string name="shared_element_chargeprice">chargeprice</string>
|
||||
<string name="github_link">https://github.com/johan12345/EVMap</string>
|
||||
<string name="github_link">https://github.com/ev-map/EVMap</string>
|
||||
<string name="twitter_handle">\@ev_map</string>
|
||||
<string name="twitter_url">https://twitter.com/ev_map</string>
|
||||
<string name="goingelectric_forum_url"><![CDATA[https://www.goingelectric.de/forum/viewtopic.php?f=5&t=56342]]></string>
|
||||
@@ -13,6 +13,7 @@
|
||||
<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="about_contributors_list">
|
||||
Danilo Bargen\n
|
||||
Altonss\n
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<resources>
|
||||
<string name="app_name">EVMap</string>
|
||||
<string name="title_activity_maps">EVMap</string>
|
||||
@@ -41,7 +42,7 @@
|
||||
<string name="settings_ui">Interface</string>
|
||||
<string name="settings_map">Map</string>
|
||||
<string name="copyright">Copyright</string>
|
||||
<string name="copyright_summary">©2020–2022 Johan von Forstner</string>
|
||||
<string name="copyright_summary">©2020–2023 Johan von Forstner</string>
|
||||
<string name="other">Other</string>
|
||||
<string name="privacy">Privacy</string>
|
||||
<string name="fav_add">Save as favorite</string>
|
||||
@@ -142,6 +143,7 @@
|
||||
<string name="category_caravan_site">Caravan site</string>
|
||||
<string name="menu_apply">Apply filters</string>
|
||||
<string name="menu_save_profile">Save as profile</string>
|
||||
<string name="menu_reset">Reset filter settings</string>
|
||||
<string name="no_filters">No filters</string>
|
||||
<string name="filter_custom">Modified filter</string>
|
||||
<string name="filter_favorites">Favorites</string>
|
||||
@@ -156,7 +158,7 @@
|
||||
<string name="welcome_2">Each charger\'s color corresponds to its max charging power</string>
|
||||
<string name="welcome_2_detail">This can also be seen in “About” → “Frequently Asked Questions”</string>
|
||||
<string name="donation_dialog_title">Thank you for using EVMap</string>
|
||||
<string name="donation_dialog_detail">EVMap is libre and free of charge. Code contributions on GitHub are much appreciated. To help cover the running costs for data access, please consider donating an amount of your choice to the developer.</string>
|
||||
<string name="donation_dialog_detail">EVMap is open source and free of charge. Code contributions on GitHub are much appreciated. To help cover the running costs for data access, please consider donating an amount of your choice to the developer.</string>
|
||||
<string name="chargeprice_donation_dialog_title">You\'re a real bargain hunter!</string>
|
||||
<string name="chargeprice_donation_dialog_detail">You make great use of the price comparison feature. Please help cover the costs for this data by supporting EVMap with a donation.</string>
|
||||
<string name="deleted_filterprofile">Deleted “%s”</string>
|
||||
@@ -180,7 +182,7 @@
|
||||
<string name="chargeprice_session_fee">session fee</string>
|
||||
<string name="chargeprice_per_kwh">per kWh</string>
|
||||
<string name="chargeprice_per_minute">per min</string>
|
||||
<string name="chargeprice_blocking_fee">Blocking fee >%s</string>
|
||||
<string name="chargeprice_blocking_fee">Blocking fee >%s</string>
|
||||
<string name="chargeprice_no_tariffs_found">No charging plans for this charger on Chargeprice.app</string>
|
||||
<string name="powered_by_chargeprice">powered by Chargeprice</string>
|
||||
<string name="chargeprice_base_fee">Base fee: %2$s%1$.2f/month</string>
|
||||
@@ -293,4 +295,4 @@
|
||||
<string name="developer_mode_disabled">Developer mode disabled</string>
|
||||
<string name="gps">GPS</string>
|
||||
<string name="compass">Compass</string>
|
||||
</resources>
|
||||
</resources>
|
||||
@@ -9,7 +9,7 @@
|
||||
(e.g. in the debug version). -->
|
||||
<intent
|
||||
android:action="android.intent.action.VIEW"
|
||||
android:targetPackage="${applicationId}"
|
||||
android:targetPackage="net.vonforst.evmap"
|
||||
android:targetClass="net.vonforst.evmap.MapsActivity">
|
||||
<extra
|
||||
android:name="favorites"
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
// Top-level build file where you can add configuration options common to all sub-projects/modules.
|
||||
|
||||
buildscript {
|
||||
ext.kotlin_version = '1.7.10'
|
||||
ext.kotlin_version = '1.7.21'
|
||||
ext.about_libs_version = '8.9.4'
|
||||
ext.nav_version = '2.5.3'
|
||||
repositories {
|
||||
@@ -10,11 +10,10 @@ buildscript {
|
||||
gradlePluginPortal()
|
||||
}
|
||||
dependencies {
|
||||
classpath 'com.android.tools.build:gradle:7.3.1'
|
||||
classpath 'com.android.tools.build:gradle:7.4.1'
|
||||
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
|
||||
classpath "com.mikepenz.aboutlibraries.plugin:aboutlibraries-plugin:$about_libs_version"
|
||||
classpath "androidx.navigation:navigation-safe-args-gradle-plugin:$nav_version"
|
||||
classpath "de.timfreiheit.resourceplaceholders:placeholders:0.4"
|
||||
|
||||
// NOTE: Do not place your application dependencies here; they belong
|
||||
// in the individual module build.gradle files
|
||||
|
||||
@@ -47,7 +47,7 @@ Below you find a list of all the services and how to obtain the API keys.
|
||||
Map providers
|
||||
-------------
|
||||
|
||||
The different Map SDKs are wrapped by our [fork](https://github.com/johan12345/AnyMaps) of the
|
||||
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.
|
||||
@@ -118,7 +118,7 @@ in German.
|
||||
- website (*Webseite*, optional)
|
||||
- phone number (*Telefonnummer*, optional)
|
||||
- name of the app (*Name der App*): EVMap
|
||||
- app website (*Webseite der App*): https://github.com/johan12345/EVMap
|
||||
- app website (*Webseite der App*): https://github.com/ev-map/EVMap
|
||||
- description (*kurze Beschreibung der App*): please explain that you would like to contribute to
|
||||
the development of EVMap and therefore need access to the GoingElectric.de API.
|
||||
- Referrer (*Herkunft*): leave this field blank!
|
||||
@@ -137,7 +137,7 @@ in German.
|
||||
1. [Sign up](https://openchargemap.org/site/loginprovider/register) for an account at OpenChargeMap
|
||||
2. Go to the [My Apps](https://openchargemap.org/site/profile/applications) page and click
|
||||
*Register an application*
|
||||
3. Enter the name of the app (EVMap) and website (https://github.com/johan12345/EVMap), and in the
|
||||
3. Enter the name of the app (EVMap) and website (https://github.com/ev-map/EVMap), and in the
|
||||
description field describe that you would like to contribute to the development of EVMap and
|
||||
therefore need access to the OpenChargeMap API. Do not tick the *List App in Public Showcase*
|
||||
box. Then, click *save*.
|
||||
@@ -160,7 +160,7 @@ Since February 2022, the Chargeprice API is no longer available for free to new
|
||||
you can use their
|
||||
[staging API](https://github.com/chargeprice/chargeprice-api-docs/blob/master/test_the_api.md)
|
||||
for free to test the Chargeprice features. This is already
|
||||
[configured](https://github.com/johan12345/EVMap/blob/master/app/src/debug/res/values/donottranslate.xml)
|
||||
[configured](https://github.com/ev-map/EVMap/blob/master/app/src/debug/res/values/donottranslate.xml)
|
||||
by default for the debug version of the app, so you can leave the `chargeprice_key` field in your
|
||||
new `app/src/main/res/values/apikeys.xml` file blank. Note that the staging API contains only a
|
||||
limited dataset, so it only outputs prices for certain charge point operators and payment plans (see
|
||||
|
||||
7
fastlane/metadata/android/de-DE/changelogs/158.txt
Normal file
7
fastlane/metadata/android/de-DE/changelogs/158.txt
Normal file
@@ -0,0 +1,7 @@
|
||||
Verbesserungen:
|
||||
- Neuer Knopf zum Zurücksetzen der Filtereinstellungen
|
||||
- Filtermenü mit neuen Icons
|
||||
- Übersetzungen aktualisiert
|
||||
|
||||
Fehler behoben:
|
||||
- Abstürze behoben
|
||||
2
fastlane/metadata/android/de-DE/changelogs/160.txt
Normal file
2
fastlane/metadata/android/de-DE/changelogs/160.txt
Normal file
@@ -0,0 +1,2 @@
|
||||
Fehler behoben:
|
||||
- Abstürze behoben
|
||||
5
fastlane/metadata/android/de-DE/changelogs/162.txt
Normal file
5
fastlane/metadata/android/de-DE/changelogs/162.txt
Normal file
@@ -0,0 +1,5 @@
|
||||
Verbesserungen:
|
||||
- Neue Übersetzung: Niederländisch
|
||||
|
||||
Fehler behoben:
|
||||
- Abstürze behoben
|
||||
@@ -11,7 +11,7 @@ Funktionen:
|
||||
- Favoritenliste, auch mit Anzeige der Verfügbarkeit
|
||||
- Keine nervige Werbung
|
||||
|
||||
EVMap ist ein Open-Source-Projekt und unter https://github.com/johan12345/EVMap zu finden.
|
||||
EVMap ist ein Open-Source-Projekt und unter https://github.com/ev-map/EVMap zu finden.
|
||||
|
||||
Die App ist kein offizielles Angebot von GoingElectric.de oder Open Charge Map, sondern nutzt die öffentlichen APIs dieser Seiten.
|
||||
|
||||
|
||||
7
fastlane/metadata/android/en-US/changelogs/158.txt
Normal file
7
fastlane/metadata/android/en-US/changelogs/158.txt
Normal file
@@ -0,0 +1,7 @@
|
||||
Improvements:
|
||||
- New button to reset filter setting
|
||||
- Filter menu with new icons
|
||||
- Updated translations
|
||||
|
||||
Bugfixes:
|
||||
- Fixed crashes
|
||||
2
fastlane/metadata/android/en-US/changelogs/160.txt
Normal file
2
fastlane/metadata/android/en-US/changelogs/160.txt
Normal file
@@ -0,0 +1,2 @@
|
||||
Bugfixes:
|
||||
- Fixed crashes
|
||||
5
fastlane/metadata/android/en-US/changelogs/162.txt
Normal file
5
fastlane/metadata/android/en-US/changelogs/162.txt
Normal file
@@ -0,0 +1,5 @@
|
||||
Improvements:
|
||||
- New translation: Dutch
|
||||
|
||||
Bugfixes:
|
||||
- Fixed crashes
|
||||
@@ -11,7 +11,7 @@ Features:
|
||||
- Favorites list, also with availability information
|
||||
- No ads, fully open source
|
||||
|
||||
EVMap is an open source project and can be found at https://github.com/johan12345/EVMap.
|
||||
EVMap is an open source project and can be found at https://github.com/ev-map/EVMap.
|
||||
|
||||
This app is not an official product of GoingElectric.de or Open Charge Map, it only uses their public APIs.
|
||||
|
||||
|
||||
@@ -11,7 +11,7 @@ Caractéristiques :
|
||||
- Liste de favoris, avec également des informations sur la disponibilité
|
||||
- Pas de publicité, entièrement open source
|
||||
|
||||
EVMap est un projet open source et peut être trouvé sur https://github.com/johan12345/EVMap.
|
||||
EVMap est un projet open source et peut être trouvé sur https://github.com/ev-map/EVMap.
|
||||
|
||||
Cette application n'est pas un produit officiel de GoingElectric.de ou Open Charge Map, elle utilise uniquement leurs API publiques.
|
||||
|
||||
|
||||
@@ -11,7 +11,7 @@ Du finner info om ladestasjoner i hele verden og sanntidsinfo for mange av dem s
|
||||
- Favorittliste, som også har tilgjengelighetsinfo
|
||||
- Ingen reklame
|
||||
|
||||
Du finner kildekoden på https://github.com/johan12345/EVMap.
|
||||
Du finner kildekoden på https://github.com/ev-map/EVMap.
|
||||
|
||||
Dette kartet er ikke et offisielt program fra hverken GoingElectric.de eller Open Charge Map.
|
||||
Kun de offentlige API-ene derfra benyttes.
|
||||
|
||||
18
fastlane/metadata/android/nl-NL/full_description.txt
Normal file
18
fastlane/metadata/android/nl-NL/full_description.txt
Normal file
@@ -0,0 +1,18 @@
|
||||
Met EVMap vind je op een eenvoudige manier EV laders op je Android toestel. Het geeft mobiele toegang tot de door de community onderhouden databases van GoingElectric.de en Open Charge Map, die informatie bevatten over laadstations over de hele wereld. Voor heel wat laadpunten in Europa kan je de real-time status zien.
|
||||
|
||||
Kenmerken:
|
||||
- Material Design
|
||||
- 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)
|
||||
- Zoek naar locaties
|
||||
- Geavanceerde filtermogelijkheden, inclusief bewaarde filterprofielen
|
||||
- Lijst van favorieten, met statusinformatie
|
||||
- Geen advertenties, volledig open source
|
||||
|
||||
EVMap is een open source project en is te vinden op https://github.com/ev-map/EVMap.
|
||||
|
||||
Deze app is geen officieel product van GoingElectric.de of Open Charge Map; ze gebruikt enkel hun publieke APIs.
|
||||
|
||||
Een lijst van noodzakelijke permissies is hier te vinden: https://evmap.vonforst.net/en/permissions.html
|
||||
1
fastlane/metadata/android/nl-NL/short_description.txt
Normal file
1
fastlane/metadata/android/nl-NL/short_description.txt
Normal file
@@ -0,0 +1 @@
|
||||
Zoek EV laadstations
|
||||
1
fastlane/metadata/android/nl-NL/title.txt
Normal file
1
fastlane/metadata/android/nl-NL/title.txt
Normal file
@@ -0,0 +1 @@
|
||||
EVMap - EV laadpunten
|
||||
2
gradle/wrapper/gradle-wrapper.properties
vendored
2
gradle/wrapper/gradle-wrapper.properties
vendored
@@ -1,6 +1,6 @@
|
||||
#Sat Aug 06 15:33:46 CEST 2022
|
||||
distributionBase=GRADLE_USER_HOME
|
||||
distributionUrl=https\://services.gradle.org/distributions/gradle-7.4-bin.zip
|
||||
distributionUrl=https\://services.gradle.org/distributions/gradle-7.5-bin.zip
|
||||
distributionPath=wrapper/dists
|
||||
zipStorePath=wrapper/dists
|
||||
zipStoreBase=GRADLE_USER_HOME
|
||||
|
||||
Reference in New Issue
Block a user