I am using Google Places Apis to filter results inside a particular city.I am able to filter results.but it also shows results out side of that city. For example if I set LatLngBounds of DELHI city and searching for a location in city NEWYORK. It also gives me result of NEWYORK city(but NEWYORK's LatLng is not lies inside DELHI).
How can I restrict my results to a particular city?
This is my PlaceAutoCompleteAdapter class
import com.google.android.gms.common.api.GoogleApiClient;
import com.google.android.gms.common.api.PendingResult;
import com.google.android.gms.common.api.Status;
import com.google.android.gms.common.data.DataBufferUtils;
import com.google.android.gms.location.places.AutocompleteFilter;
import com.google.android.gms.location.places.AutocompletePrediction;
import com.google.android.gms.location.places.AutocompletePredictionBuffer;
import com.google.android.gms.location.places.Places;
import com.google.android.gms.maps.model.LatLngBounds;
import android.content.Context;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ArrayAdapter;
import android.widget.Filter;
import android.widget.Filterable;
import android.widget.TextView;
import android.widget.Toast;
import java.util.ArrayList;
import java.util.concurrent.TimeUnit;
public class PlaceAutocompleteAdapter
extends ArrayAdapter<AutocompletePrediction> implements Filterable {
private ArrayList<AutocompletePrediction> mResultList;
private GoogleApiClient mGoogleApiClient;
private LatLngBounds mBounds;
private AutocompleteFilter mPlaceFilter;
public PlaceAutocompleteAdapter(Context context, GoogleApiClient googleApiClient,
LatLngBounds bounds, AutocompleteFilter filter) {
super(context,R.layout.simple_expandble_text_view_item, R.id.text1);
mGoogleApiClient = googleApiClient;
mBounds = bounds;
mPlaceFilter = filter;
}
public void setBounds(LatLngBounds bounds) {
mBounds = bounds;
}
@Override
public int getCount() {
return mResultList.size();
}
@Override
public AutocompletePrediction getItem(int position) {
return mResultList.get(position);
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
View row = super.getView(position, convertView, parent);
AutocompletePrediction item = getItem(position);
TextView textView1 = (TextView) row.findViewById(R.id.text1);
textView1.setText(item.getDescription());
return row;
}
@Override
public Filter getFilter() {
return new Filter() {
@Override
protected FilterResults performFiltering(CharSequence constraint) {
FilterResults results = new FilterResults();
if (constraint != null) {
mResultList = getAutocomplete(constraint);
if (mResultList != null) {
results.values = mResultList;
results.count = mResultList.size();
}
}
return results;
}
@Override
protected void publishResults(CharSequence constraint, FilterResults results) {
if (results != null && results.count > 0) {
notifyDataSetChanged();
} else {
notifyDataSetInvalidated();
}
}
@Override
public CharSequence convertResultToString(Object resultValue) {
if (resultValue instanceof AutocompletePrediction) {
return ((AutocompletePrediction) resultValue).getDescription();
} else {
return super.convertResultToString(resultValue);
}
}
};
}
private ArrayList<AutocompletePrediction> getAutocomplete(CharSequence constraint) {
if (mGoogleApiClient.isConnected()) {
PendingResult<AutocompletePredictionBuffer> results =
Places.GeoDataApi
.getAutocompletePredictions(mGoogleApiClient, constraint.toString(),
mBounds, mPlaceFilter);
AutocompletePredictionBuffer autocompletePredictions = results
.await(60, TimeUnit.SECONDS);
final Status status = autocompletePredictions.getStatus();
if (!status.isSuccess()) {
Toast.makeText(getContext(), "Error contacting API: " + status.toString(),
Toast.LENGTH_SHORT).show();
autocompletePredictions.release();
return null;
}
return DataBufferUtils.freezeAndClose(autocompletePredictions);
}
return null;
}
}
2) Make another web-service call to https://maps.googleapis.com/maps/api/place/details/json?key=API_KEY&placeid=place_id_retrieved_in_step_1. This will return a JSON which contains address_components . Looping through the types to find locality and postal_code can give you the city name and postal code.
Once you have a place_id from a Place Search, you can request more details about a particular establishment or point of interest by initiating a Place Details request.
Looking at the documentation:
public abstract PendingResult getAutocompletePredictions (GoogleApiClient client, String query, LatLngBounds bounds, AutocompleteFilter filter) Returns autocomplete predictions for a query based on the names and addresses of places. For more information, see the developer's guide.
This method performs a network lookup.
Access to this method is subject to quota restrictions. See Usage Limits for more details.
Parameters
query The query string for which the autocomplete predictions are to be fetched.
bounds A geographic bounds. If present, returned predictions will be biased towards places in this area.
filter A filter to use for restricting the returned predictions. If null, a filter with no constraints will be used.
The description for "bounds" is to return biased predictions. So those are not filtered, but biased basing on this bounds. This means that the results inside the bound should have higher priority, but those will not be the only results.
UPDATE
As of April 2018 Google added possibility to specify how to treat the bounds in autocomplete predictions. Now you can use the getAutocompletePredictions()
method of GeoDataClient
class with boundsMode
parameter.
See https://stackoverflow.com/a/50134855/5140781 for more details.
The code you have written is right. I also had done this but never tried with bounds. I checked with bounds and gone through the documentation, its written that it will give biased results that means it will give results with priority to the within the given bounds.
Here is the documentation link
https://developers.google.com/places/android-api/autocomplete
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With