mirror of
https://github.com/ev-map/EVMap.git
synced 2025-12-24 07:37:46 -05:00
Compare commits
16 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
87421e450a | ||
|
|
479917fad1 | ||
|
|
dfaf841160 | ||
|
|
c18ea5b15d | ||
|
|
62116473c8 | ||
|
|
bc8106bd81 | ||
|
|
7bd89b9ecb | ||
|
|
898b61945e | ||
|
|
38e022b547 | ||
|
|
b8c438503c | ||
|
|
2ca6a8e3e8 | ||
|
|
0ae201e363 | ||
|
|
9e0f535a13 | ||
|
|
d4a6789b00 | ||
|
|
d9415ed7a0 | ||
|
|
778d7293f4 |
3
.gitignore
vendored
3
.gitignore
vendored
@@ -10,4 +10,5 @@
|
||||
apikeys.xml
|
||||
/app/**/*.aab
|
||||
/app/**/*.apk
|
||||
/_img/connectors/*.ai
|
||||
/_img/connectors/*.ai
|
||||
api-7125266970515251116-798419-8e2dda660c80.json
|
||||
178
Gemfile.lock
Normal file
178
Gemfile.lock
Normal file
@@ -0,0 +1,178 @@
|
||||
GEM
|
||||
remote: https://rubygems.org/
|
||||
specs:
|
||||
CFPropertyList (3.0.2)
|
||||
addressable (2.7.0)
|
||||
public_suffix (>= 2.0.2, < 5.0)
|
||||
atomos (0.1.3)
|
||||
aws-eventstream (1.1.0)
|
||||
aws-partitions (1.354.0)
|
||||
aws-sdk-core (3.104.3)
|
||||
aws-eventstream (~> 1, >= 1.0.2)
|
||||
aws-partitions (~> 1, >= 1.239.0)
|
||||
aws-sigv4 (~> 1.1)
|
||||
jmespath (~> 1.0)
|
||||
aws-sdk-kms (1.36.0)
|
||||
aws-sdk-core (~> 3, >= 3.99.0)
|
||||
aws-sigv4 (~> 1.1)
|
||||
aws-sdk-s3 (1.78.0)
|
||||
aws-sdk-core (~> 3, >= 3.104.3)
|
||||
aws-sdk-kms (~> 1)
|
||||
aws-sigv4 (~> 1.1)
|
||||
aws-sigv4 (1.2.1)
|
||||
aws-eventstream (~> 1, >= 1.0.2)
|
||||
babosa (1.0.3)
|
||||
claide (1.0.3)
|
||||
colored (1.2)
|
||||
colored2 (3.1.2)
|
||||
commander-fastlane (4.4.6)
|
||||
highline (~> 1.7.2)
|
||||
declarative (0.0.20)
|
||||
declarative-option (0.1.0)
|
||||
digest-crc (0.6.1)
|
||||
rake (~> 13.0)
|
||||
domain_name (0.5.20190701)
|
||||
unf (>= 0.0.5, < 1.0.0)
|
||||
dotenv (2.7.6)
|
||||
emoji_regex (3.0.0)
|
||||
excon (0.76.0)
|
||||
faraday (1.0.1)
|
||||
multipart-post (>= 1.2, < 3)
|
||||
faraday-cookie_jar (0.0.6)
|
||||
faraday (>= 0.7.4)
|
||||
http-cookie (~> 1.0.0)
|
||||
faraday_middleware (1.0.0)
|
||||
faraday (~> 1.0)
|
||||
fastimage (2.2.0)
|
||||
fastlane (2.156.1)
|
||||
CFPropertyList (>= 2.3, < 4.0.0)
|
||||
addressable (>= 2.3, < 3.0.0)
|
||||
aws-sdk-s3 (~> 1.0)
|
||||
babosa (>= 1.0.3, < 2.0.0)
|
||||
bundler (>= 1.12.0, < 3.0.0)
|
||||
colored
|
||||
commander-fastlane (>= 4.4.6, < 5.0.0)
|
||||
dotenv (>= 2.1.1, < 3.0.0)
|
||||
emoji_regex (>= 0.1, < 4.0)
|
||||
excon (>= 0.71.0, < 1.0.0)
|
||||
faraday (~> 1.0)
|
||||
faraday-cookie_jar (~> 0.0.6)
|
||||
faraday_middleware (~> 1.0)
|
||||
fastimage (>= 2.1.0, < 3.0.0)
|
||||
gh_inspector (>= 1.1.2, < 2.0.0)
|
||||
google-api-client (>= 0.37.0, < 0.39.0)
|
||||
google-cloud-storage (>= 1.15.0, < 2.0.0)
|
||||
highline (>= 1.7.2, < 2.0.0)
|
||||
json (< 3.0.0)
|
||||
jwt (>= 2.1.0, < 3)
|
||||
mini_magick (>= 4.9.4, < 5.0.0)
|
||||
multipart-post (~> 2.0.0)
|
||||
plist (>= 3.1.0, < 4.0.0)
|
||||
rubyzip (>= 2.0.0, < 3.0.0)
|
||||
security (= 0.1.3)
|
||||
simctl (~> 1.6.3)
|
||||
slack-notifier (>= 2.0.0, < 3.0.0)
|
||||
terminal-notifier (>= 2.0.0, < 3.0.0)
|
||||
terminal-table (>= 1.4.5, < 2.0.0)
|
||||
tty-screen (>= 0.6.3, < 1.0.0)
|
||||
tty-spinner (>= 0.8.0, < 1.0.0)
|
||||
word_wrap (~> 1.0.0)
|
||||
xcodeproj (>= 1.13.0, < 2.0.0)
|
||||
xcpretty (~> 0.3.0)
|
||||
xcpretty-travis-formatter (>= 0.0.3)
|
||||
gh_inspector (1.1.3)
|
||||
google-api-client (0.38.0)
|
||||
addressable (~> 2.5, >= 2.5.1)
|
||||
googleauth (~> 0.9)
|
||||
httpclient (>= 2.8.1, < 3.0)
|
||||
mini_mime (~> 1.0)
|
||||
representable (~> 3.0)
|
||||
retriable (>= 2.0, < 4.0)
|
||||
signet (~> 0.12)
|
||||
google-cloud-core (1.5.0)
|
||||
google-cloud-env (~> 1.0)
|
||||
google-cloud-errors (~> 1.0)
|
||||
google-cloud-env (1.3.3)
|
||||
faraday (>= 0.17.3, < 2.0)
|
||||
google-cloud-errors (1.0.1)
|
||||
google-cloud-storage (1.27.0)
|
||||
addressable (~> 2.5)
|
||||
digest-crc (~> 0.4)
|
||||
google-api-client (~> 0.33)
|
||||
google-cloud-core (~> 1.2)
|
||||
googleauth (~> 0.9)
|
||||
mini_mime (~> 1.0)
|
||||
googleauth (0.13.1)
|
||||
faraday (>= 0.17.3, < 2.0)
|
||||
jwt (>= 1.4, < 3.0)
|
||||
memoist (~> 0.16)
|
||||
multi_json (~> 1.11)
|
||||
os (>= 0.9, < 2.0)
|
||||
signet (~> 0.14)
|
||||
highline (1.7.10)
|
||||
http-cookie (1.0.3)
|
||||
domain_name (~> 0.5)
|
||||
httpclient (2.8.3)
|
||||
jmespath (1.4.0)
|
||||
json (2.3.1)
|
||||
jwt (2.2.1)
|
||||
memoist (0.16.2)
|
||||
mini_magick (4.10.1)
|
||||
mini_mime (1.0.2)
|
||||
multi_json (1.15.0)
|
||||
multipart-post (2.0.0)
|
||||
nanaimo (0.3.0)
|
||||
naturally (2.2.0)
|
||||
os (1.1.1)
|
||||
plist (3.5.0)
|
||||
public_suffix (4.0.5)
|
||||
rake (13.0.1)
|
||||
representable (3.0.4)
|
||||
declarative (< 0.1.0)
|
||||
declarative-option (< 0.2.0)
|
||||
uber (< 0.2.0)
|
||||
retriable (3.1.2)
|
||||
rouge (2.0.7)
|
||||
rubyzip (2.3.0)
|
||||
security (0.1.3)
|
||||
signet (0.14.0)
|
||||
addressable (~> 2.3)
|
||||
faraday (>= 0.17.3, < 2.0)
|
||||
jwt (>= 1.5, < 3.0)
|
||||
multi_json (~> 1.10)
|
||||
simctl (1.6.8)
|
||||
CFPropertyList
|
||||
naturally
|
||||
slack-notifier (2.3.2)
|
||||
terminal-notifier (2.0.0)
|
||||
terminal-table (1.8.0)
|
||||
unicode-display_width (~> 1.1, >= 1.1.1)
|
||||
tty-cursor (0.7.1)
|
||||
tty-screen (0.8.1)
|
||||
tty-spinner (0.9.3)
|
||||
tty-cursor (~> 0.7)
|
||||
uber (0.1.0)
|
||||
unf (0.1.4)
|
||||
unf_ext
|
||||
unf_ext (0.0.7.7-x64-mingw32)
|
||||
unicode-display_width (1.7.0)
|
||||
word_wrap (1.0.0)
|
||||
xcodeproj (1.18.0)
|
||||
CFPropertyList (>= 2.3.3, < 4.0)
|
||||
atomos (~> 0.1.3)
|
||||
claide (>= 1.0.2, < 2.0)
|
||||
colored2 (~> 3.1)
|
||||
nanaimo (~> 0.3.0)
|
||||
xcpretty (0.3.0)
|
||||
rouge (~> 2.0.7)
|
||||
xcpretty-travis-formatter (1.0.0)
|
||||
xcpretty (~> 0.2, >= 0.0.7)
|
||||
|
||||
PLATFORMS
|
||||
x64-mingw32
|
||||
|
||||
DEPENDENCIES
|
||||
fastlane
|
||||
|
||||
BUNDLED WITH
|
||||
2.1.2
|
||||
27
_img/map_marker_charging_multiple.svg
Normal file
27
_img/map_marker_charging_multiple.svg
Normal file
@@ -0,0 +1,27 @@
|
||||
<?xml version="1.0" encoding="utf-8"?><!-- Generator: Adobe Illustrator 23.0.1, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
|
||||
<svg version="1.1" id="Ebene_1" xmlns="http://www.w3.org/2000/svg" x="0px" y="0px"
|
||||
viewBox="0 0 233.8 368.4" style="enable-background:new 0 0 233.8 368.4;" xml:space="preserve">
|
||||
<style type="text/css">
|
||||
.st0{fill:#FFFFFF;}
|
||||
.st1{fill:#B5B5B5;}
|
||||
.st2{fill:#808080;}
|
||||
</style>
|
||||
<g>
|
||||
<g>
|
||||
<g>
|
||||
<path class="st0" d="M109.8,0h13.6c33.9,1.9,67.1,18.5,87.7,45.8c13.5,17.2,21,38.6,22.7,60.3v8.1c-0.8,42.1-27.7,76.6-51,109.4
|
||||
c-26.2,37-50.4,77.3-57.1,122.9c-1.8,7.7,0.4,18.5-8.9,22c-2.2-1.7-4.7-3.1-6.2-5.4c-2.7-25.5-9.1-50.7-20-73.9
|
||||
c-12.3-27.1-29.5-51.6-47-75.6C33,199,23,184.2,14.7,168.3c-13-23.8-17.9-51.9-12.5-78.6C6.6,68.6,17.6,49.1,32.8,34
|
||||
C53.3,14,81.1,1.8,109.8,0z" />
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
<g>
|
||||
<polygon class="st1"
|
||||
points="143.2,109.4 123.5,143.2 123.5,181.3 166.9,106.9 144.7,106.9 " />
|
||||
<path class="st1"
|
||||
d="M122.2,101.9h16.7h5.7l22.3-44.6c0,0-10.2,0-22.4,0l-1.1,2.2L122.2,101.9z" />
|
||||
<path class="st2" d="M138.9,57.3c-9.7,0-19.8,0-26.4,0c-2.5,0-5.1,0-7.6,0c-8.2,0-16.1,0-21.4,0c-4.1,0-6.6,0-6.6,0v68.2h18.6v55.8
|
||||
l43.4-74.4h-24.8L138.9,57.3z" />
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 1.2 KiB |
@@ -13,8 +13,8 @@ android {
|
||||
applicationId "net.vonforst.evmap"
|
||||
minSdkVersion 21
|
||||
targetSdkVersion 29
|
||||
versionCode 23
|
||||
versionName "0.3.2"
|
||||
versionCode 26
|
||||
versionName "0.3.4a"
|
||||
|
||||
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
|
||||
}
|
||||
@@ -78,7 +78,7 @@ android {
|
||||
variant.resValue "string", "goingelectric_key", goingelectricKey
|
||||
}
|
||||
def googleMapsKey = env.GOOGLE_MAPS_API_KEY ?: project.findProperty("GOOGLE_MAPS_API_KEY")
|
||||
if (googleMapsKey != null) {
|
||||
if (googleMapsKey != null && variant.flavorName == 'google') {
|
||||
variant.resValue "string", "google_maps_key", googleMapsKey
|
||||
}
|
||||
def mapboxKey = env.MAPBOX_API_KEY ?: project.findProperty("MAPBOX_API_KEY")
|
||||
@@ -116,7 +116,7 @@ dependencies {
|
||||
implementation 'com.mapzen.android:lost:3.0.2'
|
||||
|
||||
// AnyMaps
|
||||
def anyMapsVersion = 'e6e014dd11'
|
||||
def anyMapsVersion = '894f6d62ac'
|
||||
implementation "com.github.johan12345.AnyMaps:anymaps-base:$anyMapsVersion"
|
||||
googleImplementation "com.github.johan12345.AnyMaps:anymaps-google:$anyMapsVersion"
|
||||
implementation "com.github.johan12345.AnyMaps:anymaps-mapbox:$anyMapsVersion"
|
||||
@@ -136,7 +136,10 @@ dependencies {
|
||||
googleImplementation 'androidx.lifecycle:lifecycle-extensions:2.2.0'
|
||||
|
||||
// Mapbox places (autocomplete)
|
||||
implementation 'com.mapbox.mapboxsdk:mapbox-android-plugin-places-v9:0.12.0'
|
||||
implementation('com.mapbox.mapboxsdk:mapbox-android-plugin-places-v9:0.12.0') {
|
||||
exclude group: 'com.mapbox.mapboxsdk', module: 'mapbox-android-accounts'
|
||||
exclude group: 'com.mapbox.mapboxsdk', module: 'mapbox-android-telemetry'
|
||||
}
|
||||
|
||||
// navigation library
|
||||
def nav_version = "2.3.0"
|
||||
|
||||
10
app/src/google/AndroidManifest.xml
Normal file
10
app/src/google/AndroidManifest.xml
Normal file
@@ -0,0 +1,10 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
package="net.vonforst.evmap">
|
||||
|
||||
<application>
|
||||
<meta-data
|
||||
android:name="com.google.android.geo.API_KEY"
|
||||
android:value="@string/google_maps_key" />
|
||||
</application>
|
||||
</manifest>
|
||||
@@ -14,17 +14,6 @@
|
||||
android:supportsRtl="true"
|
||||
android:theme="@style/AppTheme">
|
||||
|
||||
<!--
|
||||
The API key for Google Maps-based APIs is defined as a string resource.
|
||||
(See the file "res/values/apikeys.xml").
|
||||
Note that the API key is linked to the encryption key used to sign the APK.
|
||||
You need a different API key for each encryption key, including the release key that is used to
|
||||
sign the APK for publishing.
|
||||
You can define the keys for the debug and release targets in src/debug/ and src/release/.
|
||||
-->
|
||||
<meta-data
|
||||
android:name="com.google.android.geo.API_KEY"
|
||||
android:value="@string/google_maps_key" />
|
||||
<meta-data
|
||||
android:name="com.mapbox.ACCESS_TOKEN"
|
||||
android:value="@string/mapbox_key" />
|
||||
|
||||
@@ -53,7 +53,8 @@ class MapsActivity : AppCompatActivity() {
|
||||
setOf(
|
||||
R.id.map,
|
||||
R.id.favs,
|
||||
R.id.about
|
||||
R.id.about,
|
||||
R.id.settings
|
||||
),
|
||||
findViewById<DrawerLayout>(R.id.drawer_layout)
|
||||
)
|
||||
|
||||
@@ -59,6 +59,14 @@ class AboutFragment : PreferenceFragmentCompat() {
|
||||
findNavController().navigate(R.id.action_about_to_donateFragment)
|
||||
true
|
||||
}
|
||||
"twitter" -> {
|
||||
(activity as? MapsActivity)?.openUrl(getString(R.string.twitter_url))
|
||||
true
|
||||
}
|
||||
"goingelectric" -> {
|
||||
(activity as? MapsActivity)?.openUrl(getString(R.string.goingelectric_forum_url))
|
||||
true
|
||||
}
|
||||
else -> super.onPreferenceTreeClick(preference)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -169,6 +169,18 @@ class MapFragment : Fragment(), OnMapReadyCallback, MapsActivity.FragmentCallbac
|
||||
binding.detailAppBar.toolbar.updateLayoutParams<ViewGroup.MarginLayoutParams> {
|
||||
topMargin = insets.systemWindowInsetTop
|
||||
}
|
||||
|
||||
// margin of layers button
|
||||
val density = resources.displayMetrics.density
|
||||
// status bar height + toolbar height + margin
|
||||
val margin =
|
||||
insets.systemWindowInsetTop + (48 * density).toInt() + (24 * density).toInt()
|
||||
binding.fabLayers.updateLayoutParams<ViewGroup.MarginLayoutParams> {
|
||||
topMargin = margin
|
||||
}
|
||||
binding.layersSheet.updateLayoutParams<ViewGroup.MarginLayoutParams> {
|
||||
topMargin = margin
|
||||
}
|
||||
insets
|
||||
}
|
||||
|
||||
@@ -421,7 +433,10 @@ class MapFragment : Fragment(), OnMapReadyCallback, MapsActivity.FragmentCallbac
|
||||
markers.forEach { (m, c) ->
|
||||
m.setIcon(
|
||||
chargerIconGenerator.getBitmapDescriptor(
|
||||
getMarkerTint(c, vm.filteredConnectors.value), fault = c.faultReport != null
|
||||
getMarkerTint(c, vm.filteredConnectors.value),
|
||||
highlight = false,
|
||||
fault = c.faultReport != null,
|
||||
multi = getMarkerMulti(c, vm.filteredConnectors.value)
|
||||
)
|
||||
)
|
||||
}
|
||||
@@ -434,7 +449,8 @@ class MapFragment : Fragment(), OnMapReadyCallback, MapsActivity.FragmentCallbac
|
||||
chargerIconGenerator.getBitmapDescriptor(
|
||||
getMarkerTint(charger, vm.filteredConnectors.value),
|
||||
highlight = true,
|
||||
fault = charger.faultReport != null
|
||||
fault = charger.faultReport != null,
|
||||
multi = getMarkerMulti(charger, vm.filteredConnectors.value)
|
||||
)
|
||||
)
|
||||
animator.animateMarkerBounce(marker)
|
||||
@@ -444,13 +460,31 @@ class MapFragment : Fragment(), OnMapReadyCallback, MapsActivity.FragmentCallbac
|
||||
if (m != marker) {
|
||||
m.setIcon(
|
||||
chargerIconGenerator.getBitmapDescriptor(
|
||||
getMarkerTint(c, vm.filteredConnectors.value), fault = c.faultReport != null
|
||||
getMarkerTint(c, vm.filteredConnectors.value),
|
||||
highlight = false,
|
||||
fault = c.faultReport != null,
|
||||
multi = getMarkerMulti(c, vm.filteredConnectors.value)
|
||||
)
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun getMarkerMulti(charger: ChargeLocation, filteredConnectors: Set<String>?): Boolean {
|
||||
var chargepoints = charger.chargepointsMerged
|
||||
.filter { filteredConnectors?.contains(it.type) ?: true }
|
||||
if (charger.maxPower(filteredConnectors) >= 43) {
|
||||
// fast charger -> only count fast chargers
|
||||
chargepoints = chargepoints.filter { it.power >= 43 }
|
||||
}
|
||||
val connectors = chargepoints.map { it.type }.distinct().toSet()
|
||||
|
||||
// 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 } }
|
||||
return chargepointsPerConnector.any { it > 1 }
|
||||
}
|
||||
|
||||
private fun updateFavoriteToggle() {
|
||||
val favs = vm.favorites.value ?: return
|
||||
val charger = vm.chargerSparse.value ?: return
|
||||
@@ -703,7 +737,8 @@ class MapFragment : Fragment(), OnMapReadyCallback, MapsActivity.FragmentCallbac
|
||||
chargerIconGenerator.getBitmapDescriptor(
|
||||
getMarkerTint(charger, vm.filteredConnectors.value),
|
||||
highlight = charger == vm.chargerSparse.value,
|
||||
fault = charger.faultReport != null
|
||||
fault = charger.faultReport != null,
|
||||
multi = getMarkerMulti(charger, vm.filteredConnectors.value)
|
||||
)
|
||||
)
|
||||
}
|
||||
@@ -720,7 +755,8 @@ class MapFragment : Fragment(), OnMapReadyCallback, MapsActivity.FragmentCallbac
|
||||
val tint = getMarkerTint(charger, vm.filteredConnectors.value)
|
||||
val highlight = charger == vm.chargerSparse.value
|
||||
val fault = charger.faultReport != null
|
||||
animator.animateMarkerDisappear(marker, tint, highlight, fault)
|
||||
val multi = getMarkerMulti(charger, vm.filteredConnectors.value)
|
||||
animator.animateMarkerDisappear(marker, tint, highlight, fault, multi)
|
||||
} else {
|
||||
animator.deleteMarker(marker)
|
||||
}
|
||||
@@ -734,6 +770,7 @@ class MapFragment : Fragment(), OnMapReadyCallback, MapsActivity.FragmentCallbac
|
||||
val tint = getMarkerTint(charger, vm.filteredConnectors.value)
|
||||
val highlight = charger == vm.chargerSparse.value
|
||||
val fault = charger.faultReport != null
|
||||
val multi = getMarkerMulti(charger, vm.filteredConnectors.value)
|
||||
val marker = map.addMarker(
|
||||
MarkerOptions()
|
||||
.position(LatLng(charger.coordinates.lat, charger.coordinates.lng))
|
||||
@@ -743,12 +780,13 @@ class MapFragment : Fragment(), OnMapReadyCallback, MapsActivity.FragmentCallbac
|
||||
0,
|
||||
255,
|
||||
highlight,
|
||||
fault
|
||||
fault,
|
||||
multi
|
||||
)
|
||||
)
|
||||
.anchor(0.5f, 1f)
|
||||
)
|
||||
animator.animateMarkerAppear(marker, tint, highlight, fault)
|
||||
animator.animateMarkerAppear(marker, tint, highlight, fault, multi)
|
||||
markers[marker] = charger
|
||||
}
|
||||
}
|
||||
|
||||
@@ -71,7 +71,7 @@ class MultiSelectDialog : AppCompatDialogFragment() {
|
||||
list.layoutManager = LinearLayoutManager(view.context)
|
||||
|
||||
items = data.entries.toList()
|
||||
.sortedBy { it.value }
|
||||
.sortedBy { it.value.toLowerCase(Locale.getDefault()) }
|
||||
.sortedByDescending { commonChoices?.contains(it.key) == true }
|
||||
.map { MultiSelectItem(it.key, it.value, it.key in selected) }
|
||||
adapter.submitList(items)
|
||||
|
||||
@@ -0,0 +1,50 @@
|
||||
package net.vonforst.evmap.navigation
|
||||
|
||||
import android.app.Activity
|
||||
import android.content.Context
|
||||
import android.net.Uri
|
||||
import android.os.Bundle
|
||||
import android.util.AttributeSet
|
||||
import androidx.browser.customtabs.CustomTabsIntent
|
||||
import androidx.core.content.ContextCompat
|
||||
import androidx.core.content.withStyledAttributes
|
||||
import androidx.navigation.NavDestination
|
||||
import androidx.navigation.NavOptions
|
||||
import androidx.navigation.Navigator
|
||||
import net.vonforst.evmap.R
|
||||
|
||||
@Navigator.Name("chrome")
|
||||
class ChromeCustomTabsNavigator(
|
||||
private val context: Context
|
||||
) : Navigator<ChromeCustomTabsNavigator.Destination>() {
|
||||
|
||||
override fun createDestination() =
|
||||
Destination(this)
|
||||
|
||||
override fun navigate(
|
||||
destination: Destination,
|
||||
args: Bundle?,
|
||||
navOptions: NavOptions?,
|
||||
navigatorExtras: Extras?
|
||||
): NavDestination? {
|
||||
val intent = CustomTabsIntent.Builder()
|
||||
.setToolbarColor(ContextCompat.getColor(context, R.color.colorPrimary))
|
||||
.build()
|
||||
intent.launchUrl(context, destination.url!!)
|
||||
return null // Do not add to the back stack, managed by Chrome Custom Tabs
|
||||
}
|
||||
|
||||
override fun popBackStack() = true // Managed by Chrome Custom Tabs
|
||||
|
||||
@NavDestination.ClassType(Activity::class)
|
||||
class Destination(navigator: Navigator<out NavDestination>) : NavDestination(navigator) {
|
||||
var url: Uri? = null
|
||||
|
||||
override fun onInflate(context: Context, attrs: AttributeSet) {
|
||||
super.onInflate(context, attrs)
|
||||
context.withStyledAttributes(attrs, R.styleable.ChromeCustomTabsNavigator, 0, 0) {
|
||||
url = Uri.parse(getString(R.styleable.ChromeCustomTabsNavigator_url))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,15 @@
|
||||
package net.vonforst.evmap.navigation
|
||||
|
||||
import androidx.navigation.NavController
|
||||
import androidx.navigation.fragment.NavHostFragment
|
||||
|
||||
class NavHostFragment : NavHostFragment() {
|
||||
override fun onCreateNavController(navController: NavController) {
|
||||
super.onCreateNavController(navController)
|
||||
navController.navigatorProvider.addNavigator(
|
||||
ChromeCustomTabsNavigator(
|
||||
requireContext()
|
||||
)
|
||||
)
|
||||
}
|
||||
}
|
||||
@@ -47,14 +47,17 @@ class ChargerIconGenerator(val context: Context, val factory: BitmapDescriptorFa
|
||||
val scale: Int,
|
||||
val alpha: Int,
|
||||
val highlight: Boolean,
|
||||
val fault: Boolean
|
||||
val fault: Boolean,
|
||||
val multi: Boolean
|
||||
)
|
||||
|
||||
val cacheSize = 420; // 420 items: 21 sizes, 5 colors, highlight on/off, fault on/off
|
||||
val cacheSize = 840; // 840 items: 21 sizes, 5 colors, highlight, fault, multi on/off
|
||||
val cache = LruCache<BitmapData, BitmapDescriptor>(cacheSize)
|
||||
val oversize = 1.4f // increase to add padding for fault icon or scale > 1
|
||||
val icon = R.drawable.ic_map_marker_charging
|
||||
val multiIcon = R.drawable.ic_map_marker_charging_multiple
|
||||
val highlightIcon = R.drawable.ic_map_marker_highlight
|
||||
val highlightIconMulti = R.drawable.ic_map_marker_charging_highlight_multiple
|
||||
val faultIcon = R.drawable.ic_map_marker_fault
|
||||
|
||||
init {
|
||||
@@ -72,9 +75,11 @@ class ChargerIconGenerator(val context: Context, val factory: BitmapDescriptorFa
|
||||
)
|
||||
for (fault in listOf(false, true)) {
|
||||
for (highlight in listOf(false, true)) {
|
||||
for (tint in tints) {
|
||||
for (scale in 0..20) {
|
||||
getBitmapDescriptor(tint, scale, 255, highlight, fault)
|
||||
for (multi in listOf(false, true)) {
|
||||
for (tint in tints) {
|
||||
for (scale in 0..20) {
|
||||
getBitmapDescriptor(tint, scale, 255, highlight, fault, multi)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -86,9 +91,10 @@ class ChargerIconGenerator(val context: Context, val factory: BitmapDescriptorFa
|
||||
scale: Int = 20,
|
||||
alpha: Int = 255,
|
||||
highlight: Boolean = false,
|
||||
fault: Boolean = false
|
||||
fault: Boolean = false,
|
||||
multi: Boolean = false
|
||||
): BitmapDescriptor? {
|
||||
val data = BitmapData(tint, scale, alpha, highlight, fault)
|
||||
val data = BitmapData(tint, scale, alpha, highlight, fault, multi)
|
||||
val cachedImg = cache[data]
|
||||
return if (cachedImg != null) {
|
||||
cachedImg
|
||||
@@ -101,13 +107,14 @@ class ChargerIconGenerator(val context: Context, val factory: BitmapDescriptorFa
|
||||
}
|
||||
|
||||
private fun generateBitmap(data: BitmapData): Bitmap {
|
||||
val vd: Drawable = context.getDrawable(icon)!!
|
||||
val icon = if (data.multi) multiIcon else icon
|
||||
val vd: Drawable = ContextCompat.getDrawable(context, icon)!!
|
||||
|
||||
DrawableCompat.setTint(vd, ContextCompat.getColor(context, data.tint));
|
||||
DrawableCompat.setTintMode(vd, PorterDuff.Mode.MULTIPLY);
|
||||
|
||||
val leftPadding = vd.intrinsicWidth * (oversize - 1) / 2
|
||||
val topPadding = vd.intrinsicWidth * (oversize - 1)
|
||||
val topPadding = vd.intrinsicHeight * (oversize - 1)
|
||||
vd.setBounds(
|
||||
leftPadding.toInt(), topPadding.toInt(),
|
||||
leftPadding.toInt() + vd.intrinsicWidth,
|
||||
@@ -132,7 +139,8 @@ class ChargerIconGenerator(val context: Context, val factory: BitmapDescriptorFa
|
||||
vd.draw(canvas)
|
||||
|
||||
if (data.highlight) {
|
||||
val highlightDrawable = context.getDrawable(highlightIcon)!!
|
||||
val hIcon = if (data.multi) highlightIconMulti else highlightIcon
|
||||
val highlightDrawable = ContextCompat.getDrawable(context, hIcon)!!
|
||||
highlightDrawable.setBounds(
|
||||
leftPadding.toInt(), topPadding.toInt(),
|
||||
leftPadding.toInt() + vd.intrinsicWidth,
|
||||
@@ -143,7 +151,7 @@ class ChargerIconGenerator(val context: Context, val factory: BitmapDescriptorFa
|
||||
}
|
||||
|
||||
if (data.fault) {
|
||||
val faultDrawable = context.getDrawable(faultIcon)!!
|
||||
val faultDrawable = ContextCompat.getDrawable(context, faultIcon)!!
|
||||
val faultSize = 0.75
|
||||
val faultShift = 0.25
|
||||
val base = vd.intrinsicWidth
|
||||
|
||||
@@ -28,7 +28,8 @@ class MarkerAnimator(val gen: ChargerIconGenerator) {
|
||||
marker: Marker,
|
||||
tint: Int,
|
||||
highlight: Boolean,
|
||||
fault: Boolean
|
||||
fault: Boolean,
|
||||
multi: Boolean
|
||||
) {
|
||||
animatingMarkers[marker]?.let {
|
||||
it.cancel()
|
||||
@@ -45,7 +46,8 @@ class MarkerAnimator(val gen: ChargerIconGenerator) {
|
||||
tint,
|
||||
scale = scale,
|
||||
highlight = highlight,
|
||||
fault = fault
|
||||
fault = fault,
|
||||
multi = multi
|
||||
)
|
||||
)
|
||||
}
|
||||
@@ -63,7 +65,8 @@ class MarkerAnimator(val gen: ChargerIconGenerator) {
|
||||
marker: Marker,
|
||||
tint: Int,
|
||||
highlight: Boolean,
|
||||
fault: Boolean
|
||||
fault: Boolean,
|
||||
multi: Boolean
|
||||
) {
|
||||
animatingMarkers[marker]?.let {
|
||||
it.cancel()
|
||||
@@ -80,7 +83,8 @@ class MarkerAnimator(val gen: ChargerIconGenerator) {
|
||||
tint,
|
||||
scale = scale,
|
||||
highlight = highlight,
|
||||
fault = fault
|
||||
fault = fault,
|
||||
multi = multi
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
@@ -4,32 +4,40 @@ import android.content.Context
|
||||
import android.content.ContextWrapper
|
||||
import android.content.res.Configuration
|
||||
import android.os.Build
|
||||
import androidx.core.os.ConfigurationCompat
|
||||
import java.util.*
|
||||
|
||||
|
||||
class LocaleContextWrapper(base: Context?) : ContextWrapper(base) {
|
||||
companion object {
|
||||
fun wrap(context: Context, language: String): ContextWrapper {
|
||||
val config: Configuration = context.resources.configuration
|
||||
var sysLocale: Locale? = null
|
||||
sysLocale = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
|
||||
config.locales.get(0)
|
||||
} else {
|
||||
@Suppress("DEPRECATION")
|
||||
config.locale
|
||||
}
|
||||
val sysConfig: Configuration = context.applicationContext.resources.configuration
|
||||
val appConfig: Configuration = context.resources.configuration
|
||||
var ctx = context
|
||||
if (language != "" && language != "default" && sysLocale.language != language) {
|
||||
|
||||
|
||||
if (language == "" || language == "default") {
|
||||
// set default locale
|
||||
Locale.setDefault(ConfigurationCompat.getLocales(sysConfig)[0])
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
|
||||
appConfig.setLocales(sysConfig.locales)
|
||||
} else {
|
||||
@Suppress("DEPRECATION")
|
||||
appConfig.locale = sysConfig.locale
|
||||
}
|
||||
} else {
|
||||
// set selected locale
|
||||
val locale = Locale(language)
|
||||
Locale.setDefault(locale)
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
|
||||
config.setLocale(locale)
|
||||
appConfig.setLocale(locale)
|
||||
} else {
|
||||
@Suppress("DEPRECATION")
|
||||
config.locale = locale
|
||||
appConfig.locale = locale
|
||||
}
|
||||
ctx = context.createConfigurationContext(config)
|
||||
}
|
||||
|
||||
ctx = context.createConfigurationContext(appConfig)
|
||||
return LocaleContextWrapper(ctx)
|
||||
}
|
||||
}
|
||||
|
||||
10
app/src/main/res/drawable/ic_add.xml
Normal file
10
app/src/main/res/drawable/ic_add.xml
Normal file
@@ -0,0 +1,10 @@
|
||||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="24dp"
|
||||
android:height="24dp"
|
||||
android:viewportWidth="24"
|
||||
android:viewportHeight="24"
|
||||
android:tint="?attr/colorControlNormal">
|
||||
<path
|
||||
android:fillColor="@android:color/white"
|
||||
android:pathData="M19,13h-6v6h-2v-6H5v-2h6V5h2v6h6v2z" />
|
||||
</vector>
|
||||
@@ -0,0 +1,17 @@
|
||||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="28dp"
|
||||
android:height="44.11976dp"
|
||||
android:viewportWidth="233.8"
|
||||
android:viewportHeight="368.4">
|
||||
<path
|
||||
android:fillColor="#FFFFFF"
|
||||
android:fillAlpha="0.8"
|
||||
android:pathData="M143.2,109.4l-19.7,33.8l0,38.1l43.4,-74.4l-22.2,0z" />
|
||||
<path
|
||||
android:fillColor="#FFFFFF"
|
||||
android:fillAlpha="0.8"
|
||||
android:pathData="M122.2,101.9h16.7h5.7l22.3,-44.6c0,0 -10.2,0 -22.4,0l-1.1,2.2L122.2,101.9z" />
|
||||
<path
|
||||
android:fillColor="#FFFFFF"
|
||||
android:pathData="M138.9,57.3c-9.7,0 -19.8,0 -26.4,0c-2.5,0 -5.1,0 -7.6,0c-8.2,0 -16.1,0 -21.4,0c-4.1,0 -6.6,0 -6.6,0v68.2h18.6v55.8l43.4,-74.4h-24.8L138.9,57.3z" />
|
||||
</vector>
|
||||
@@ -0,0 +1,18 @@
|
||||
<vector android:height="44.11976dp"
|
||||
android:viewportHeight="368.4"
|
||||
android:viewportWidth="233.8"
|
||||
android:width="28dp"
|
||||
xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<path
|
||||
android:fillColor="#FFFFFF"
|
||||
android:pathData="M109.8,0h13.6c33.9,1.9 67.1,18.5 87.7,45.8c13.5,17.2 21,38.6 22.7,60.3v8.1c-0.8,42.1 -27.7,76.6 -51,109.4c-26.2,37 -50.4,77.3 -57.1,122.9c-1.8,7.7 0.4,18.5 -8.9,22c-2.2,-1.7 -4.7,-3.1 -6.2,-5.4c-2.7,-25.5 -9.1,-50.7 -20,-73.9c-12.3,-27.1 -29.5,-51.6 -47,-75.6C33,199 23,184.2 14.7,168.3c-13,-23.8 -17.9,-51.9 -12.5,-78.6C6.6,68.6 17.6,49.1 32.8,34C53.3,14 81.1,1.8 109.8,0z" />
|
||||
<path
|
||||
android:fillColor="#B5B5B5"
|
||||
android:pathData="M143.2,109.4l-19.7,33.8l0,38.1l43.4,-74.4l-22.2,0z" />
|
||||
<path
|
||||
android:fillColor="#B5B5B5"
|
||||
android:pathData="M122.2,101.9h16.7h5.7l22.3,-44.6c0,0 -10.2,0 -22.4,0l-1.1,2.2L122.2,101.9z" />
|
||||
<path
|
||||
android:fillColor="#808080"
|
||||
android:pathData="M138.9,57.3c-9.7,0 -19.8,0 -26.4,0c-2.5,0 -5.1,0 -7.6,0c-8.2,0 -16.1,0 -21.4,0c-4.1,0 -6.6,0 -6.6,0v68.2h18.6v55.8l43.4,-74.4h-24.8L138.9,57.3z" />
|
||||
</vector>
|
||||
@@ -7,7 +7,7 @@
|
||||
|
||||
<fragment
|
||||
android:id="@+id/nav_host_fragment"
|
||||
android:name="androidx.navigation.fragment.NavHostFragment"
|
||||
android:name="net.vonforst.evmap.navigation.NavHostFragment"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_width="match_parent"
|
||||
android:fitsSystemWindows="true"
|
||||
|
||||
@@ -139,6 +139,8 @@
|
||||
android:layout_marginTop="2dp"
|
||||
android:text="@{charger.data.amenities}"
|
||||
android:textAppearance="@style/TextAppearance.MaterialComponents.Body2"
|
||||
android:autoLink="web"
|
||||
android:linksClickable="true"
|
||||
app:goneUnless="@{charger.data.amenities != null}"
|
||||
app:layout_constraintEnd_toStartOf="@+id/guideline2"
|
||||
app:layout_constraintHorizontal_bias="0.0"
|
||||
@@ -167,6 +169,8 @@
|
||||
android:layout_marginTop="2dp"
|
||||
android:text="@{charger.data.generalInformation}"
|
||||
android:textAppearance="@style/TextAppearance.MaterialComponents.Body2"
|
||||
android:autoLink="web"
|
||||
android:linksClickable="true"
|
||||
app:goneUnless="@{charger.data.generalInformation != null}"
|
||||
app:layout_constraintEnd_toStartOf="@+id/guideline2"
|
||||
app:layout_constraintHorizontal_bias="0.0"
|
||||
|
||||
@@ -158,8 +158,8 @@
|
||||
android:layout_gravity="top|end"
|
||||
android:layout_marginEnd="12dp"
|
||||
android:layout_marginTop="96dp"
|
||||
android:tint="?colorControlNormal"
|
||||
android:elevation="-1dp"
|
||||
app:tint="?android:colorControlNormal"
|
||||
app:backgroundTint="?android:colorBackground"
|
||||
app:borderWidth="0dp"
|
||||
app:fabSize="mini"
|
||||
|
||||
@@ -13,6 +13,14 @@
|
||||
android:icon="@drawable/ic_fav"
|
||||
android:title="@string/menu_favs" />
|
||||
</group>
|
||||
<group
|
||||
android:id="@+id/nav_group_links"
|
||||
android:checkableBehavior="single">
|
||||
<item
|
||||
android:id="@+id/report_new_charger"
|
||||
android:icon="@drawable/ic_add"
|
||||
android:title="@string/menu_report_new_charger" />
|
||||
</group>
|
||||
<group
|
||||
android:id="@+id/nav_group_settings"
|
||||
android:checkableBehavior="single">
|
||||
|
||||
@@ -63,4 +63,7 @@
|
||||
android:name="net.vonforst.evmap.fragment.DonateFragment"
|
||||
android:label="@string/donate"
|
||||
tools:layout="@layout/fragment_donate" />
|
||||
<chrome
|
||||
android:id="@+id/report_new_charger"
|
||||
app:url="@string/report_new_charger_url" />
|
||||
</navigation>
|
||||
@@ -103,6 +103,10 @@
|
||||
<string name="charge_cards">Ladetarife</string>
|
||||
<string name="and_n_others">und %d weitere</string>
|
||||
<string name="pref_map_provider">Kartenanbieter</string>
|
||||
<string name="twitter">Twitter</string>
|
||||
<string name="goingelectric_forum">Forenthread bei GoingElectric.de</string>
|
||||
<string name="contact">Kontakt</string>
|
||||
<string name="menu_report_new_charger">Ladesäule melden</string>
|
||||
<plurals name="charge_cards_compatible_num">
|
||||
<item quantity="one">%d kompatibler Ladetarif</item>
|
||||
<item quantity="other">%d kompatible Ladetarife</item>
|
||||
|
||||
6
app/src/main/res/values/attrs.xml
Normal file
6
app/src/main/res/values/attrs.xml
Normal file
@@ -0,0 +1,6 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<resources>
|
||||
<declare-styleable name="ChromeCustomTabsNavigator">
|
||||
<attr name="url" format="reference" />
|
||||
</declare-styleable>
|
||||
</resources>
|
||||
@@ -4,4 +4,8 @@
|
||||
<string name="github_link">https://github.com/johan12345/EVMap</string>
|
||||
<string name="privacy_link">https://evmap.vonforst.net/privacy.html</string>
|
||||
<string name="faq_link">https://evmap.vonforst.net/faq.html</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>
|
||||
<string name="report_new_charger_url">https://www.goingelectric.de/stromtankstellen/new/</string>
|
||||
</resources>
|
||||
@@ -102,6 +102,10 @@
|
||||
<string name="charge_cards">Payment methods</string>
|
||||
<string name="and_n_others">and %d others</string>
|
||||
<string name="pref_map_provider">Map provider</string>
|
||||
<string name="twitter">Twitter</string>
|
||||
<string name="goingelectric_forum">Forum thread at GoingElectric.de</string>
|
||||
<string name="contact">Contact</string>
|
||||
<string name="menu_report_new_charger">Report new charger</string>
|
||||
<plurals name="charge_cards_compatible_num">
|
||||
<item quantity="one">%d compatible payment method</item>
|
||||
<item quantity="other">%d compatible payment methods</item>
|
||||
|
||||
@@ -21,6 +21,18 @@
|
||||
<Preference
|
||||
android:key="donate"
|
||||
android:title="@string/donate" />
|
||||
</PreferenceCategory>
|
||||
|
||||
<PreferenceCategory android:title="@string/contact">
|
||||
|
||||
<Preference
|
||||
android:key="twitter"
|
||||
android:title="@string/twitter"
|
||||
android:summary="@string/twitter_handle" />
|
||||
|
||||
<Preference
|
||||
android:key="goingelectric"
|
||||
android:title="@string/goingelectric_forum" />
|
||||
|
||||
</PreferenceCategory>
|
||||
|
||||
|
||||
2
fastlane/Appfile
Normal file
2
fastlane/Appfile
Normal file
@@ -0,0 +1,2 @@
|
||||
json_key_file("api-7125266970515251116-798419-8e2dda660c80.json") # Path to the json secret file - Follow https://docs.fastlane.tools/actions/supply/#setup to get one
|
||||
package_name("net.vonforst.evmap") # e.g. com.krausefx.app
|
||||
38
fastlane/Fastfile
Normal file
38
fastlane/Fastfile
Normal file
@@ -0,0 +1,38 @@
|
||||
# This file contains the fastlane.tools configuration
|
||||
# You can find the documentation at https://docs.fastlane.tools
|
||||
#
|
||||
# For a list of all available actions, check out
|
||||
#
|
||||
# https://docs.fastlane.tools/actions
|
||||
#
|
||||
# For a list of all available plugins, check out
|
||||
#
|
||||
# https://docs.fastlane.tools/plugins/available-plugins
|
||||
#
|
||||
|
||||
# Uncomment the line if you want fastlane to automatically update itself
|
||||
# update_fastlane
|
||||
|
||||
default_platform(:android)
|
||||
|
||||
platform :android do
|
||||
desc "Runs all the tests"
|
||||
lane :test do
|
||||
gradle(task: "test")
|
||||
end
|
||||
|
||||
desc "Submit a new Beta Build to Crashlytics Beta"
|
||||
lane :beta do
|
||||
gradle(task: "clean assembleRelease")
|
||||
crashlytics
|
||||
|
||||
# sh "your_script.sh"
|
||||
# You can also use other beta testing services here
|
||||
end
|
||||
|
||||
desc "Deploy a new version to the Google Play"
|
||||
lane :deploy do
|
||||
gradle(task: "clean assembleRelease")
|
||||
upload_to_play_store
|
||||
end
|
||||
end
|
||||
4
fastlane/metadata/android/de-DE/changelogs/20.txt
Normal file
4
fastlane/metadata/android/de-DE/changelogs/20.txt
Normal file
@@ -0,0 +1,4 @@
|
||||
Verbesserungen:
|
||||
- Verändertes Layout für Filter nach Anschluss (bessere Stabilität)
|
||||
- Absturz bei fehlender Internetverbindung behoben
|
||||
- Fehlende Übersetzungen eingefügt
|
||||
6
fastlane/metadata/android/de-DE/changelogs/25.txt
Normal file
6
fastlane/metadata/android/de-DE/changelogs/25.txt
Normal file
@@ -0,0 +1,6 @@
|
||||
Verbesserungen:
|
||||
- Sortierung in Filterdialogen unabhängig von Groß- und Kleinschreibung
|
||||
- Vertikale Position der Marker auf der Karte korrigiert
|
||||
- Neues Icon für Ladestationen mit mehr als einem Anschluss (bei Schnelladern: mehr als ein schnelladefähiger Anschluss)
|
||||
- "Über EVMap": Links zu Twitter-Account @ev_map und Thread im GoingElectric-Forum hinzugefügt
|
||||
- Button "Ladesäule melden" im Hauptmenü hinzugefügt
|
||||
17
fastlane/metadata/android/de-DE/full_description.txt
Normal file
17
fastlane/metadata/android/de-DE/full_description.txt
Normal file
@@ -0,0 +1,17 @@
|
||||
Mit EVMap kannst du Stromtankstellen in deiner Nähe komfortabel über dein Android-Smartphone finden. Die Datenbank von GoingElectric.de wird als Datenquelle genutzt und bietet Community-gepflegte Informationen zu mehr als 100.000 Ladepunkten an über 40.000 Standorten in 48 Ländern (die meisten in Europa). Für viele Ladepunkte kann zusätzlich der aktuelle Status (verfügbar oder belegt) angezeigt werden.
|
||||
|
||||
Funktionen:
|
||||
- Zeitgemäßes Material Design
|
||||
- Anzeige der Stromtankstellen aus dem GoingElectric-Stromtankstellenverzeichnis
|
||||
- Echtzeit-Verfügbarkeitsanzeige für viele Ladesäulen
|
||||
- Direkte Links zu Chargeprice.app für einen Preisvergleich für die jeweilige Ladesäule
|
||||
- Markierung des aktuellen Standorts
|
||||
- Google Maps-Verkehrsdaten
|
||||
- Suche nach Orten
|
||||
- Erweiterte Filterfunktionen
|
||||
- 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.
|
||||
|
||||
Die App ist kein offizielles Angebot von GoingElectric.de, sondern nutzt die öffentliche API dieser Seite.
|
||||
BIN
fastlane/metadata/android/de-DE/images/featureGraphic.png
Normal file
BIN
fastlane/metadata/android/de-DE/images/featureGraphic.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 71 KiB |
BIN
fastlane/metadata/android/de-DE/images/icon.png
Normal file
BIN
fastlane/metadata/android/de-DE/images/icon.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 24 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 909 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 943 KiB |
1
fastlane/metadata/android/de-DE/short_description.txt
Normal file
1
fastlane/metadata/android/de-DE/short_description.txt
Normal file
@@ -0,0 +1 @@
|
||||
Finde Elektroauto-Ladestationen in deiner Nähe
|
||||
1
fastlane/metadata/android/de-DE/title.txt
Normal file
1
fastlane/metadata/android/de-DE/title.txt
Normal file
@@ -0,0 +1 @@
|
||||
EVMap - Elektroauto-Ladestationen
|
||||
0
fastlane/metadata/android/de-DE/video.txt
Normal file
0
fastlane/metadata/android/de-DE/video.txt
Normal file
4
fastlane/metadata/android/en-US/changelogs/20.txt
Normal file
4
fastlane/metadata/android/en-US/changelogs/20.txt
Normal file
@@ -0,0 +1,4 @@
|
||||
Improvements:
|
||||
- Different layout for filtering by connector (with better stability)
|
||||
- Crash fixed when internet is not available
|
||||
- Added missing German translations
|
||||
6
fastlane/metadata/android/en-US/changelogs/25.txt
Normal file
6
fastlane/metadata/android/en-US/changelogs/25.txt
Normal file
@@ -0,0 +1,6 @@
|
||||
Improvements:
|
||||
- Sorting of filter dialogs is case-insensitive
|
||||
- Vertical positions of map markers fixed
|
||||
- New icon for chargers with more than one connector (for fast chargers: more than one fast-charging connector)
|
||||
- "About EVMap": Added links to Twitter account @ev_map and GoingElectric.de forum thread
|
||||
- Added button "rerport new charger" in main menu
|
||||
2
fastlane/metadata/android/en-US/changelogs/26.txt
Normal file
2
fastlane/metadata/android/en-US/changelogs/26.txt
Normal file
@@ -0,0 +1,2 @@
|
||||
Crash fixed
|
||||
Fix wrong position of layers button on devices with camera cutout
|
||||
16
fastlane/metadata/android/en-US/full_description.txt
Normal file
16
fastlane/metadata/android/en-US/full_description.txt
Normal file
@@ -0,0 +1,16 @@
|
||||
Using EVMap, you can find electric vehicle chargers comfortably using your Android phone. It provides mobile access to the community-driven database from GoingElectric.de, containing more than 100,000 chargepoints at 40,000 locations in 48 countries (focusing on Europe). For many chargepoints, you can see real-time status information.
|
||||
|
||||
Features:
|
||||
- Material Design
|
||||
- Shows all charging stations from the community-maintained GoingElectric.de directory
|
||||
- Realtime availability information (beta)
|
||||
- Direct link to Chargeprice.app for comparing prices
|
||||
- Marker for current location
|
||||
- Search places
|
||||
- Favorites list, also with availability information
|
||||
- Advanced filtering options
|
||||
- No ads, fully open source
|
||||
|
||||
EVMap is an open source project and can be found at https://github.com/johan12345/EVMap.
|
||||
|
||||
This app is not an official product of GoingElectric.de, but only uses its public API.
|
||||
1
fastlane/metadata/android/en-US/short_description.txt
Normal file
1
fastlane/metadata/android/en-US/short_description.txt
Normal file
@@ -0,0 +1 @@
|
||||
Find electric vehicle charging stations
|
||||
1
fastlane/metadata/android/en-US/title.txt
Normal file
1
fastlane/metadata/android/en-US/title.txt
Normal file
@@ -0,0 +1 @@
|
||||
EVMap - Electric vehicle chargers
|
||||
0
fastlane/metadata/android/en-US/video.txt
Normal file
0
fastlane/metadata/android/en-US/video.txt
Normal file
Reference in New Issue
Block a user