我是Android开发的先驱。
我正在努力自动完成用户输入。我需要谷歌地图,如自动完成用户输入。用户需要选择地址,地点,街道a.s.o.从汽车完成,我需要它的LatLong。
我试图通过使用谷歌cource来完成这项工作,但这不是我想要的。我不想要一个完整的片段或仅用于选择一个地方的东西,我正在寻找AutoCompleteTextView
解决方案。有这么容易理解的方法吗?
我找到了this,但这看起来不像是“正常方式”,或者我错了?这是一个Web API调用而不是Android API调用不是吗?
-------------------------------- UPDATE ----------- ------------------
我的清单:
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="aaeu.app">
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="com.google.android.providers.gsf.permission.READ_GSERVICES"/>
<uses-library android:name="com.google.android.maps" />
<application
android:name="com.activeandroid.app.Application"
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:supportsRtl="true"
android:theme="@style/AppTheme">
<activity android:name=".presentationlayer.MainActivity"
android:screenOrientation="portrait">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<activity android:name=".presentationlayer.AlertDetailActivity"
android:screenOrientation="portrait"/>
<meta-data
android:name="AA_DB_NAME"
android:value="local_test_db.db" />
<meta-data
android:name="AA_DB_VERSION"
android:value="9" />
<meta-data
android:name="AA_MODELS"
android:value="aaeu.app.datalayer.Alert , aaeu.app.datalayer.Area" />
<meta-data
android:name="com.google.android.maps.v2.API_KEY"
android:value="XXXXXXBsWU9seEWmlB-CMc_pxZ358b4-esTNR5I" />
<!-- without this meta-data below the app don't crash but sais API key wrong -->
<meta-data
android:name="com.google.android.geo.API_KEY"
android:value="XXXXXXBsWU9seEWmlB-CMc_pxZ358b4-esTNR5I" />
<meta-data
android:name="com.google.android.gms.version"
android:value="@integer/google_play_services_version"/>
</application>
</manifest>
答案 0 :(得分:7)
使用此选项可创建自定义位置建议并处理数据。以下是在AutoCompleteTextView
public class MainActivity extends AppCompatActivity implements
GoogleApiClient.OnConnectionFailedListener,
GoogleApiClient.ConnectionCallbacks {
private static final String LOG_TAG = "MainActivity";
private static final int GOOGLE_API_CLIENT_ID = 0;
private AutoCompleteTextView mAutocompleteTextView;
private TextView mNameTextView;
private TextView mAddressTextView;
private TextView mIdTextView;
private TextView mPhoneTextView;
private TextView mWebTextView;
private TextView mAttTextView;
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));
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mGoogleApiClient = new GoogleApiClient.Builder(MainActivity.this)
.addApi(Places.GEO_DATA_API)
.enableAutoManage(this, GOOGLE_API_CLIENT_ID, this)
.addConnectionCallbacks(this)
.build();
mAutocompleteTextView = (AutoCompleteTextView) findViewById(R.id
.autoCompleteTextView);
mAutocompleteTextView.setThreshold(3);
mNameTextView = (TextView) findViewById(R.id.name);
mAddressTextView = (TextView) findViewById(R.id.address);
mIdTextView = (TextView) findViewById(R.id.place_id);
mPhoneTextView = (TextView) findViewById(R.id.phone);
mWebTextView = (TextView) findViewById(R.id.web);
mAttTextView = (TextView) findViewById(R.id.att);
mAutocompleteTextView.setOnItemClickListener(mAutocompleteClickListener);
mPlaceArrayAdapter = new PlaceArrayAdapter(this, android.R.layout.simple_list_item_1,
BOUNDS_MOUNTAIN_VIEW, null);
mAutocompleteTextView.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);
final String placeId = String.valueOf(item.placeId);
Log.i(LOG_TAG, "Selected: " + item.description);
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.e(LOG_TAG, "Place query did not complete. Error: " +
places.getStatus().toString());
return;
}
// Selecting the first object buffer.
final Place place = places.get(0);
CharSequence attributions = places.getAttributions();
mNameTextView.setText(Html.fromHtml(place.getName() + ""));
mAddressTextView.setText(Html.fromHtml(place.getAddress() + ""));
mIdTextView.setText(Html.fromHtml(place.getId() + ""));
mPhoneTextView.setText(Html.fromHtml(place.getPhoneNumber() + ""));
mWebTextView.setText(place.getWebsiteUri() + "");
if (attributions != null) {
mAttTextView.setText(Html.fromHtml(attributions.toString()));
}
}
};
@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.");
}
}
所需的过滤器适配器可根据需要定制,如下所示
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();
}
}
}
通过以下链接解释每一行
答案 1 :(得分:2)
只是坚持谷歌的地方自动完成只要你想要它像AutoCompleteTextView.its MODE_OVERLAY选项那样做。
Intent intent = new PlaceAutocomplete.IntentBuilder(PlaceAutocomplete.MODE_OVERLAY)
.build(mActivity);
startActivityForResult(intent, REQUEST_CODE_AUTOCOMPLETE);
答案 2 :(得分:-1)
Android版Places SDK的Google Play服务版本(在Google Play服务16.0.0中)自2019年1月29日起弃用,并将于2019年7月29日关闭。
Now how we use the **Sreehari** answers with new modifications?
如果有人知道解决方案,请告诉我。目前我使用的是android自动完成功能 搜索过程。但仍在努力将旧的自动填充地点搜索迁移到新地点。