我正在尝试创建一个可以找到附近地方的应用。我想使用官方的Android API,但我找不到任何好的例子来学习。
我见过很多例子,但他们都使用的是Web版本,而不是Android API。谷歌的网站guides是如此蹩脚,唯一的指导是关于获得你的实际位置,我不能让它工作。我想,没有人使用这个API?
我已经获得了API_KEY,但我不知道下一步该怎么做
答案 0 :(得分:1)
使用以下代码。
PickLocation.java
import android.support.v4.app.FragmentActivity;
import android.os.Bundle;
import com.google.android.gms.maps.CameraUpdateFactory;
import com.google.android.gms.maps.GoogleMap;
import com.google.android.gms.maps.OnMapReadyCallback;
import com.google.android.gms.maps.SupportMapFragment;
import com.google.android.gms.maps.model.LatLng;
import com.google.android.gms.maps.model.MarkerOptions;
import grocery.srs.info.srsgrocery_v1.R;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.text.Html;
import android.util.Log;
import android.view.View;
import android.view.WindowManager;
import android.widget.AdapterView;
import android.widget.AutoCompleteTextView;
import android.widget.TextView;
import android.widget.Toast;
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.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;
import grocery.srs.info.srsgrocery_v1.adapter.PlaceArrayAdapter;
public class PickLocation 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.pick_location);
getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,
WindowManager.LayoutParams.FLAG_FULLSCREEN);
mGoogleApiClient = new GoogleApiClient.Builder(PickLocation.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.");
}
}
pick_location.xml
android:layout_width="match_parent"
android:layout_height="match_parent">
<AutoCompleteTextView
android:id="@+id/autoCompleteTextView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentEnd="true"
android:layout_alignParentLeft="true"
android:layout_alignParentRight="true"
android:layout_alignParentStart="true"
android:layout_alignParentTop="true"
android:hint="Enter Place Here"/>
<LinearLayout
android:id="@+id/mylocation_layout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="@+id/autoCompleteTextView"
android:background="@color/border">
<Button
android:id="@+id/btn_use_my_location"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:layout_alignParentStart="true"
android:layout_below="@+id/location_searchView"
android:layout_margin="5dp"
android:background="#FFF"
android:drawableLeft="@mipmap/location"
android:gravity="center_vertical"
android:text="Use My Location"
android:textColor="@color/border" />
</LinearLayout>
</RelativeLayout>
PlaceArrayAdapter.java
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;
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;
}
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();
}
}
}