📜 ⬆️ ⬇️

Google Play Services Research: Place Picker & Autocomplete

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.

image
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 on the map
image

Select from the list
image

The obvious question is, “Why do we use 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.


Operational process Place Picker
image


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); // Do something with the place } } } 

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:

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:


 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.

Source: https://habr.com/ru/post/270217/


All Articles