我在使用Google商家信息自动填充功能时遇到问题。我正在关注这个tutorial,我没有收到任何错误,但是当我从我的国家输入一个地方时,textview并没有给我预测。
这是我的代码,与教程
完全相同cout << num_of_trailing_zeros << endl;
依赖条件
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;
}
}
}
答案 0 :(得分: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));
}
使用此适配器
/**
* 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;
}
}
答案 1 :(得分:0)
您应该替换您的代码
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"));
这一个
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"));