I'm trying to implement AutocompleteTextView with predictions of Google Places in Android, so here's my code, which I took partially from Google sample
public class PlaceArrayAdapter
extends ArrayAdapter<PlaceArrayAdapter.PlaceAutocomplete> implements Filterable {
private static final String TAG = "PlaceArrayAdapter";
private GoogleApiClient mGoogleApiClient;
private AutocompleteFilter mPlaceFilter;
private LatLngBounds mBounds;
private ArrayList<PlaceAutocomplete> mResultList;
/**
* Constructor
*
* #param context Context
* #param resource Layout resource
* #param bounds Used to specify the search bounds
* #param filter Used to specify place types
*/
public PlaceArrayAdapter(Context context, int resource, LatLngBounds bounds,
AutocompleteFilter filter) {
super(context, resource);
mBounds = bounds;
mPlaceFilter = filter;
}
public void setGoogleApiClient(GoogleApiClient googleApiClient) {
if (googleApiClient == null || !googleApiClient.isConnected()) {
mGoogleApiClient = null;
} else {
mGoogleApiClient = googleApiClient;
}
}
#Override
public int getCount() {
return mResultList.size();
}
#Override
public PlaceAutocomplete getItem(int position) {
return mResultList.get(position);
}
private ArrayList<PlaceAutocomplete> resultList;
private ArrayList<PlaceAutocomplete> getPredictions(CharSequence constraint) {
if (mGoogleApiClient != null) {
Log.i(TAG, "Executing autocomplete query for: " + constraint);
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: " + status.toString(),
Toast.LENGTH_SHORT).show();
Log.e(TAG, "Error getting place predictions: " + status
.toString());
autocompletePredictions.release();
return null;
}
Iterator<AutocompletePrediction> iterator = autocompletePredictions.iterator();
resultList = new ArrayList<>(autocompletePredictions.getCount());
while (iterator.hasNext()) {
AutocompletePrediction prediction = iterator.next();
resultList.add(new PlaceAutocomplete(prediction.getPlaceId(),
prediction.getDescription()));
}
autocompletePredictions.release();
return resultList;
}
Log.e(TAG, "Google API client is not connected.");
return null;
}
#Override
public Filter getFilter() {
Filter filter = new Filter() {
#Override
protected FilterResults performFiltering(CharSequence constraint) {
FilterResults results = new FilterResults();
if (constraint != null) {
// Query the autocomplete API for the entered constraint
mResultList = getPredictions(constraint);
if (mResultList != null) {
// Results
results.values = mResultList;
results.count = mResultList.size();
}
}
return results;
}
#Override
protected void publishResults(CharSequence constraint, FilterResults results) {
if (results != null && results.count > 0) {
// The API returned at least one result, update the data.
notifyDataSetChanged();
} else {
// The API did not return any results, invalidate the data set.
notifyDataSetInvalidated();
}
}
};
return filter;
}
public class PlaceAutocomplete {
public CharSequence placeId;
public CharSequence description;
public CharSequence streetAddress;
PlaceAutocomplete(CharSequence placeId, CharSequence description) {
this.placeId = placeId;
this.description = description;
}
#Override
public String toString() {
return description.toString();
}
}
}
So the problem is it returns only Description, while I need the street Address only, without country and city, when I try to rewrite code like this:
private ArrayList<PlaceAutocomplete> getPredictions(CharSequence constraint) {
if (mGoogleApiClient != null) {
Log.i(TAG, "Executing autocomplete query for: " + constraint);
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: " + status.toString(),
Toast.LENGTH_SHORT).show();
Log.e(TAG, "Error getting place predictions: " + status
.toString());
autocompletePredictions.release();
return null;
}
Iterator<AutocompletePrediction> iterator = autocompletePredictions.iterator();
resultList = new ArrayList<>(autocompletePredictions.getCount());
while (iterator.hasNext()) {
AutocompletePrediction prediction = iterator.next();
PendingResult<PlaceBuffer> placeResult = Places.GeoDataApi
.getPlaceById(mGoogleApiClient, prediction.getPlaceId());
placeResult.setResultCallback(new ResultCallback<PlaceBuffer>() {
#Override
public void onResult(PlaceBuffer places) {
if (!places.getStatus().isSuccess()) {
Log.e("ERROR", "Place query did not complete. Error: " +
places.getStatus().toString());
return;
}
final Place place = places.get(0);
resultList.add(new PlaceAutocomplete(place.getId(), place.getName()));
}
});
}
autocompletePredictions.release();
return resultList;
}
Log.e(TAG, "Google API client is not connected.");
return null;
}
But it works very slow, and returns data only in English, while I need it to be returned in Russian language.
So if anyone ever tried to do such things - please help :)
Related
I was using android's autocompelete for fetching places but now I have just create new play console app for that I didn't get the option for Android Sdk for places rather there is option for places Api only but I am using same code as earlier Places Autocomplete and I am getting and error:
Error getting place predictions:
Status{statusCode=PLACES_API_ACCESS_NOT_CONFIGURED, resolution=null}
I am using following gradle :
implementation 'com.google.android.gms:play-services-plus:16.0.0'
implementation 'com.google.android.gms:play-services-auth:16.0.1'
implementation 'com.google.android.gms:play-services-maps:16.1.0'
implementation 'com.google.android.gms:play-services-location:16.0.0'
implementation 'com.google.android.gms:play-services-places:16.0.0'
and My Place Adapter code is :
public class PlaceArrayAdapter extends ArrayAdapter<PlaceArrayAdapter.PlaceAutocomplete> implements Filterable {
private static final String TAG = "PlaceArrayAdapter";
private GoogleApiClient mGoogleApiClient;
private AutocompleteFilter mPlaceFilter;
private LatLngBounds mBounds;
private ArrayList<PlaceAutocomplete> mResultList;
/**
* Constructor
*
* #param context Context
* #param resource Layout resource
* #param bounds Used to specify the search bounds
* #param filter Used to specify place types
*/
public PlaceArrayAdapter(Context context, int resource, LatLngBounds bounds,
AutocompleteFilter filter) {
super(context, resource);
mBounds = bounds;
mPlaceFilter = filter;
}
public void setGoogleApiClient(GoogleApiClient googleApiClient) {
if (googleApiClient == null || !googleApiClient.isConnected()) {
mGoogleApiClient = null;
} else {
mGoogleApiClient = googleApiClient;
}
}
#Override
public int getCount() {
return mResultList.size();
}
#Override
public PlaceAutocomplete getItem(int position) {
return mResultList.get(position);
}
private ArrayList<PlaceAutocomplete> getPredictions(CharSequence constraint) {
if (mGoogleApiClient != null) {
Logger.showMessage("Executing autocomplete query for: " + constraint);
PendingResult<AutocompletePredictionBuffer> results =
Places.GeoDataApi
.getAutocompletePredictions(mGoogleApiClient, constraint.toString(),
mBounds, mPlaceFilter);
// Wait for predictions, set the timeout.
AutocompletePredictionBuffer autocompletePredictions = results
.await(60, TimeUnit.SECONDS);
final Status status = autocompletePredictions.getStatus();
if (!status.isSuccess()) {
Toast.makeText(getContext(), "Error: " + status.toString(),
Toast.LENGTH_SHORT).show();
Logger.showMessage("Error getting place predictions: " + status
.toString());
autocompletePredictions.release();
return null;
}
Logger.showMessage("Query completed. Received " + autocompletePredictions.getCount()
+ " predictions.");
Iterator<AutocompletePrediction> iterator = autocompletePredictions.iterator();
ArrayList resultList = new ArrayList<>(autocompletePredictions.getCount());
while (iterator.hasNext()) {
AutocompletePrediction prediction = iterator.next();
resultList.add(new PlaceAutocomplete(prediction.getPlaceId(),
prediction.getFullText(null)));
}
// Buffer release
autocompletePredictions.release();
return resultList;
}
Logger.showMessage("Google API client is not connected.");
return null;
}
#Override
public Filter getFilter() {
Filter filter = new Filter() {
#Override
protected FilterResults performFiltering(CharSequence constraint) {
FilterResults results = new FilterResults();
if (constraint != null) {
// Query the autocomplete API for the entered constraint
mResultList = getPredictions(constraint);
if (mResultList != null) {
// Results
results.values = mResultList;
results.count = mResultList.size();
}
}
return results;
}
#Override
protected void publishResults(CharSequence constraint, FilterResults results) {
if (results != null && results.count > 0) {
// The API returned at least one result, update the data.
notifyDataSetChanged();
} else {
// The API did not return any results, invalidate the data set.
notifyDataSetInvalidated();
}
}
};
return filter;
}
public class PlaceAutocomplete {
public CharSequence placeId;
public CharSequence description;
PlaceAutocomplete(CharSequence placeId, CharSequence description) {
this.placeId = placeId;
this.description = description;
}
#Override
public String toString() {
return description.toString();
}
}
}
Activity code :
GoogleApiClient mGoogleApiClient;
GoogleSignInOptions gso;
private PlaceArrayAdapter mPlaceArrayAdapter;
private void googlePlaceApi() {
gso = new GoogleSignInOptions.Builder(GoogleSignInOptions.DEFAULT_SIGN_IN)
.requestEmail()
.build();
mGoogleApiClient = new GoogleApiClient.Builder(this)
.addApi(Places.GEO_DATA_API)
.addApi(Auth.GOOGLE_SIGN_IN_API, gso)
.enableAutoManage(this, MYPerference.GOOGLE_API_CLIENT_ID, this)
.addConnectionCallbacks(this)
.build();
etLocation.setThreshold(1);
etLocation.setOnItemClickListener(mAutocompleteClickListener);
mPlaceArrayAdapter = new PlaceArrayAdapter(this, android.R.layout.simple_list_item_1,
BOUNDS_MOUNTAIN_VIEW, null);
etLocation.setAdapter(mPlaceArrayAdapter);
}
private AdapterView.OnItemClickListener mAutocompleteClickListener
= new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
final PlaceArrayAdapter.PlaceAutocomplete item = mPlaceArrayAdapter.getItem(position);
Logger.showMessage(" place id : "+item.placeId);
final String placeId = String.valueOf(item.placeId);
PendingResult<PlaceBuffer> placeResult = Places.GeoDataApi
.getPlaceById(mGoogleApiClient, placeId);
placeResult.setResultCallback(mUpdatePlaceDetailsCallback);
}
};
private ResultCallback<PlaceBuffer> mUpdatePlaceDetailsCallback
= new ResultCallback<PlaceBuffer>() {
#Override
public void onResult(PlaceBuffer places) {
if (!places.getStatus().isSuccess()) {
return;
}
Logger.showMessage(" error : "+places.getStatus().getStatusMessage());
Logger.showMessage(" error : "+places.getStatus());
// Selecting the first object buffer.
final Place place = places.get(0);
CharSequence attributions = places.getAttributions();
address = String.valueOf(place.getAddress());
latString = String.valueOf(place.getLatLng().latitude);
lngString = String.valueOf(place.getLatLng().longitude);
//getLatLongFromAddress(address);
}
};
Note : Places Api is Enabled and unable to find any option for Places sdk for android and App billing is enabled and is working in Ios.
Thanks in advance.
I found this PlacesAutoCompleteAdapter in one of tutorials, but I cannot change it to show specified data.
I want to:
display only cities (not all companies and etc)
save to AutoCompleteTextView only when item is selected from list
Can you guys help me with this?
I think I need to change mPlaceFilter to display only citites (locality or administrative_area_level_3) but I don't know how...
public class PlacesAutoCompleteAdapter
extends ArrayAdapter<PlacesAutoCompleteAdapter.PlaceAutocomplete> implements Filterable {
private static final String TAG = "PlaceAutocomplete";
/**
* Current results returned by this adapter.
*/
private ArrayList<PlaceAutocomplete> mResultList;
/**
* Handles autocomplete requests.
*/
private GoogleApiClient mGoogleApiClient;
/**
* The bounds used for Places Geo Data autocomplete API requests.
*/
private LatLngBounds mBounds;
/**
* The autocomplete filter used to restrict queries to a specific set of place types.
*/
private AutocompleteFilter mPlaceFilter;
/**
* Initializes with a resource for text rows and autocomplete query bounds.
*
* #see ArrayAdapter#ArrayAdapter(Context, int)
*/
public PlacesAutoCompleteAdapter(Context context, int resource, GoogleApiClient googleApiClient,
LatLngBounds bounds, AutocompleteFilter filter) {
super(context, resource);
mGoogleApiClient = googleApiClient;
mBounds = bounds;
mPlaceFilter = filter;
}
/**
* Sets the bounds for all subsequent queries.
*/
public void setBounds(LatLngBounds bounds) {
mBounds = bounds;
}
/**
* Returns the number of results received in the last autocomplete query.
*/
#Override
public int getCount() {
return mResultList.size();
}
/**
* Returns an item from the last autocomplete query.
*/
#Override
public PlaceAutocomplete getItem(int position) {
return mResultList.get(position);
}
/**
* Returns the filter for the current set of autocomplete results.
*/
#Override
public Filter getFilter() {
Filter filter = new Filter() {
#Override
protected FilterResults performFiltering(CharSequence constraint) {
FilterResults results = new FilterResults();
// Skip the autocomplete query if no constraints are given OR has got less than 3 letters
if (constraint != null && constraint.length() >= 3) {
// Query the autocomplete API for the (constraint) search string.
mResultList = getAutocomplete(constraint);
if (mResultList != null) {
// The API successfully returned results.
results.values = mResultList;
results.count = mResultList.size();
}
}
return results;
}
#Override
protected void publishResults(CharSequence constraint, FilterResults results) {
if (results != null && results.count > 0) {
// The API returned at least one result, update the data.
notifyDataSetChanged();
} else {
// The API did not return any results, invalidate the data set.
notifyDataSetInvalidated();
}
}
};
return filter;
}
private ArrayList<PlaceAutocomplete> getAutocomplete(CharSequence constraint) {
if (mGoogleApiClient.isConnected()) {
Log.i(TAG, "Starting autocomplete query for: " + constraint);
// Submit the query to the autocomplete API and retrieve a PendingResult that will
// contain the results when the query completes.
PendingResult<AutocompletePredictionBuffer> results =
Places.GeoDataApi
.getAutocompletePredictions(mGoogleApiClient, constraint.toString(),
mBounds, mPlaceFilter);
// This method should have been called off the main UI thread. Block and wait for at most 60s
// for a result from the API.
AutocompletePredictionBuffer autocompletePredictions = results
.await(60, TimeUnit.SECONDS);
// Confirm that the query completed successfully, otherwise return null
final Status status = autocompletePredictions.getStatus();
if (!status.isSuccess()) {
Toast.makeText(getContext(), "Error contacting API: " + status.getStatusMessage(),
Toast.LENGTH_SHORT).show();
Log.e(TAG, "Error getting autocomplete prediction API call: " + status.toString());
autocompletePredictions.release();
return null;
}
Log.i(TAG, "Query completed. Received " + autocompletePredictions.getCount()
+ " predictions.");
// Copy the results into our own data structure, because we can't hold onto the buffer.
// AutocompletePrediction objects encapsulate the API response (place ID and description).
Iterator<AutocompletePrediction> iterator = autocompletePredictions.iterator();
ArrayList resultList = new ArrayList<>(autocompletePredictions.getCount());
while (iterator.hasNext()) {
AutocompletePrediction prediction = iterator.next();
// Get the details of this prediction and copy it into a new PlaceAutocomplete object.
resultList.add(new PlaceAutocomplete(prediction.getPlaceId(), prediction.getFullText(null)));
}
// Release the buffer now that all data has been copied.
autocompletePredictions.release();
return resultList;
}
Log.e(TAG, "Google API client is not connected for autocomplete query.");
return null;
}
/**
* Holder for Places Geo Data Autocomplete API results.
*/
public class PlaceAutocomplete {
public CharSequence placeId;
public CharSequence description;
PlaceAutocomplete(CharSequence placeId, CharSequence description) {
this.placeId = placeId;
this.description = description;
}
#Override
public String toString() {
return description.toString();
}
}
}
Set filter to cities like this:
mPlaceFilter = new AutocompleteFilter.Builder()
.setTypeFilter(AutocompleteFilter.TYPE_FILTER_CITIES)
.build();
Hi everyone,
We are facing one problem regarding google maps i.e,Place finding using AutoCompleteTextview.
We are getting message as Google API connected but places are not displaying for AutoCompleteTextView i.e,not giving any suggentions for places
Here is below code:
public class PlacesAutoCompleteActivity extends BaseActivity implements
GoogleApiClient.OnConnectionFailedListener,
GoogleApiClient.ConnectionCallbacks {
private static final String LOG_TAG = "Finding Location";
private static final int GOOGLE_API_CLIENT_ID = 0;
private static final int ACCESS_FINE_LOCATION = 0;
private AutoCompleteTextView mAutocompleteTextView;
private GoogleApiClient mGoogleApiClient;
private PlaceArrayAdapter mPlaceArrayAdapter;
private static final LatLngBounds BOUNDS_MOUNTAIN_VIEW = new LatLngBounds(
new LatLng(37.398160, -122.180831), new LatLng(37.430610, -121.972090));
private Toolbar mToolbar;
private TextView tv_currentLocation;
Context mContext;
public static double latitude = 0;
public static double longitude = 0;
Handler handler;
public static String st_city, st_postalcode, st_statename, st_countryname;
private String str_loc = null;
private ListView lv_location;
ArrayList<String> arraylocation;
List<Addressdetails> address_details;
ArrayAdapter<String> locationadapter;
private LinearLayout ll_currentlocation;
private String st_featurName;
private String st_throughfare;
private String st_loc_firstname;
private String st_loc_lastname;
private String st_loc_email;
private String st_loc_phone;
private String st_loc_specailInstrc;
private String st_loc_addressline2;
private String st_loc_active;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_pick_up_location);
mContext = this;
mToolbar = (Toolbar) findViewById(R.id.toolbar_picklocation);
setSupportActionBar(mToolbar);
// mToolbar.setTitle(R.string.app_name);
mToolbar.setTitleTextColor(getResources().getColor(R.color.white));
mToolbar.setNavigationIcon(R.drawable.abc_ic_ab_back_mtrl_am_alpha);
mToolbar.setNavigationOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
onBackPressed();
}
});
if (InternetDetector.isConnected(PlacesAutoCompleteActivity.this)) {
mGoogleApiClient = new GoogleApiClient.Builder(PlacesAutoCompleteActivity.this)
.addApi(Places.GEO_DATA_API)
.enableAutoManage(this, GOOGLE_API_CLIENT_ID, this)
.addConnectionCallbacks(this)
.addApi(LocationServices.API)
.addApi(Places.PLACE_DETECTION_API)
.addOnConnectionFailedListener(this)
.build();
mAutocompleteTextView = (AutoCompleteTextView) findViewById(R.id.autocomplete_places);
mAutocompleteTextView.setThreshold(1);
mAutocompleteTextView.setDropDownBackgroundResource(R.color.white);
mAutocompleteTextView.setOnItemClickListener(mAutocompleteClickListener);
mPlaceArrayAdapter = new PlaceArrayAdapter(this, android.R.layout.simple_list_item_1, BOUNDS_MOUNTAIN_VIEW, null);
mAutocompleteTextView.setAdapter(mPlaceArrayAdapter);
}
private String loc_placename;
private AdapterView.OnItemClickListener mAutocompleteClickListener
= new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
final PlaceArrayAdapter.PlaceAutocomplete item = mPlaceArrayAdapter.getItem(position);
final String placeId = String.valueOf(item.placeId);
loc_placename = String.valueOf(item.description);
Log.i(LOG_TAG, "Loctaionname " + loc_placename);
PendingResult<PlaceBuffer> placeResult = Places.GeoDataApi
.getPlaceById(mGoogleApiClient, placeId);
placeResult.setResultCallback(mUpdatePlaceDetailsCallback);
Log.i(LOG_TAG, "Fetching details for ID: " + item.placeId);
}
};
private ResultCallback<PlaceBuffer> mUpdatePlaceDetailsCallback
= new ResultCallback<PlaceBuffer>() {
#Override
public void onResult(PlaceBuffer places) {
if (!places.getStatus().isSuccess()) {
Log.d(LOG_TAG, "Place query did not complete. Error: " +
places.getStatus().toString());
return;
}
// Selecting the first object buffer.
try {
final Place place = places.get(0);
// CharSequence attributions = places.getAttributions();
LatLng queried_location = place.getLatLng();
latitude = queried_location.latitude;
longitude = queried_location.longitude;
//Toast.makeText(getApplicationContext(),queried_location.latitude+ "Text"+queried_location.longitude, Toast.LENGTH_LONG).show();
getAddressFromLocation(latitude, longitude, getApplicationContext(), handler);
//
}
} catch (Exception e) {
Log.d("Exception", e.toString());
}
}
};
public void getAddressFromLocation(final double latitude, final double longitude,
final Context context, final Handler handler) {
Thread thread = new Thread() {
#Override
public void run() {
Geocoder geocoder = new Geocoder(context, Locale.getDefault());
String result = null;
try {
List<Address> addressList = geocoder.getFromLocation(
latitude, longitude, 1);
if (addressList != null && addressList.size() > 0) {
Address address = addressList.get(0);
st_city = address.getLocality();
st_countryname = address.getCountryName();
st_postalcode = address.getPostalCode();
st_statename = address.getAdminArea();
st_featurName = address.getFeatureName();//route
st_throughfare = address.getThoroughfare();//street
Log.d("values", st_featurName + st_throughfare);
}
} catch (IOException e) {
Log.e(LOG_TAG, "Unable connect to Geocoder", e);
}
}
};
thread.start();
}
}
#Override
public void onConnected(Bundle bundle) {
mPlaceArrayAdapter.setGoogleApiClient(mGoogleApiClient);
Log.i(LOG_TAG, "Google Places API connected.");
}
#Override
public void onConnectionFailed(ConnectionResult connectionResult) {
Log.e(LOG_TAG, "Google Places API connection failed with error code: "
+ connectionResult.getErrorCode());
/* Toast.makeText(this,
"Google Places API connection failed with error code:" +
connectionResult.getErrorCode(),
Toast.LENGTH_LONG).show()*/;
}
#Override
public void onConnectionSuspended(int i) {
mPlaceArrayAdapter.setGoogleApiClient(null);
Log.e(LOG_TAG, "Google Places API connection suspended.");
}
}
Here is PlaceAdapter class:
package com.app.letmecall.customer.Adapters;
import android.content.Context;
import android.util.Log;
import android.widget.ArrayAdapter;
import android.widget.Filter;
import android.widget.Filterable;
import android.widget.Toast;
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.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 java.util.ArrayList;
import java.util.Iterator;
import java.util.concurrent.TimeUnit;
#SuppressWarnings("unchecked")
public class PlaceArrayAdapter
extends ArrayAdapter<PlaceArrayAdapter.PlaceAutocomplete> implements Filterable {
private static final String TAG = "PlaceArrayAdapter";
private GoogleApiClient mGoogleApiClient;
private AutocompleteFilter mPlaceFilter;
private LatLngBounds mBounds;
private ArrayList<PlaceAutocomplete> mResultList;
/**
* Constructor
*
* #param context Context
* #param resource Layout resource
* #param bounds Used to specify the search bounds
* #param filter Used to specify place types
*/
#SuppressWarnings("unchecked")
public PlaceArrayAdapter(Context context, int resource, LatLngBounds bounds,
AutocompleteFilter filter) {
super(context, resource);
mBounds = bounds;
mPlaceFilter = filter;
}
#SuppressWarnings("unchecked")
public void setGoogleApiClient(GoogleApiClient googleApiClient) {
if (googleApiClient == null || !googleApiClient.isConnected()) {
mGoogleApiClient = null;
} else {
mGoogleApiClient = googleApiClient;
}
}
#SuppressWarnings("unchecked")
#Override
public int getCount() {
return mResultList.size();
}
#SuppressWarnings("unchecked")
#Override
public PlaceAutocomplete getItem(int position) {
return mResultList.get(position);
}
#SuppressWarnings("unchecked")
private ArrayList<PlaceAutocomplete> getPredictions(CharSequence constraint) {
if (mGoogleApiClient != null) {
Log.i(TAG, "Executing autocomplete query for: " + constraint);
PendingResult<AutocompletePredictionBuffer> results =
Places.GeoDataApi
.getAutocompletePredictions(mGoogleApiClient, constraint.toString(),
mBounds, mPlaceFilter);
// Wait for predictions, set the timeout.
AutocompletePredictionBuffer autocompletePredictions = results
.await(60, TimeUnit.SECONDS);
final Status status = autocompletePredictions.getStatus();
if (!status.isSuccess()) {
/* Toast.makeText(getContext(), "Error: " + status.toString(),
Toast.LENGTH_SHORT).show();
Log.e(TAG, "Error getting place predictions: " + status
.toString());*/
autocompletePredictions.release();
return null;
}
Log.i(TAG, "Query completed. Received " + autocompletePredictions.getCount()
+ " predictions.");
Iterator<AutocompletePrediction> iterator = autocompletePredictions.iterator();
ArrayList resultList = new ArrayList<>(autocompletePredictions.getCount());
while (iterator.hasNext()) {
AutocompletePrediction prediction = iterator.next();
resultList.add(new PlaceAutocomplete(prediction.getPlaceId(),
prediction.getDescription()));
}
// Buffer release
autocompletePredictions.release();
return resultList;
}
Log.e(TAG, "Google API client is not connected.");
return null;
}
#SuppressWarnings("unchecked")
#Override
public Filter getFilter() {
Filter filter = new Filter() {
#Override
protected FilterResults performFiltering(CharSequence constraint) {
FilterResults results = new FilterResults();
if (constraint != null) {
// Query the autocomplete API for the entered constraint
mResultList = getPredictions(constraint);
if (mResultList != null) {
// Results
results.values = mResultList;
results.count = mResultList.size();
}
}
return results;
}
#SuppressWarnings("unchecked")
#Override
protected void publishResults(CharSequence constraint, FilterResults results) {
if (results != null && results.count > 0) {
// The API returned at least one result, update the data.
notifyDataSetChanged();
} else {
// The API did not return any results, invalidate the data set.
notifyDataSetInvalidated();
}
}
};
return filter;
}
#SuppressWarnings("unchecked")
public class PlaceAutocomplete {
public CharSequence placeId;
public CharSequence description;
#SuppressWarnings("unchecked")
PlaceAutocomplete(CharSequence placeId, CharSequence description) {
this.placeId = placeId;
this.description = description;
}
#SuppressWarnings("unchecked")
#Override
public String toString() {
return description.toString();
}
}
}
Please guide us!
Thanks in advance
try this
((TextView) findViewById(R.id.startpoint)).setOnClickListener(this);
Inside the OnClick(View)
Intent intent = new PlaceAutocomplete.IntentBuilder(PlaceAutocomplete.MODE_FULLSCREEN).build(Final_maps.this);
startActivityForResult(intent, REQUEST_INT);
Select the place:
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
Place place = PlaceAutocomplete.getPlace(Final_maps.this, data);
Log.d(TAG, place.toString());
((TextView) findViewById(R.id.startpoint)).setText(place.getName());
Inside the manifest make sure you have added
<permission
android:name="<com.package.name>.permission.MAPS_RECEIVE"
android:protectionLevel="signature" />
<uses-permission android:name="<com.package.name>.permission.MAPS_RECEIVE" />
<uses-permission android:name="com.google.android.providers.gsf.permission.READ_GSERVICES" />
I am using the autoComplete Places API and also the google maps in my activity. I want to remove the logo Powered by google which is being appeared in the drop down list of autoComplete Places API but I have found only solution in javascript not for android.
Finally I implemented like below:
This is the adapter
public class PlaceArrayAdapter extends ArrayAdapter<PlaceArrayAdapter.PlaceAutocomplete> implements Filterable {
private static final String TAG = "PlaceArrayAdapter";
private GoogleApiClient mGoogleApiClient;
private AutocompleteFilter mPlaceFilter;
private LatLngBounds mBounds;
private ArrayList<PlaceAutocomplete> mResultList;
/**
* Constructor
*
* #param context Context
* #param resource Layout resource
* #param bounds Used to specify the search bounds
* #param filter Used to specify place types
*/
public PlaceArrayAdapter(Context context, int resource, LatLngBounds bounds, AutocompleteFilter filter) {
super(context, resource);
mBounds = bounds;
mPlaceFilter = filter;
}
public void setGoogleApiClient(GoogleApiClient googleApiClient) {
if (googleApiClient == null || !googleApiClient.isConnected()) {
mGoogleApiClient = null;
} else {
mGoogleApiClient = googleApiClient;
}
}
#Override
public int getCount() {
return mResultList.size();
}
#Override
public PlaceAutocomplete getItem(int position) {
return mResultList.get(position);
}
private ArrayList<PlaceAutocomplete> getPredictions(CharSequence constraint) {
if (mGoogleApiClient != null) {
Log.i(TAG, "Executing autocomplete query for: " + constraint);
PendingResult<AutocompletePredictionBuffer> results =
Places.GeoDataApi
.getAutocompletePredictions(mGoogleApiClient, constraint.toString(),
mBounds, mPlaceFilter);
// Wait for predictions, set the timeout.
AutocompletePredictionBuffer autocompletePredictions = results
.await(60, TimeUnit.SECONDS);
final Status status = autocompletePredictions.getStatus();
if (!status.isSuccess()) {
Toast.makeText(getContext(), "Error: " + status.toString(),
Toast.LENGTH_SHORT).show();
Log.e(TAG, "Error getting place predictions: " + status
.toString());
autocompletePredictions.release();
return null;
}
Log.i(TAG, "Query completed. Received " + autocompletePredictions.getCount()
+ " predictions.");
Iterator<AutocompletePrediction> iterator = autocompletePredictions.iterator();
ArrayList resultList = new ArrayList<>(autocompletePredictions.getCount());
while (iterator.hasNext()) {
AutocompletePrediction prediction = iterator.next();
resultList.add(new PlaceAutocomplete(prediction.getPlaceId(),
prediction.getDescription()));
}
// Buffer release
autocompletePredictions.release();
return resultList;
}
Log.e(TAG, "Google API client is not connected.");
return null;
}
#Override
public Filter getFilter() {
Filter filter = new Filter() {
#Override
protected FilterResults performFiltering(CharSequence constraint) {
FilterResults results = new FilterResults();
if (constraint != null) {
// Query the autocomplete API for the entered constraint
mResultList = getPredictions(constraint);
if (mResultList != null) {
// Results
results.values = mResultList;
results.count = mResultList.size();
}
}
return results;
}
#Override
protected void publishResults(CharSequence constraint, FilterResults results) {
if (results != null && results.count > 0) {
// The API returned at least one result, update the data.
notifyDataSetChanged();
} else {
// The API did not return any results, invalidate the data set.
notifyDataSetInvalidated();
}
}
};
return filter;
}
class PlaceAutocomplete {
public CharSequence placeId;
public CharSequence description;
PlaceAutocomplete(CharSequence placeId, CharSequence description) {
this.placeId = placeId;
this.description = description;
}
#Override
public String toString() {
return description.toString();
}
}
}
and this is the activity:
public class FindLocationByTextActivity extends AppCompatActivity implements OnMapReadyCallback, GoogleApiClient.OnConnectionFailedListener, GoogleApiClient.ConnectionCallbacks {
private static final int GOOGLE_API_CLIENT_ID = 0;
private GoogleApiClient mGoogleApiClient;
private PlaceArrayAdapter mPlaceArrayAdapter;
private AutoCompleteTextView mAutocompleteTextView;
private static final LatLngBounds BOUNDS_MOUNTAIN_VIEW = new LatLngBounds(new LatLng(37.398160, -122.180831), new LatLng(37.430610, -121.972090));
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_find_location_by_text);
mGoogleApiClient = new GoogleApiClient.Builder(FindLocationByTextActivity.this)
.addApi(Places.GEO_DATA_API)
.enableAutoManage(this, GOOGLE_API_CLIENT_ID, this)
.addConnectionCallbacks(this)
.build();
mAutocompleteTextView = (AutoCompleteTextView) findViewById(R.id.place_autocomplete_text_view);
mAutocompleteTextView.setThreshold(2);
mAutocompleteTextView.setOnItemClickListener(mAutocompleteClickListener);
mPlaceArrayAdapter = new PlaceArrayAdapter(this, android.R.layout.simple_list_item_1, BOUNDS_MOUNTAIN_VIEW, null);
mAutocompleteTextView.setAdapter(mPlaceArrayAdapter);
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.menu_location, menu);
return true;
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
// Handle action bar item clicks here. The action bar will
// automatically handle clicks on the Home/Up button, so long
// as you specify a parent activity in AndroidManifest.xml.
int id = item.getItemId();
return super.onOptionsItemSelected(item);
}
private AdapterView.OnItemClickListener mAutocompleteClickListener
= new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
final PlaceArrayAdapter.PlaceAutocomplete item = mPlaceArrayAdapter.getItem(position);
final String placeId = String.valueOf(item.placeId);
Log.i("Location", "Selected: " + item.description);
PendingResult<PlaceBuffer> placeResult = Places.GeoDataApi
.getPlaceById(mGoogleApiClient, placeId);
placeResult.setResultCallback(mUpdatePlaceDetailsCallback);
Log.i("Location", "Fetching details for ID: " + item.placeId);
}
};
private ResultCallback<PlaceBuffer> mUpdatePlaceDetailsCallback
= new ResultCallback<PlaceBuffer>() {
#Override
public void onResult(PlaceBuffer places) {
if (!places.getStatus().isSuccess()) {
Log.e("Location", "Place query did not complete. Error: " +
places.getStatus().toString());
return;
}
// Selecting the first object buffer.
final Place place = places.get(0);
Log.i("name", place.getName().toString());
Log.i("coordinates", place.getLatLng().toString());
}
};
#Override
public void onConnected(Bundle bundle) {
mPlaceArrayAdapter.setGoogleApiClient(mGoogleApiClient);
Log.i("Location", "Google Places API connected.");
}
#Override
public void onConnectionFailed(ConnectionResult connectionResult) {
Log.e("Location", "Google Places API connection failed with error code: "
+ connectionResult.getErrorCode());
Toast.makeText(this,
"Google Places API connection failed with error code:" +
connectionResult.getErrorCode(),
Toast.LENGTH_LONG).show();
}
#Override
public void onConnectionSuspended(int i) {
mPlaceArrayAdapter.setGoogleApiClient(null);
Log.e("Location", "Google Places API connection suspended.");
}
}
If your application displays data from the Places API on a Google Map, then the Google logo will be included and may not be altered.
If your application displays Places API data on a page or view without a Google Map, you must show a 'Powered by Google' image with that data.
For use on a light background: #drawable/places_powered_by_google_light
For use on a dark background: #drawable/places_powered_by_google_dark
for more detail please refer this google documentation link
https://developers.google.com/places/android-sdk/attributions
I'm having trouble using the Google Places Autocomplete. I'm following this tutorial, I don't get any errors, but the textview isn't giving me predictions when I type a place from my country.
This is my code which is exactly the same from the tutorial
public class MainActivity extends Activity implements OnItemClickListener {
private static final String LOG_TAG = "Google Places Autocomplete";
private static final String PLACES_API_BASE = "https://maps.googleapis.com/maps/api/place";
private static final String TYPE_AUTOCOMPLETE = "/autocomplete";
private static final String OUT_JSON = "/json";
private static final String API_KEY = "my api key here";
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
AutoCompleteTextView autoCompView = (AutoCompleteTextView) findViewById(R.id.autoCompleteTextView);
autoCompView.setAdapter(new GooglePlacesAutocompleteAdapter(this, R.layout.list_item));
autoCompView.setOnItemClickListener(this);
}
public void onItemClick(AdapterView adapterView, View view, int position, long id) {
String str = (String) adapterView.getItemAtPosition(position);
Toast.makeText(this, str, Toast.LENGTH_SHORT).show();
}
public static ArrayList autocomplete(String input) {
ArrayList resultList = null;
HttpURLConnection conn = null;
StringBuilder jsonResults = new StringBuilder();
try {
StringBuilder sb = new StringBuilder(PLACES_API_BASE + TYPE_AUTOCOMPLETE + OUT_JSON);
sb.append("?key=" + API_KEY);
sb.append("&components=country:ph");
sb.append("&input=" + URLEncoder.encode(input, "utf8"));
URL url = new URL(sb.toString());
conn = (HttpURLConnection) url.openConnection();
InputStreamReader in = new InputStreamReader(conn.getInputStream());
// Load the results into a StringBuilder
int read;
char[] buff = new char[1024];
while ((read = in.read(buff)) != -1) {
jsonResults.append(buff, 0, read);
}
} catch (MalformedURLException e) {
Log.e(LOG_TAG, "Error processing Places API URL", e);
return resultList;
} catch (IOException e) {
Log.e(LOG_TAG, "Error connecting to Places API", e);
return resultList;
} finally {
if (conn != null) {
conn.disconnect();
}
}
try {
// Create a JSON object hierarchy from the results
JSONObject jsonObj = new JSONObject(jsonResults.toString());
JSONArray predsJsonArray = jsonObj.getJSONArray("predictions");
// Extract the Place descriptions from the results
resultList = new ArrayList(predsJsonArray.length());
for (int i = 0; i < predsJsonArray.length(); i++) {
System.out.println(predsJsonArray.getJSONObject(i).getString("description"));
System.out.println("============================================================");
resultList.add(predsJsonArray.getJSONObject(i).getString("description"));
}
} catch (JSONException e) {
Log.e(LOG_TAG, "Cannot process JSON results", e);
}
return resultList;
}
class GooglePlacesAutocompleteAdapter extends ArrayAdapter implements Filterable {
private ArrayList resultList;
public GooglePlacesAutocompleteAdapter(Context context, int textViewResourceId) {
super(context, textViewResourceId);
}
#Override
public int getCount() {
return resultList.size();
}
#Override
public Object getItem(int index) {
return resultList.get(index);
}
#Override
public Filter getFilter() {
Filter filter = new Filter() {
#Override
protected FilterResults performFiltering(CharSequence constraint) {
FilterResults filterResults = new FilterResults();
if (constraint != null) {
// Retrieve the autocomplete results.
resultList = autocomplete(constraint.toString());
// Assign the data to the FilterResults
filterResults.values = resultList;
filterResults.count = resultList.size();
}
return filterResults;
}
#Override
protected void publishResults(CharSequence constraint, FilterResults results) {
if (results != null && results.count > 0) {
notifyDataSetChanged();
} else {
notifyDataSetInvalidated();
}
}
};
return filter;
}
}
}
dependecies
dependencies {
compile fileTree(dir: 'libs', include: ['*.jar'])
testCompile 'junit:junit:4.12'
compile 'com.android.support:appcompat-v7:23.1.1'
compile 'com.android.support:design:23.1.1'
compile 'com.google.android.gms:play-services-location:8.3.0'
}
private AdapterView.OnItemClickListener mAutocompleteClickListener
= new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
/*
Retrieve the place ID of the selected item from the Adapter.
The adapter stores each Place suggestion in a AutocompletePrediction from which we
read the place ID and title.
*/
final AutocompletePrediction item = mAdapter.getItem(position);
final String placeId = item.getPlaceId();
final CharSequence primaryText = item.getDescription();
Log.i(TAG, "Autocomplete item selected: " + primaryText);
/*
Issue a request to the Places Geo Data API to retrieve a Place object with additional
details about the place.
*/
mAutocompleteView.setText("");
PendingResult<PlaceBuffer> placeResult = Places.GeoDataApi.getPlaceById(mGoogleApiClient, placeId);
placeResult.setResultCallback(mUpdatePlaceDetailsCallback);
{
InputMethodManager imm = (InputMethodManager)getSystemService(Context.INPUT_METHOD_SERVICE);
imm.hideSoftInputFromWindow(view.getWindowToken(), 0);
}
//Toast.makeText(getApplicationContext(), "Clicked: " + primaryText, Toast.LENGTH_SHORT).show();
Log.i(TAG, "Called getPlaceById to get Place details for " + placeId);
}
};
private ResultCallback<PlaceBuffer> mUpdatePlaceDetailsCallback = new ResultCallback<PlaceBuffer>() {
#Override
public void onResult(PlaceBuffer places) {
if (!places.getStatus().isSuccess()) {
// Request did not complete successfully
Log.e(TAG, "Place query did not complete. Error: " + places.getStatus().toString());
places.release();
return;
}
// Get the Place object from the buffer.
final Place place = places.get(0);
Spanned s;
// Format details of the place for display and show it in a TextView.
s=formatPlaceDetails(getResources(),
place.getName(),place.getId(), place.getAddress(),
place.getPhoneNumber(),place.getWebsiteUri());
MY_ADDRESS=place.getName().toString();
getLatlong(place.getId());
final CharSequence thirdPartyAttribution = places.getAttributions();
if (thirdPartyAttribution == null) {
// mPlaceDetailsAttribution.setVisibility(View.GONE);
} else {
// mPlaceDetailsAttribution.setVisibility(View.VISIBLE);
// mPlaceDetailsAttribution.setText(Html.fromHtml(thirdPartyAttribution.toString()));
}
Log.i(TAG, "Place details received: " + place.getName());
getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_HIDDEN);
places.release();
}
};
private static Spanned formatPlaceDetails(Resources res, CharSequence name, String id,CharSequence address, CharSequence phoneNumber, Uri websiteUri) {
Log.e(TAG, res.getString(R.string.place_details, name, id, address, phoneNumber, websiteUri));
return Html.fromHtml(res.getString(R.string.place_details, name, id, address, phoneNumber,websiteUri));
}
Use this Adapter
/**
* Created by Alan on 06-11-2015.
*/
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.graphics.Typeface;
import android.text.style.CharacterStyle;
import android.text.style.StyleSpan;
import android.util.Log;
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.Iterator;
import java.util.concurrent.TimeUnit;
/**
* Adapter that handles Autocomplete requests from the Places Geo Data API.
* {#link AutocompletePrediction} results from the API are frozen and stored directly in this
* adapter. (See {#link AutocompletePrediction#freeze()}.)
* <p>
* Note that this adapter requires a valid {#link com.google.android.gms.common.api.GoogleApiClient}.
* The API client must be maintained in the encapsulating Activity, including all lifecycle and
* connection states. The API client must be connected with the {#link Places#GEO_DATA_API} API.
*/
public class PlaceAutocompleteAdapter
extends ArrayAdapter<AutocompletePrediction> implements Filterable {
private static final String TAG = "PlaceAutoComAdapter";
private static final CharacterStyle STYLE_BOLD = new StyleSpan(Typeface.BOLD);
/**
* Current results returned by this adapter.
*/
private ArrayList<AutocompletePrediction> mResultList;
/**
* Handles autocomplete requests.
*/
private GoogleApiClient mGoogleApiClient;
/**
* The bounds used for Places Geo Data autocomplete API requests.
*/
private LatLngBounds mBounds;
/**
* The autocomplete filter used to restrict queries to a specific set of place types.
*/
private AutocompleteFilter mPlaceFilter;
/**
* Initializes with a resource for text rows and autocomplete query bounds.
*
* #see android.widget.ArrayAdapter#ArrayAdapter(android.content.Context, int)
*/
public PlaceAutocompleteAdapter(Context context, GoogleApiClient googleApiClient,
LatLngBounds bounds, AutocompleteFilter filter) {
super(context, android.R.layout.simple_list_item_1,android.R.id.text1);
mGoogleApiClient = googleApiClient;
mBounds = bounds;
mPlaceFilter = filter;
}
/**
* Sets the bounds for all subsequent queries.
*/
public void setBounds(LatLngBounds bounds) {
mBounds = bounds;
}
/**
* Returns the number of results received in the last autocomplete query.
*/
#Override
public int getCount() {
return mResultList.size();
}
/**
* Returns an item from the last autocomplete query.
*/
#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);
// Sets the primary and secondary text for a row.
// Note that getPrimaryText() and getSecondaryText() return a CharSequence that may contain
// styling based on the given CharacterStyle.
AutocompletePrediction item = getItem(position);
TextView textView1 = (TextView) row.findViewById(android.R.id.text1);
//TextView textView2 = (TextView) row.findViewById(android.R.id.text2);
textView1.setText(item.getDescription());
//textView2.setText(item.getDescription());
return row;
}
/**
* Returns the filter for the current set of autocomplete results.
*/
#Override
public Filter getFilter() {
return new Filter() {
#Override
protected FilterResults performFiltering(CharSequence constraint) {
FilterResults results = new FilterResults();
// Skip the autocomplete query if no constraints are given.
if (constraint != null) {
// Query the autocomplete API for the (constraint) search string.
mResultList = getAutocomplete(constraint);
if (mResultList != null) {
// The API successfully returned results.
results.values = mResultList;
results.count = mResultList.size();
}
}
return results;
}
#Override
protected void publishResults(CharSequence constraint, FilterResults results) {
if (results != null && results.count > 0) {
// The API returned at least one result, update the data.
notifyDataSetChanged();
} else {
// The API did not return any results, invalidate the data set.
notifyDataSetInvalidated();
}
}
#Override
public CharSequence convertResultToString(Object resultValue) {
// Override this method to display a readable result in the AutocompleteTextView
// when clicked.
if (resultValue instanceof AutocompletePrediction) {
return ((AutocompletePrediction) resultValue).getDescription();
} else {
return super.convertResultToString(resultValue);
}
}
};
}
/**
* Submits an autocomplete query to the Places Geo Data Autocomplete API.
* Results are returned as frozen AutocompletePrediction objects, ready to be cached.
* objects to store the Place ID and description that the API returns.
* Returns an empty list if no results were found.
* Returns null if the API client is not available or the query did not complete
* successfully.
* This method MUST be called off the main UI thread, as it will block until data is returned
* from the API, which may include a network request.
*
* #param constraint Autocomplete query string
* #return Results from the autocomplete API or null if the query was not successful.
* #see Places#GEO_DATA_API#getAutocomplete(CharSequence)
* #see AutocompletePrediction#freeze()
*/
private ArrayList<AutocompletePrediction> getAutocomplete(CharSequence constraint) {
if (mGoogleApiClient.isConnected()) {
Log.i(TAG, "Starting autocomplete query for: " + constraint);
// Submit the query to the autocomplete API and retrieve a PendingResult that will
// contain the results when the query completes.
PendingResult<AutocompletePredictionBuffer> results =
Places.GeoDataApi
.getAutocompletePredictions(mGoogleApiClient, constraint.toString(),
mBounds, mPlaceFilter);
// This method should have been called off the main UI thread. Block and wait for at most 60s
// for a result from the API.
AutocompletePredictionBuffer autocompletePredictions = results
.await(60, TimeUnit.SECONDS);
// Confirm that the query completed successfully, otherwise return null
final Status status = autocompletePredictions.getStatus();
if (!status.isSuccess()) {
Toast.makeText(getContext(), "Error contacting API: " + status.toString(),
Toast.LENGTH_SHORT).show();
Log.e(TAG, "Error getting autocomplete prediction API call: " + status.toString());
autocompletePredictions.release();
return null;
}
Log.i(TAG, "Query completed. Received " + autocompletePredictions.getCount()
+ " predictions.");
// Freeze the results immutable representation that can be stored safely.
return DataBufferUtils.freezeAndClose(autocompletePredictions);
}
Log.e(TAG, "Google API client is not connected for autocomplete query.");
return null;
}
}
You should replace your code
StringBuilder sb = new StringBuilder(PLACES_API_BASE + TYPE_AUTOCOMPLETE + OUT_JSON);
sb.append("?key=" + API_KEY);
sb.append("&components=country:ph");
sb.append("&input=" + URLEncoder.encode(input, "utf8"));
with this one
StringBuilder sb = new StringBuilder(PLACES_API_BASE + TYPE_AUTOCOMPLETE + OUT_JSON);
sb.append("?key=" + API_KEY);
sb.append(""); // THIS SHOULD BE LEFT BLANK
sb.append("&input=" + URLEncoder.encode(input, "utf8"));