Skip to content

Commit edd7983

Browse files
authored
Migrated to latest Google Places API version (#297)
* Migrated to latest Google Places API version * resolved merge conflicts * removed explicit type arguments * mapped bounds to location bias * remove unneeded code * google places api as param in builder * Lint issues * Lint issues
1 parent 5694543 commit edd7983

7 files changed

Lines changed: 69 additions & 66 deletions

File tree

README.md

Lines changed: 3 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -260,29 +260,13 @@ That's all folks!
260260

261261
Leku now supports Google Places queries using the search box. If you want to enable it these are the steps you need to follow:
262262

263-
1. You need to replace your old `com.google.android.maps.v2.API_KEY` meta-data for the `com.google.android.geo.API_KEY`
263+
1. Enable Google Places API for Android on your [google developer console](https://console.developers.google.com/).
264264

265-
```xml
266-
<!-- Use this if only using Maps and not Places
267-
<meta-data
268-
android:name="com.google.android.maps.v2.API_KEY"
269-
android:value="@string/google_maps_key"
270-
/>
271-
-->
272-
273-
<meta-data
274-
android:name="com.google.android.geo.API_KEY"
275-
android:value="@string/google_maps_key"/>
276-
```
277-
278-
2. Enable Google Places API for Android on your [google developer console](https://console.developers.google.com/).
279-
280-
3. Enable it when instantiating LocationPickerActivity by adding `.withGooglePlacesEnabled()`:
265+
2. Add the key to the location picker builder
281266

282267
```kotlin
283268
val locationPickerIntent = LocationPickerActivity.Builder()
284-
**.withGooglePlacesEnabled()**
285-
.build(applicationContext)
269+
.withGooglePlacesApiKey("<PUT API KEY HERE>")
286270
```
287271

288272
And you are good to go. :)

app/src/main/java/com/schibsted/mappicker/MainActivity.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,7 @@ class MainActivity : AppCompatActivity() {
6565
val locationPickerIntent = LocationPickerActivity.Builder()
6666
.withLocation(41.4036299, 2.1743558)
6767
// .withGeolocApiKey("<PUT API KEY HERE>")
68+
// .withGooglePlacesApiKey("<PUT API KEY HERE>")
6869
// .withSearchZone("es_ES")
6970
// .withSearchZone(SearchZoneRect(LatLng(26.525467, -18.910366), LatLng(43.906271, 5.394197)))
7071
.withDefaultLocaleSearchZone()
@@ -73,7 +74,6 @@ class MainActivity : AppCompatActivity() {
7374
// .withCityHidden()
7475
// .withZipCodeHidden()
7576
// .withSatelliteViewHidden()
76-
// .withGooglePlacesEnabled()
7777
.withGoogleTimeZoneEnabled()
7878
// .withVoiceSearchHidden()
7979
.withUnnamedRoadHidden()

build.gradle

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@ plugins {
3333

3434
allprojects {
3535
repositories {
36+
maven { url 'https://jitpack.io' }
3637
maven {
3738
url "http://dl.bintray.com/schibstedspain/maven"
3839
}

leku/build.gradle

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -88,13 +88,13 @@ dependencies {
8888
exclude group: "com.android.support"
8989
}
9090

91-
implementation ("com.google.android.libraries.places:places-compat:2.2.0") {
91+
implementation ("com.google.android.libraries.places:places:2.2.0") {
9292
exclude group: "com.android.support"
9393
}
9494

9595
implementation "com.google.maps:google-maps-services:0.2.9"
9696

97-
implementation 'pl.charmas.android:android-reactive-location2:2.1@aar'
97+
implementation 'com.github.MarsXan:Android-ReactiveLocation:2.1.0'
9898

9999
implementation 'io.reactivex.rxjava3:rxjava:3.0.3'
100100
implementation 'io.reactivex.rxjava3:rxandroid:3.0.0'

leku/src/main/java/com/schibstedspain/leku/LocationPickerActivity.kt

Lines changed: 21 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,6 @@ import com.google.android.gms.common.GoogleApiAvailability
3333
import com.google.android.gms.common.api.GoogleApiClient
3434
import com.google.android.gms.location.LocationListener
3535
import com.google.android.gms.location.LocationServices
36-
import com.google.android.gms.location.places.Places
3736
import com.google.android.gms.maps.CameraUpdateFactory
3837
import com.google.android.gms.maps.GoogleMap
3938
import com.google.android.gms.maps.GoogleMap.MAP_TYPE_NORMAL
@@ -46,6 +45,7 @@ import com.google.android.gms.maps.model.LatLng
4645
import com.google.android.gms.maps.model.MapStyleOptions
4746
import com.google.android.gms.maps.model.Marker
4847
import com.google.android.gms.maps.model.MarkerOptions
48+
import com.google.android.libraries.places.api.Places
4949
import com.google.android.material.floatingactionbutton.FloatingActionButton
5050
import com.google.maps.GeoApiContext
5151
import com.schibstedspain.leku.geocoder.AndroidGeocoderDataSource
@@ -88,6 +88,7 @@ const val TIME_ZONE_DISPLAY_NAME = "time_zone_display_name"
8888
const val MAP_STYLE = "map_style"
8989
const val UNNAMED_ROAD_VISIBILITY = "unnamed_road_visibility"
9090
private const val GEOLOC_API_KEY = "geoloc_api_key"
91+
private const val PLACES_API_KEY = "places_api_key"
9192
private const val LOCATION_KEY = "location_key"
9293
private const val LAST_LOCATION_QUERY = "last_location_query"
9394
private const val OPTIONS_HIDE_STREET = "street"
@@ -143,7 +144,7 @@ class LocationPickerActivity : AppCompatActivity(),
143144
private var shouldReturnOkOnBackPressed = false
144145
private var enableSatelliteView = true
145146
private var enableLocationPermissionRequest = true
146-
private var isGooglePlacesEnabled = false
147+
private var googlePlacesApiKey: String? = null
147148
private var isGoogleTimeZoneEnabled = false
148149
private var searchZone: String? = null
149150
private var searchZoneRect: SearchZoneRect? = null
@@ -247,7 +248,13 @@ class LocationPickerActivity : AppCompatActivity(),
247248
}
248249

249250
private fun setUpMainVariables() {
250-
val placesDataSource = GooglePlacesDataSource(Places.getGeoDataClient(this))
251+
var placesDataSource: GooglePlacesDataSource? = null
252+
if (!Places.isInitialized() && !googlePlacesApiKey.isNullOrEmpty()) {
253+
googlePlacesApiKey?.let {
254+
Places.initialize(applicationContext, it)
255+
}
256+
placesDataSource = GooglePlacesDataSource(Places.createClient(this))
257+
}
251258
val geocoder = Geocoder(this, Locale.getDefault())
252259
apiInteractor = GoogleGeocoderDataSource(NetworkClient(), AddressBuilder())
253260
val geocoderRepository = GeocoderRepository(AndroidGeocoderDataSource(geocoder), apiInteractor!!)
@@ -352,7 +359,7 @@ class LocationPickerActivity : AppCompatActivity(),
352359
updateAddressLayoutVisibility()
353360
updateVoiceSearchVisibility()
354361

355-
if (isGooglePlacesEnabled) {
362+
if (!googlePlacesApiKey.isNullOrEmpty()) {
356363
geocoderPresenter?.enableGooglePlaces()
357364
}
358365
}
@@ -710,8 +717,8 @@ class LocationPickerActivity : AppCompatActivity(),
710717
if (savedInstanceState.keySet().contains(GEOLOC_API_KEY)) {
711718
apiInteractor?.setApiKey(savedInstanceState.getString(GEOLOC_API_KEY, ""))
712719
}
713-
if (savedInstanceState.keySet().contains(ENABLE_GOOGLE_PLACES)) {
714-
isGooglePlacesEnabled = savedInstanceState.getBoolean(ENABLE_GOOGLE_PLACES, false)
720+
if (savedInstanceState.keySet().contains(PLACES_API_KEY)) {
721+
googlePlacesApiKey = savedInstanceState.getString(PLACES_API_KEY, "")
715722
}
716723
if (savedInstanceState.keySet().contains(ENABLE_GOOGLE_TIME_ZONE)) {
717724
isGoogleTimeZoneEnabled = savedInstanceState.getBoolean(ENABLE_GOOGLE_TIME_ZONE, false)
@@ -778,8 +785,8 @@ class LocationPickerActivity : AppCompatActivity(),
778785
if (transitionBundle.keySet().contains(GEOLOC_API_KEY)) {
779786
apiInteractor!!.setApiKey(transitionBundle.getString(GEOLOC_API_KEY, ""))
780787
}
781-
if (transitionBundle.keySet().contains(ENABLE_GOOGLE_PLACES)) {
782-
isGooglePlacesEnabled = transitionBundle.getBoolean(ENABLE_GOOGLE_PLACES, false)
788+
if (transitionBundle.keySet().contains(PLACES_API_KEY)) {
789+
googlePlacesApiKey = transitionBundle.getString(PLACES_API_KEY, "")
783790
}
784791
if (transitionBundle.keySet().contains(ENABLE_GOOGLE_TIME_ZONE)) {
785792
isGoogleTimeZoneEnabled = transitionBundle.getBoolean(ENABLE_GOOGLE_TIME_ZONE, false)
@@ -1155,10 +1162,6 @@ class LocationPickerActivity : AppCompatActivity(),
11551162
.addOnConnectionFailedListener(this)
11561163
.addApi(LocationServices.API)
11571164

1158-
if (isGooglePlacesEnabled) {
1159-
googleApiClientBuilder.addApi(Places.GEO_DATA_API)
1160-
}
1161-
11621165
googleApiClient = googleApiClientBuilder.build()
11631166
googleApiClient?.connect()
11641167
}
@@ -1215,7 +1218,7 @@ class LocationPickerActivity : AppCompatActivity(),
12151218
private var shouldReturnOkOnBackPressed = false
12161219
private var lekuPois: List<LekuPoi>? = null
12171220
private var geolocApiKey: String? = null
1218-
private var googlePlacesEnabled = false
1221+
private var googlePlacesApiKey: String? = null
12191222
private var googleTimeZoneEnabled = false
12201223
private var voiceSearchEnabled = true
12211224
private var mapStyle: Int? = null
@@ -1285,8 +1288,8 @@ class LocationPickerActivity : AppCompatActivity(),
12851288
return this
12861289
}
12871290

1288-
fun withGooglePlacesEnabled(): Builder {
1289-
this.googlePlacesEnabled = true
1291+
fun withGooglePlacesApiKey(apiKey: String): Builder {
1292+
this.googlePlacesApiKey = apiKey
12901293
return this
12911294
}
12921295

@@ -1339,8 +1342,10 @@ class LocationPickerActivity : AppCompatActivity(),
13391342
geolocApiKey?.let {
13401343
intent.putExtra(GEOLOC_API_KEY, geolocApiKey)
13411344
}
1345+
googlePlacesApiKey?.let {
1346+
intent.putExtra(PLACES_API_KEY, googlePlacesApiKey)
1347+
}
13421348
mapStyle?.let { style -> intent.putExtra(MAP_STYLE, style) }
1343-
intent.putExtra(ENABLE_GOOGLE_PLACES, googlePlacesEnabled)
13441349
intent.putExtra(ENABLE_GOOGLE_TIME_ZONE, googleTimeZoneEnabled)
13451350
intent.putExtra(ENABLE_VOICE_SEARCH, voiceSearchEnabled)
13461351
intent.putExtra(UNNAMED_ROAD_VISIBILITY, unnamedRoadVisible)

leku/src/main/java/com/schibstedspain/leku/geocoder/GeocoderPresenter.kt

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -52,10 +52,9 @@ class GeocoderPresenter @JvmOverloads constructor(
5252

5353
fun getLastKnownLocation() {
5454
@SuppressLint("MissingPermission")
55-
val disposable = RxJavaBridge.toV3Observable(locationProvider.lastKnownLocation)
55+
val disposable = RxJavaBridge.toV3Single(locationProvider.lastKnownLocation)
5656
.retry(RETRY_COUNT.toLong())
5757
.subscribe({ view?.showLastLocation(it) },
58-
{ },
5958
{ view?.didGetLastLocation() })
6059
compositeDisposable.add(disposable)
6160
}

leku/src/main/java/com/schibstedspain/leku/geocoder/places/GooglePlacesDataSource.kt

Lines changed: 40 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,17 @@
11
package com.schibstedspain.leku.geocoder.places
22

3-
import android.annotation.SuppressLint
43
import android.location.Address
5-
import com.google.android.gms.common.data.DataBufferUtils
6-
import com.google.android.gms.location.places.AutocompletePrediction
7-
import com.google.android.gms.location.places.GeoDataClient
8-
import com.google.android.gms.location.places.Place
94
import com.google.android.gms.maps.model.LatLngBounds
105
import com.google.android.gms.tasks.RuntimeExecutionException
116
import com.google.android.gms.tasks.Tasks
7+
import com.google.android.libraries.places.api.model.Place
8+
import com.google.android.libraries.places.api.model.RectangularBounds
9+
import com.google.android.libraries.places.api.net.FetchPlaceRequest
10+
import com.google.android.libraries.places.api.net.FindAutocompletePredictionsRequest
11+
import com.google.android.libraries.places.api.net.FindAutocompletePredictionsResponse
12+
import com.google.android.libraries.places.api.net.PlacesClient
1213
import io.reactivex.rxjava3.core.Observable
1314
import io.reactivex.rxjava3.core.Observable.defer
14-
import java.util.ArrayList
1515
import java.util.Locale
1616
import java.util.concurrent.ExecutionException
1717
import java.util.concurrent.TimeUnit
@@ -20,11 +20,19 @@ import java.util.concurrent.TimeoutException
2020
private const val PREDICTIONS_WAITING_TIME: Long = 6
2121
private const val PLACE_BY_ID_WAITING_TIME: Long = 3
2222

23-
class GooglePlacesDataSource(private val geoDataClient: GeoDataClient) {
23+
class GooglePlacesDataSource(private val geoDataClient: PlacesClient) {
2424

2525
fun getFromLocationName(query: String, latLngBounds: LatLngBounds): Observable<List<Address>> {
26+
val locationBias = RectangularBounds.newInstance(
27+
latLngBounds.southwest,
28+
latLngBounds.northeast)
2629
return defer {
27-
val results = geoDataClient.getAutocompletePredictions(query, latLngBounds, null)
30+
val findAutocompletePredictionsRequest = FindAutocompletePredictionsRequest
31+
.builder()
32+
.setQuery(query)
33+
.setLocationBias(locationBias)
34+
.build()
35+
val results = geoDataClient.findAutocompletePredictions(findAutocompletePredictionsRequest)
2836
try {
2937
Tasks.await(results, PREDICTIONS_WAITING_TIME, TimeUnit.SECONDS)
3038
} catch (ignored: ExecutionException) {
@@ -33,39 +41,45 @@ class GooglePlacesDataSource(private val geoDataClient: GeoDataClient) {
3341
}
3442

3543
try {
36-
val autocompletePredictions = results.result
37-
val predictionList = DataBufferUtils.freezeAndClose(autocompletePredictions)
38-
val addressList = getAddressListFromPrediction(predictionList)
44+
val addressList = getAddressListFromPrediction(results.result)
3945
return@defer Observable.just(addressList)
4046
} catch (e: RuntimeExecutionException) {
4147
return@defer Observable.just(ArrayList<Address>())
4248
}
4349
}
4450
}
4551

46-
private fun getAddressListFromPrediction(predictionList: List<AutocompletePrediction>): List<Address> {
52+
private fun getAddressListFromPrediction(result: FindAutocompletePredictionsResponse?): List<Address> {
4753
val addressList = ArrayList<Address>()
48-
for (prediction in predictionList) {
49-
val placeBufferResponseTask = geoDataClient.getPlaceById(prediction.placeId!!)
50-
try {
51-
Tasks.await(placeBufferResponseTask, PLACE_BY_ID_WAITING_TIME, TimeUnit.SECONDS)
52-
} catch (ignored: ExecutionException) {
53-
} catch (ignored: InterruptedException) {
54-
} catch (ignored: TimeoutException) {
55-
}
54+
result?.let { predictionsResults ->
55+
for (prediction in predictionsResults.autocompletePredictions) {
56+
val placeFields = listOf(Place.Field.ID, Place.Field.NAME)
57+
val fetchPlaceRequest = FetchPlaceRequest.builder(prediction.placeId, placeFields).build()
58+
val placeBufferResponseTask = geoDataClient.fetchPlace(fetchPlaceRequest)
59+
try {
60+
Tasks.await(placeBufferResponseTask, PLACE_BY_ID_WAITING_TIME, TimeUnit.SECONDS)
61+
} catch (ignored: ExecutionException) {
62+
} catch (ignored: InterruptedException) {
63+
} catch (ignored: TimeoutException) {
64+
}
5665

57-
val placeBufferResponse = placeBufferResponseTask.result
58-
@SuppressLint("RestrictedApi") val place = placeBufferResponse!!.get(0)
59-
addressList.add(mapPlaceToAddress(place))
66+
val placeBufferResponse = placeBufferResponseTask.result
67+
val place = placeBufferResponse?.place
68+
place?.let {
69+
addressList.add(mapPlaceToAddress(it))
70+
}
71+
}
6072
}
6173
return addressList
6274
}
6375

6476
private fun mapPlaceToAddress(place: Place): Address {
6577
val address = Address(Locale.getDefault())
66-
address.latitude = place.latLng.latitude
67-
address.longitude = place.latLng.longitude
68-
val addressName = place.name.toString() + " - " + place.address!!.toString()
78+
place.latLng?.let {
79+
address.latitude = it.latitude
80+
address.longitude = it.longitude
81+
}
82+
val addressName = place.name.toString() + " - " + place.address.toString()
6983
address.setAddressLine(0, addressName)
7084
address.featureName = addressName
7185
return address

0 commit comments

Comments
 (0)