Google Cloud Console Setup
Enable Maps SDK for Android on Google Cloud Console
Enable Billing
Get API Key
Goto Google Cloud Console -> Credentials
- Create credentials -> API key (copy API Key)
- Click Restrict Key
- name: Android-GoogleCloud
- Application restrictions: Android apps; Restrict usage to your Android apps: Add Item (Package Name, Sha1)
- API restrictions: Restrict key for
Maps SDK for Android
,Places API
Android Setup
Edit Module:app build.gradle
dependencies {
implementation 'com.google.android.libraries.places:places:2.0.0'
}
Initialize at Application class.
val API_KEY = ...Places.initialize(getApplicationContext(), API_KEY)
NOTE: Refer Android How to Secure Api Key
Autocomplete Activity
Popup an activity to allow user to search for places and select a place.
class CardFragment : Fragment() { companion object { const val REQUEST_PLACES_AUTOCOMPLETE = 1 } override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) { // super.onActivityResult(requestCode, resultCode, data) if (requestCode == REQUEST_PLACES_AUTOCOMPLETE) { when (resultCode) { RESULT_OK -> { val place = Autocomplete.getPlaceFromIntent(data!!) Timber.d("place=${place.id}, ${place.name}, ${place.latLng}, ${place.types}") } AutocompleteActivity.RESULT_ERROR -> { // TODO: Handle the error. val status = Autocomplete.getStatusFromIntent(data!!) Timber.e("status=$status") } RESULT_CANCELED -> // The user canceled the operation. Timber.d("cancelled") } } } private fun launchAutocomplete() { val fields = listOf(Place.Field.ID, Place.Field.NAME, Place.Field.LAT_LNG, Place.Field.ADDRESS_COMPONENTS, Place.Field.TYPES) val intent = Autocomplete.IntentBuilder(AutocompleteActivityMode.OVERLAY, fields) // .setLocationBias(bounds) .build(context) startActivityForResult(intent, REQUEST_PLACES_AUTOCOMPLETE) }}
NOTE: Refer to Build RectangularBounds From a List of LatLng for setLocationBias(bounds)
Autocomplete programmatically
val placesClient = Places.createClient(context)val token = AutocompleteSessionToken.newInstance()// val bounds = RectangularBounds.newInstance(latLng, latLng)val request = FindAutocompletePredictionsRequest.builder() // .setLocationBias(bounds) .setSessionToken(token) .setTypeFilter(TypeFilter.ESTABLISHMENT) .setCountry("US") .setQuery("Bahn Mi Cafe") .build()placesClient.findAutocompletePredictions(request)val response = placesClient.findAutocompletePredictions(request).await()for (prediction in response.autocompletePredictions) { Timber.d("prediction=${prediction.placeId}, ${prediction.getPrimaryText(null)}")}
NOTE: For Task.await()
, refer to Google Api Get Task Result Without Callback
Get Place Detail
val fields = listOf(Place.Field.ID, Place.Field.NAME, Place.Field.LAT_LNG, Place.Field.ADDRESS_COMPONENTS, Place.Field.TYPES)// val request = FetchPlaceRequest.newInstance(prediction.placeId, fields)val request = FetchPlaceRequest.builder(prediction.placeId, fields) .setSessionToken(token) .build()placesClient.fetchPlace(request)val placeResponse = placesClient.fetchPlace(request).await()val place = placeResponse.placeTimber.d("place=${place.id }, ${place.name}")
Troubleshoot
If you bump into the following error
com.google.android.gms.common.api.ApiException: 9011: This API project is not authorized to use this API.
Places: Error while autocompleting: REQUEST_DENIED
Map sure you enable APIs for Maps SDK for Android
and Places API
and API Key Restriction includes them as well.
References: