From 7052ce3c3cb808668f5fcaef1849ca1a994deb33 Mon Sep 17 00:00:00 2001 From: Johan von Forstner Date: Sun, 9 Aug 2020 12:22:58 +0200 Subject: [PATCH] fixes for Google Maps and OSM variants --- app/build.gradle | 2 +- app/src/foss/java/net/vonforst/evmap/Inits.kt | 3 +- .../evmap/autocomplete/Autocomplete.kt | 4 +- .../google/java/net/vonforst/evmap/Inits.kt | 11 ++- .../vonforst/evmap/adapter/DonationAdapter.kt | 1 + .../evmap/autocomplete/Autocomplete.kt | 22 +++-- .../res/{ => layout}/fragment_donate.xml | 0 .../google/res/{ => layout}/item_donation.xml | 0 .../java/net/vonforst/evmap/MapsActivity.kt | 2 +- .../vonforst/evmap/fragment/MapFragment.kt | 81 ++++++++++++------- 10 files changed, 84 insertions(+), 42 deletions(-) rename app/src/google/res/{ => layout}/fragment_donate.xml (100%) rename app/src/google/res/{ => layout}/item_donation.xml (100%) diff --git a/app/build.gradle b/app/build.gradle index 51de986c..06bd9cbf 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -116,7 +116,7 @@ dependencies { implementation 'com.mapzen.android:lost:3.0.2' // AnyMaps - def anyMapsVersion = 'a8c270b4ea' + def anyMapsVersion = '57bec80da6' implementation "com.github.johan12345.AnyMaps:anymaps-base:$anyMapsVersion" googleImplementation "com.github.johan12345.AnyMaps:anymaps-google:$anyMapsVersion" fossImplementation "com.github.johan12345.AnyMaps:anymaps-mapbox:$anyMapsVersion" diff --git a/app/src/foss/java/net/vonforst/evmap/Inits.kt b/app/src/foss/java/net/vonforst/evmap/Inits.kt index 5d347be6..047f096d 100644 --- a/app/src/foss/java/net/vonforst/evmap/Inits.kt +++ b/app/src/foss/java/net/vonforst/evmap/Inits.kt @@ -1,11 +1,12 @@ package net.vonforst.evmap +import android.app.Activity import android.content.Context fun init(context: Context) { } -fun checkPlayServices(): Boolean { +fun checkPlayServices(activity: Activity): Boolean { return true } \ No newline at end of file diff --git a/app/src/foss/java/net/vonforst/evmap/autocomplete/Autocomplete.kt b/app/src/foss/java/net/vonforst/evmap/autocomplete/Autocomplete.kt index 80f86816..05b4befe 100644 --- a/app/src/foss/java/net/vonforst/evmap/autocomplete/Autocomplete.kt +++ b/app/src/foss/java/net/vonforst/evmap/autocomplete/Autocomplete.kt @@ -1,10 +1,10 @@ package net.vonforst.evmap.autocomplete -import android.content.Context +import android.app.Activity import android.content.Intent import net.vonforst.evmap.viewmodel.PlaceWithBounds -fun launchAutocomplete(context: Context) { +fun launchAutocomplete(activity: Activity) { // TODO: } diff --git a/app/src/google/java/net/vonforst/evmap/Inits.kt b/app/src/google/java/net/vonforst/evmap/Inits.kt index d676ca7b..2979179a 100644 --- a/app/src/google/java/net/vonforst/evmap/Inits.kt +++ b/app/src/google/java/net/vonforst/evmap/Inits.kt @@ -1,18 +1,23 @@ package net.vonforst.evmap +import android.app.Activity import android.content.Context +import android.util.Log +import com.google.android.gms.common.ConnectionResult +import com.google.android.gms.common.GoogleApiAvailability +import com.google.android.libraries.places.api.Places fun init(context: Context) { Places.initialize(context, context.getString(R.string.google_maps_key)); } -fun checkPlayServices(): Boolean { +fun checkPlayServices(activity: Activity): Boolean { val request = 9000 val apiAvailability = GoogleApiAvailability.getInstance() - val resultCode = apiAvailability.isGooglePlayServicesAvailable(this) + val resultCode = apiAvailability.isGooglePlayServicesAvailable(activity) if (resultCode != ConnectionResult.SUCCESS) { if (apiAvailability.isUserResolvableError(resultCode)) { - apiAvailability.getErrorDialog(this, resultCode, request).show() + apiAvailability.getErrorDialog(activity, resultCode, request).show() } else { Log.d("EVMap", "This device is not supported.") } diff --git a/app/src/google/java/net/vonforst/evmap/adapter/DonationAdapter.kt b/app/src/google/java/net/vonforst/evmap/adapter/DonationAdapter.kt index f2634d3f..8ddf9d30 100644 --- a/app/src/google/java/net/vonforst/evmap/adapter/DonationAdapter.kt +++ b/app/src/google/java/net/vonforst/evmap/adapter/DonationAdapter.kt @@ -1,5 +1,6 @@ package net.vonforst.evmap.adapter +import net.vonforst.evmap.R import net.vonforst.evmap.viewmodel.DonationItem class DonationAdapter() : DataBindingAdapter() { diff --git a/app/src/google/java/net/vonforst/evmap/autocomplete/Autocomplete.kt b/app/src/google/java/net/vonforst/evmap/autocomplete/Autocomplete.kt index 79002b70..93d91c04 100644 --- a/app/src/google/java/net/vonforst/evmap/autocomplete/Autocomplete.kt +++ b/app/src/google/java/net/vonforst/evmap/autocomplete/Autocomplete.kt @@ -1,22 +1,32 @@ package net.vonforst.evmap.autocomplete +import android.app.Activity import android.content.Context +import android.content.Intent +import android.view.inputmethod.InputMethodManager +import com.car2go.maps.google.adapter.AnyMapAdapter +import com.google.android.libraries.places.api.model.Place +import com.google.android.libraries.places.widget.Autocomplete +import com.google.android.libraries.places.widget.model.AutocompleteActivityMode +import net.vonforst.evmap.fragment.REQUEST_AUTOCOMPLETE import net.vonforst.evmap.viewmodel.PlaceWithBounds -fun launchAutocomplete(context: Context) { +fun launchAutocomplete(activity: Activity) { val fields = listOf(Place.Field.LAT_LNG, Place.Field.VIEWPORT) val intent: Intent = Autocomplete.IntentBuilder( AutocompleteActivityMode.OVERLAY, fields ) - .build(requireContext()) + .build(activity) .addFlags(Intent.FLAG_ACTIVITY_NO_ANIMATION) - startActivityForResult(intent, REQUEST_AUTOCOMPLETE) + activity.startActivityForResult(intent, REQUEST_AUTOCOMPLETE) // show keyboard val imm = - requireContext().getSystemService(Context.INPUT_METHOD_SERVICE) as InputMethodManager + activity.getSystemService(Context.INPUT_METHOD_SERVICE) as InputMethodManager imm.toggleSoftInput(0, 0) } -fun handleAutocompleteResult(intent: Intent): PlaceWithBounds? = - Autocomplete.getPlaceFromIntent(data!!) \ No newline at end of file +fun handleAutocompleteResult(intent: Intent): PlaceWithBounds? { + val place = Autocomplete.getPlaceFromIntent(intent) + return PlaceWithBounds(AnyMapAdapter.adapt(place.latLng), AnyMapAdapter.adapt(place.viewport)) +} \ No newline at end of file diff --git a/app/src/google/res/fragment_donate.xml b/app/src/google/res/layout/fragment_donate.xml similarity index 100% rename from app/src/google/res/fragment_donate.xml rename to app/src/google/res/layout/fragment_donate.xml diff --git a/app/src/google/res/item_donation.xml b/app/src/google/res/layout/item_donation.xml similarity index 100% rename from app/src/google/res/item_donation.xml rename to app/src/google/res/layout/item_donation.xml diff --git a/app/src/main/java/net/vonforst/evmap/MapsActivity.kt b/app/src/main/java/net/vonforst/evmap/MapsActivity.kt index bdb51edd..d50b2276 100644 --- a/app/src/main/java/net/vonforst/evmap/MapsActivity.kt +++ b/app/src/main/java/net/vonforst/evmap/MapsActivity.kt @@ -61,7 +61,7 @@ class MapsActivity : AppCompatActivity() { prefs = PreferenceDataSource(this) - checkPlayServices() + checkPlayServices(this) } fun navigateTo(charger: ChargeLocation) { diff --git a/app/src/main/java/net/vonforst/evmap/fragment/MapFragment.kt b/app/src/main/java/net/vonforst/evmap/fragment/MapFragment.kt index 2b9b673e..bc747904 100644 --- a/app/src/main/java/net/vonforst/evmap/fragment/MapFragment.kt +++ b/app/src/main/java/net/vonforst/evmap/fragment/MapFragment.kt @@ -1,6 +1,6 @@ package net.vonforst.evmap.fragment -import android.Manifest +import android.Manifest.permission.ACCESS_FINE_LOCATION import android.annotation.SuppressLint import android.app.Activity import android.content.Intent @@ -12,8 +12,10 @@ import android.os.Handler import android.view.* import android.widget.TextView import androidx.activity.OnBackPressedCallback +import androidx.annotation.RequiresPermission import androidx.appcompat.app.AlertDialog import androidx.appcompat.widget.PopupMenu +import androidx.core.app.ActivityCompat import androidx.core.app.SharedElementCallback import androidx.core.content.ContextCompat import androidx.core.view.updateLayoutParams @@ -34,7 +36,6 @@ import androidx.transition.TransitionManager import com.car2go.maps.AnyMap import com.car2go.maps.MapFragment import com.car2go.maps.OnMapReadyCallback -import com.car2go.maps.mapbox.MapsConfiguration import com.car2go.maps.model.LatLng import com.car2go.maps.model.Marker import com.car2go.maps.model.MarkerOptions @@ -71,7 +72,8 @@ const val ARG_CHARGER_ID = "chargerId" const val ARG_LAT = "lat" const val ARG_LON = "lon" -class MapFragment : Fragment(), OnMapReadyCallback, MapsActivity.FragmentCallback { +class MapFragment : Fragment(), OnMapReadyCallback, MapsActivity.FragmentCallback, + LostApiClient.ConnectionCallbacks { private lateinit var binding: FragmentMapBinding private val vm: MapViewModel by viewModels(factoryProducer = { viewModelFactory { @@ -117,7 +119,6 @@ class MapFragment : Fragment(), OnMapReadyCallback, MapsActivity.FragmentCallbac override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) - MapsConfiguration.getInstance().initialize(context) } override fun onCreateView( @@ -129,7 +130,9 @@ class MapFragment : Fragment(), OnMapReadyCallback, MapsActivity.FragmentCallbac binding.lifecycleOwner = this binding.vm = vm - locationClient = LostApiClient.Builder(requireContext()).build() + locationClient = LostApiClient.Builder(requireContext()) + .addConnectionCallbacks(this) + .build() locationClient.connect() clusterIconGenerator = ClusterIconGenerator(requireContext()) @@ -184,13 +187,17 @@ class MapFragment : Fragment(), OnMapReadyCallback, MapsActivity.FragmentCallbac private fun setupClickListeners() { binding.fabLocate.setOnClickListener { - if (!hasLocationPermission()) { + if (ContextCompat.checkSelfPermission( + requireContext(), + ACCESS_FINE_LOCATION + ) != PackageManager.PERMISSION_GRANTED + ) { requestPermissions( - arrayOf(Manifest.permission.ACCESS_FINE_LOCATION), + arrayOf(ACCESS_FINE_LOCATION), REQUEST_LOCATION_PERMISSION ) } else { - enableLocation(true, true) + enableLocation(moveTo = true, animate = true) } } binding.fabDirections.setOnClickListener { @@ -219,7 +226,7 @@ class MapFragment : Fragment(), OnMapReadyCallback, MapsActivity.FragmentCallbac bottomSheetBehavior.state = BottomSheetBehaviorGoogleMapsLike.STATE_ANCHOR_POINT } binding.search.setOnClickListener { - launchAutocomplete(requireContext()) + launchAutocomplete(requireActivity()) } binding.detailAppBar.toolbar.setNavigationOnClickListener { bottomSheetBehavior.state = STATE_COLLAPSED @@ -605,7 +612,11 @@ class MapFragment : Fragment(), OnMapReadyCallback, MapsActivity.FragmentCallbac positionSet = true } - if (hasLocationPermission()) { + if (ContextCompat.checkSelfPermission( + requireContext(), + ACCESS_FINE_LOCATION + ) == PackageManager.PERMISSION_GRANTED + ) { enableLocation(!positionSet, false) positionSet = true } @@ -621,32 +632,29 @@ class MapFragment : Fragment(), OnMapReadyCallback, MapsActivity.FragmentCallbac ) } - @SuppressLint("MissingPermission") + @RequiresPermission(ACCESS_FINE_LOCATION) private fun enableLocation(moveTo: Boolean, animate: Boolean) { val map = this.map ?: return map.setMyLocationEnabled(true) vm.myLocationEnabled.value = true map.uiSettings.setMyLocationButtonEnabled(false) if (moveTo && locationClient.isConnected) { - val location = LocationServices.FusedLocationApi.getLastLocation(locationClient) - if (location != null) { - val latLng = LatLng(location.latitude, location.longitude) - val camUpdate = map.cameraUpdateFactory.newLatLngZoom(latLng, 13f) - if (animate) { - map.animateCamera(camUpdate) - } else { - map.moveCamera(camUpdate) - } - } + moveToCurrentLocation(map, animate) } } - private fun hasLocationPermission(): Boolean { - val context = context ?: return false - return ContextCompat.checkSelfPermission( - context, - Manifest.permission.ACCESS_FINE_LOCATION - ) == PackageManager.PERMISSION_GRANTED + @RequiresPermission(ACCESS_FINE_LOCATION) + private fun moveToCurrentLocation(map: AnyMap, animate: Boolean) { + val location = LocationServices.FusedLocationApi.getLastLocation(locationClient) + if (location != null) { + val latLng = LatLng(location.latitude, location.longitude) + val camUpdate = map.cameraUpdateFactory.newLatLngZoom(latLng, 13f) + if (animate) { + map.animateCamera(camUpdate) + } else { + map.moveCamera(camUpdate) + } + } } @Synchronized @@ -732,6 +740,7 @@ class MapFragment : Fragment(), OnMapReadyCallback, MapsActivity.FragmentCallbac } } + @SuppressLint("MissingPermission") override fun onRequestPermissionsResult( requestCode: Int, permissions: Array, @@ -740,7 +749,7 @@ class MapFragment : Fragment(), OnMapReadyCallback, MapsActivity.FragmentCallbac when (requestCode) { REQUEST_LOCATION_PERMISSION -> { if ((grantResults.isNotEmpty() && grantResults[0] == PackageManager.PERMISSION_GRANTED)) { - enableLocation(true, true) + enableLocation(moveTo = true, animate = true) } } else -> super.onRequestPermissionsResult(requestCode, permissions, grantResults) @@ -847,4 +856,20 @@ class MapFragment : Fragment(), OnMapReadyCallback, MapsActivity.FragmentCallbac } } } + + override fun onConnected() { + val map = this.map ?: return + if (vm.myLocationEnabled.value == true) { + if (ActivityCompat.checkSelfPermission( + requireContext(), + ACCESS_FINE_LOCATION + ) == PackageManager.PERMISSION_GRANTED + ) { + moveToCurrentLocation(map, false) + } + } + } + + override fun onConnectionSuspended() { + } } \ No newline at end of file