Place Picker widget and Autocomplete component are powerful features of Google Play services. In this article we will look at them in detail, as well as how to implement them in applications.

With the release of Play Services 7.0, Google has made some very useful features available for implementation in our applications - two of which include the Place Picker UI and the Autocomplete component. Both of them can help to significantly improve existing solutions in your application, or even help you implement similar functions in your future applications. In any case, providing native and clean solutions in such frequently used functions will greatly help to improve the quality of the usage experience your application offers.
Taking into account the fact that I have not had the opportunity to implement any of these functions since their release, I decided that it was already time to take a closer look at them.
Together with this article, I created an application that allowed an experiment with these functions - you can find the code on github at the
link .
')
Customization
Since you are still reading this here, I believe that you want to try these components in person. So, before you put your java-hat on and write code, you need to start by adding the play-services-location dependency to your build.gradle file.
compile 'com.google.android.gms:play-services-location:8.1.0'
Note: In the event that you are not familiar with the format used, you only need to declare the dependency of the play service you will use. For more information, I recommend reading
this manual .
In addition, you will also need to register an API key when using location services, which can be done in the following
guide . Once you have completed the registration, you will need to add the API key and the play services version to your manifest file, as shown below:
<meta-data android:name="com.google.android.geo.API_KEY" android:value="YOUR_API_KEY" /> <meta-data android:name="com.google.android.gms.version" android:value="@integer/google_play_services_version" />
Place picker
The place picker is a user interface component that provides the ability to interact with an interactive map based on the current geographical location of the device. This map can be used to select nearby locations in one of two ways:
- Selection of the current location - The user can move the map displayed on the screen to select a location if the automatically selected one does not suit him.
- Selecting a place nearby - The user can choose a place from the list of places located near his current location; this list can be opened by dragging from the bottom of the map.
The obvious question is, “Why do we use it?”
- Development time is significantly reduced - Components are ready straight-out-of-the-box, which means that all functions (map, locations, life cycle, network requests, etc.) are completely controlled by the widget. Compared to how this can be done manually, time is simply enormous.
- Consistent experience of use - Using this component not only by Google, but also by third-party developers (like you) makes the user experience much easier, since they already know this component, which eliminates the extra time to learn how to work with it.
Operational process
So now we know what we are dealing with, everything looks as if we are ready to begin. There are several important operations that are always present in the Place Picker life cycle, which we will now review.
- Opening Place Picker using the startActivityForResult () method, the moment when we catch the selected place returned by our activity.
- The next step is to decide the initial location on the map. If the place is provided in advance - we use it, otherwise the current position of the device will be selected.
- Whether the user chooses a place on the map or from a list of places nearby, or will close the place picker without making a choice.
- As soon as the selection is made, the place picker is completed and the result (selected location) is returned to our activity.
Operational process Place Picker Implementation
First we need to create a new builder instance using the IntentBuilder from the Place Picker class.
PlacePicker.IntentBuilder builder = new PlacePicker.IntentBuilder();
Using this builder, we can set the initial boundaries of the dogma latitude that will be used by the place picker instance. As mentioned earlier, if the initial value is not set then by default our place picker will use the current position of the device as
LatLngBounds
.
builder.setLatLngBounds(new LatLngBounds(...));
Once this is done, we start the picker using the
startActivityForResult()
method, passing an instance of the place picker and the request code as parameters to our builder. As mentioned earlier, the selected place (
Place ) from Place Picker is returned to our activity in
onActivityResult
, where we use the request code
PLACE_PICKER_REQUEST to filter the results.
startActivityForResult(builder.build(this), PLACE_PICKER_REQUEST);
When the
startActivityForResult
method is
startActivityForResult
, the place picker widget in the new activity will be opened. Here the user will make a choice using the current position or location based on the recommendations. As soon as the place picker is closed, our
onActivityResult
will be called:
protected void onActivityResult(int requestCode, int resultCode, Intent data) { if (requestCode == PLACE_PICKER_REQUEST) { if (resultCode == RESULT_OK) { Place selectedPlace = PlacePicker.getPlace(data, this);
As shown above, we retrieve our selected place (
Place ) when activity returns it to us. We do this as follows:
Place selectedPlace = PlacePicker.getPlace(data, this);
In this place, if the user uses the
back button to exit the picker widget without selecting a location, then the result will not be returned.
Note : You will need to give your application the following rights -
ACCESS_FINE_LOCATION in order to use the
Place Picker widget.
Themes
To stay in the same theme with your application, by default the Place Picker widget will use the colors of your application:
- colorPrimary - Will be used as the text and arrow color back in the action bar of the application.
- colorPrimaryDark - This will be used as the background color for the action bar.
Be careful and check back the set color attributes of the theme.
Beacon Signals
With the release of play services 7.8, the place picker widget can also use signals from nearby beacons to determine the current location of the device. This works thanks to the
PlaceId
detected beacon (
beacon ) along with the other detected signals that are available to the device (network, wifi, etc.). Based on the collected geo-data, a list of recommendations will be built for displaying to the user as 'Places nearby' in the Place Picker component.
Place Autocomplete
Place Autocomplete is a new component that can be used to return a list of recommended places nearby based on a search query, where the result is offset from the current location of the device. Previously, to achieve this result, it was necessary to call the API of sites directly, but now the same can be done by wrapping GoogleApiClient automatically.
To begin, we must create a new instance of the GoogleApiClient class. For this we will use GoogleApiClient builder, where we also need to specify that we want to use the Places API:
mGoogleApiClient = new GoogleApiClient.Builder(this) .enableAutoManage(this, 0, this) .addApi(Places.GEO_DATA_API) .build();
As a result of the search query, the current location will query the Auto Complete API using this instance.
Since RxJava is currently part of my workflow, I decided to implement this with observables. I suggest you look at the
completed class to understand the code:
- We are starting to use the Places API to retrieve a list of auto-complete predictions based on the provided search queries and latitude-longitude boundaries.
PendingResult<AutocompletePredictionBuffer> results = Places.GeoDataApi.getAutocompletePredictions( mGoogleApiClient, query, bounds, null);
Note : Providing an
LatLngBounds
instance does not limit the results to these bounds. The results will be shifted within the limits provided, which means that places nearby will be given higher priority.
The
PendingResult
method
PendingResult
used to retrieve data from Google Play Services by accessing the API. We do this using the
await()
method to give the
PendingResult
some time to return data to us.
AutocompletePredictionBuffer autocompletePredictions = results.await(60, TimeUnit.SECONDS);
As soon as we wait for the result, we can check the status of our DataBuffer to check the success of the request:
final Status status = autocompletePredictions.getStatus(); if (!status.isSuccess()) { autocompletePredictions.release(); subscriber.onError(null); } else { for (AutocompletePrediction place : autocompletePredictions) { subscriber.onNext( new AutocompletePlace( place.getPlaceId(), place.getDescription() )); } autocompletePredictions.release(); subscriber.onCompleted(); }
If the request is completed successfully, we return a set of
AutocompletePrediction objects, which in theory are the minimal Place object. Since this will not be enough to display useful information to the user, we use
placeId
to get the complete Place object with the API. This is done by binding queries to our
observable stream, where we get place in this way:
final PendingResult<PlaceBuffer> placeResult = Places.GeoDataApi.getPlaceById(mGoogleApiClient, id); placeResult.setResultCallback(new ResultCallback<PlaceBuffer>() { @Override public void onResult(PlaceBuffer places) { if (!places.getStatus().isSuccess()) { places.release(); subscriber.onError(new Throwable(...)); } else { subscriber.onNext( PointOfInterest.fromPlace(places.get(0))); places.close(); subscriber.onCompleted(); } } });
Note : Do not forget to call
release
for a
PlaceBuffer instance.
These results Place will then be returned to the
activity and displayed as a result of the recyclerview search. Then it works like the
Place Picker example, when autocomplete predictions are selected from the list, it returns to the
MainActivity and displays it in the list of saved Places.
findings
I hope that from this article you can conclude how demonstrated services are easy to implement and configure, and I hope you will use them in your applications.
Although the standard
MapView
is still used in many different situations (mainly for fine tuning and increased functionality, Place Picker will be useful when you do not need any advanced features. The same applies to the Autocomplete component , again, you can independently implement an API call to get recommendations based on geodata, but using
GoogleApiClient
is much easier. Saying this, I believe that the components provided in Play Services will be enough to solve more The challenges of everyday tasks.