Google将自动完成API安卓设置为无效
我正在定义我的界限如下:
private static final LatLngBounds BOUNDS_CHENNAI = new LatLngBounds(
new LatLng(12.8339547, 80.0817007), new LatLng(13.2611661, 80.33632279999999)); // Chennai city bounds.
创建Goolge API客户端如下:
mGoogleApiClient = new GoogleApiClient.Builder(this)
.enableAutoManage(this,this)
.addApi(Places.GEO_DATA_API)
.addConnectionCallbacks(this)
.build();
在适配器中使用这些边界如下:
PendingResult<AutocompletePredictionBuffer> results =
Places.GeoDataApi
.getAutocompletePredictions(mGoogleApiClient, constraint.toString(),
mBounds, mPlaceFilter);
根据文件是应该返回我只在钦奈市内的位置,但它返回我从世界各地的位置。
例如,当我输入“Sola”时,它将返回Ahmedabad城市的“Sola路”,而不是在边界内显示匹配结果。
我有与android中的界限相同的问题。 我尝试了一切,无法解决问题。
寻找其他网页时,我在尝试设置区域边界时在javascript文档中发现了这个问题:
结果偏向于但不限于包含在这些范围内的地点。
它看起来像android的地方api文档不完整。 我们将不得不等待。
如果您必须显示指定国家或附近国家/地区的结果,我发现了一个原始解决方法:
private ArrayList<PlaceAutocomplete> getAutocomplete(CharSequence constraint) {
if (mGoogleApiClient.isConnected()) {
// 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);
AutocompletePredictionBuffer autocompletePredictions = results
.await(60, TimeUnit.SECONDS);
final Status status = autocompletePredictions.getStatus();
if (status.isSuccess()) {
Log.i(LOG_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<PlaceAutocomplete> 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.
String data = prediction.getDescription();
// here we manually checking whether description contains our needed country(ies)
if (predictionIsInNeededCountry(data)) {
resultList.add(new PlaceAutocomplete(prediction.getPlaceId(), prediction.getDescription(),
prediction.getPrimaryText(mCharacterStyle), prediction.getSecondaryText(mCharacterStyle),
prediction.getFullText(mCharacterStyle)));
}
}
} else {
Toast.makeText(mContext, "Error contacting API: " + status.toString(),
Toast.LENGTH_SHORT).show();
Log.e(LOG_TAG, "Error getting autocomplete prediction API call: " + status.toString());
autocompletePredictions.release();
return null;
}
// Release the buffer now that all data has been copied.
autocompletePredictions.release();
return resultList;
}
Log.e(LOG_TAG, "Google API client is not connected for autocomplete query.");
return null;
}
private boolean predictionIsInNeededCountry(String data) {
// here you can add countries (in different languages if you want)
// also you can try get current country programmatically with use of Geocoder
if (data.contains("Ukraine") || data.contains("Украина") || data.contains("Україна")) {
return true;
}
return false;
}
对于边界我使用当前坐标(当前的经度和纬度为西南和东北)。
我还实施了另一个解决方案
它似乎工作更准确,但需要额外的请求和计算。
就我而言,我只需要来自2个国家的结果,所以我最终得到了第一个更简单的解决方案。
import android.content.Context;
import android.content.res.Resources;
import android.net.Uri;
import android.os.Bundle;
import android.support.v4.app.FragmentActivity;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.Toolbar;
import android.text.Html;
import android.text.Spanned;
import android.view.MenuItem;
import android.view.View;
import android.widget.AdapterView;
import android.widget.AutoCompleteTextView;
import android.widget.Button;
import android.widget.TextView;
import com.google.android.gms.common.ConnectionResult;
import com.google.android.gms.common.api.GoogleApiClient;
import com.google.android.gms.common.api.PendingResult;
import com.google.android.gms.common.api.ResultCallback;
import com.google.android.gms.location.places.AutocompletePrediction;
import com.google.android.gms.location.places.Place;
import com.google.android.gms.location.places.PlaceBuffer;
import com.google.android.gms.location.places.Places;
import com.google.android.gms.maps.model.LatLng;
import com.google.android.gms.maps.model.LatLngBounds;
public class SearchPlacesActivity extends AppCompatActivity implements GoogleApiClient.OnConnectionFailedListener {
protected GoogleApiClient mGoogleApiClient;
private PlaceAutocompleteAdapter mAdapter;
private AutoCompleteTextView mAutocompleteView;
private TextView mPlaceDetailsText;
private TextView mPlaceDetailsAttribution;
Toolbar toolbar;
private static final LatLngBounds BOUNDS_GREATER_SYDNEY = new LatLngBounds(
// new LatLng(-34.041458, 150.790100), new LatLng(-33.682247, 151.383362));
new LatLng(0, 0), new LatLng(0, 0));
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// Construct a GoogleApiClient for the {@link Places#GEO_DATA_API} using AutoManage
// functionality, which automatically sets up the API client to handle Activity lifecycle
// events. If your activity does not extend FragmentActivity, make sure to call connect()
// and disconnect() explicitly.
mGoogleApiClient = new GoogleApiClient.Builder(this)
.enableAutoManage(this, 0 /* clientId */, this)
.addApi(Places.GEO_DATA_API)
.build();
setContentView(R.layout.activity_search_places);
//Set toolbar
toolbar = (Toolbar) findViewById(R.id.maintoolbar);
toolbar.setTitle("Change Location");
toolbar.setTitleTextColor(0xFFFFFFFF);
setSupportActionBar(toolbar);
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
getSupportActionBar().setHomeButtonEnabled(false);
// Retrieve the AutoCompleteTextView that will display Place suggestions.
mAutocompleteView = (AutoCompleteTextView) findViewById(R.id.autocomplete_places);
// Register a listener that receives callbacks when a suggestion has been selected
mAutocompleteView.setOnItemClickListener(mAutocompleteClickListener);
// Retrieve the TextViews that will display details and attributions of the selected place.
mPlaceDetailsText = (TextView) findViewById(R.id.place_details);
mPlaceDetailsAttribution = (TextView) findViewById(R.id.place_attribution);
// Set up the adapter that will retrieve suggestions from the Places Geo Data API that cover
// the entire world.
mAdapter = new PlaceAutocompleteAdapter(this, mGoogleApiClient, BOUNDS_GREATER_SYDNEY,
null);
mAutocompleteView.setAdapter(mAdapter);
// Set up the 'clear text' button that clears the text in the autocomplete view
Button clearButton = (Button) findViewById(R.id.button_clear);
clearButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
mAutocompleteView.setText("");
}
});
}
/**
* Listener that handles selections from suggestions from the AutoCompleteTextView that
* displays Place suggestions.
* Gets the place id of the selected item and issues a request to the Places Geo Data API
* to retrieve more details about the place.
*
* @see com.google.android.gms.location.places.GeoDataApi#getPlaceById(GoogleApiClient,
* String...)
*/
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.getPrimaryText(null);
AppLog.i("Search", "Autocomplete item selected: " + primaryText);
/*
Issue a request to the Places Geo Data API to retrieve a Place object with additional
details about the place.
*/
PendingResult<PlaceBuffer> placeResult = Places.GeoDataApi
.getPlaceById(mGoogleApiClient, placeId);
placeResult.setResultCallback(mUpdatePlaceDetailsCallback);
/*Toast.makeText(getApplicationContext(), "Clicked: " + primaryText,
Toast.LENGTH_SHORT).show();*/
AppLog.i("Search", "Called getPlaceById to get Place details for " + placeId);
}
};
/**
* Callback for results from a Places Geo Data API query that shows the first place result in
* the details view on screen.
*/
private ResultCallback<PlaceBuffer> mUpdatePlaceDetailsCallback
= new ResultCallback<PlaceBuffer>() {
@Override
public void onResult(PlaceBuffer places) {
if (!places.getStatus().isSuccess()) {
// Request did not complete successfully
AppLog.e("Search", "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);
// Format details of the place for display and show it in a TextView.
/* mPlaceDetailsText.setText(formatPlaceDetails(getResources(), place.getName(),
place.getId(), place.getAddress(), place.getPhoneNumber(),
place.getWebsiteUri(),place.getLatLng()));*/
AppLog.e("LAtlng", ">>>>>>>>>>>>" + place.getLatLng());
LatLng latLng = place.getLatLng();
double lat = latLng.latitude;
double lng = latLng.longitude;
SearchFood.searchresult = place.getName().toString() + "," + place.getAddress().toString();
SearchActivity.searchresult = place.getName().toString() + "," + place.getAddress().toString();
onBackPressed();
places.release();
}
};
private static Spanned formatPlaceDetails(Resources res, CharSequence name, String id,
CharSequence address, CharSequence phoneNumber, Uri websiteUri, LatLng latLng) {
AppLog.e("Search", 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));
}
/**
* Called when the Activity could not connect to Google Play services and the auto manager
* could resolve the error automatically.
* In this case the API is not available and notify the user.
*
* @param connectionResult can be inspected to determine the cause of the failure
*/
@Override
public void onConnectionFailed(ConnectionResult connectionResult) {
AppLog.e("Search", "onConnectionFailed: ConnectionResult.getErrorCode() = "
+ connectionResult.getErrorCode());
// TODO(Developer): Check error code and notify the user of error state and resolution.
/* Toast.makeText(this,
"Could not connect to Google API Client: Error " + connectionResult.getErrorCode(),
Toast.LENGTH_SHORT).show();*/
}
@Override
public void onBackPressed() {
super.onBackPressed();
SearchPlacesActivity.this.finish();
overridePendingTransition(R.anim.trans_right_in, R.anim.trans_right_out);
}
@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();
//noinspection SimplifiableIfStatement
if (id == android.R.id.home) {
onBackPressed();
}
return super.onOptionsItemSelected(item);
}
}
// ADAPTER CLASS
import android.content.Context;
import android.graphics.Typeface;
import android.text.style.CharacterStyle;
import android.text.style.StyleSpan;
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 com.eatcommunity.util.AppLog;
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 java.util.ArrayList;
import java.util.concurrent.TimeUnit;
public class PlaceAutocompleteAdapter
extends ArrayAdapter<AutocompletePrediction> implements Filterable {
private static final String TAG = "PlaceAutocompleteAdapter";
private static final CharacterStyle STYLE_BOLD = new StyleSpan(Typeface.BOLD);
/**
* Current results returned by this adapter.
*/
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, android.R.layout.simple_expandable_list_item_2, android.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);
// 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.getPrimaryText(STYLE_BOLD));
textView2.setText(item.getSecondaryText(STYLE_BOLD));
return row;
}
@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).getFullText(null);
} else {
return super.convertResultToString(resultValue);
}
}
};
}
private ArrayList<AutocompletePrediction> getAutocomplete(CharSequence constraint) {
if (mGoogleApiClient.isConnected()) {
AppLog.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);
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();*/
AppLog.e(TAG, "Error getting autocomplete prediction API call: " + status.toString());
autocompletePredictions.release();
return null;
}
return DataBufferUtils.freezeAndClose(autocompletePredictions);
}
AppLog.e(TAG, "Google API client is not connected for autocomplete query.");
return null;
}
}
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">
<LinearLayout
android:id="@+id/container_toolbar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<include
android:id="@+id/maintoolbar"
layout="@layout/application_toolbar" />
</LinearLayout>
<ScrollView
android:id="@+id/scrollView"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_below="@+id/container_toolbar">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:paddingBottom="@dimen/activity_vertical_margin"
android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
android:text="Search Places"
android:textAppearance="? android:attr/textAppearanceMedium" />
<AutoCompleteTextView
android:id="@+id/autocomplete_places"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
android:hint="Enter your place"
android:singleLine="true" />
<ImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="right"
android:src="@drawable/powered_by_google_light"
android:visibility="gone" />
<Button
android:id="@+id/button_clear"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
android:text="Clear text" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Selelcted Place"
android:textAppearance="?android:attr/textAppearanceMedium"
android:visibility="gone" />
<TextView
android:id="@+id/place_details"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:autoLink="all"
android:text=""
android:textAppearance="? android:attr/textAppearanceMedium" />
<TextView
android:id="@+id/place_attribution"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:autoLink="all"
android:paddingTop="@dimen/activity_vertical_margin"
android:text=""
android:textAppearance="?android:attr/textAppearanceSmall" />
</LinearLayout>
</ScrollView>
</RelativeLayout>
Menifest File change
<meta-data
android:name="com.google.android.geo.API_KEY"
android:value="YOURAPIKEY" />
<meta-data
android:name="com.google.android.gms.version"
android:value="@integer/google_play_services_version" />
链接地址: http://www.djcxy.com/p/88495.html
上一篇: Google places autocompletes API Android : bounds not working