我正面临在我的项目中使用Google Map and Place的问题。我已经尝试了几天寻找最佳解决方案,但我还没有。
我想使用Goolge map和Place API。我的目标是当我将餐厅位置输入到EditText搜索自动完成时,谷歌地图将识别此位置,并通过标记显示附近的其他餐馆。
那么,我可以使用谷歌地图和地方来实现并使用json来管理标记吗?
我知道Google服务数据库已经申请了用户,但是有太多的标记,我无法创建新的和手动的
我已经参考了这个链接:
https://mapmaker.google.com/mapmaker
但它不能满足我的要求
谢谢!
答案 0 :(得分:0)
代码有点冗长但不难实现
从地图片段开始放置片段.....
Fragment fragmentObject = new AutoCompletePlacesFragment();
Bundle args = new Bundle(2);
args.putInt("userID", preferedUserId);
args.putString("passengerGcm", preferedPassengerGcm);
fragmentObject.setArguments(args);
android.support.v4.app.FragmentManager fm = getFragmentManager();
fm.beginTransaction()
.replace(R.id.container, fragmentObject)
.commit();
这是一个名为AutoCompletePlacesFragment.java的placefragment(在你找到这条线的地方管理你的东西* //点击这里的东西点击...... *)
public class AutoCompletePlacesFragment extends Fragment实现了GoogleApiClient.ConnectionCallbacks,GoogleApiClient.OnConnectionFailedListener,View.OnClickListener {
private static final LatLngBounds BOUND = new LatLngBounds(new LatLng(-0,0),new LatLng(0,0));
私人EditText mAutocompleteView; private RecyclerView mRecyclerView; private LinearLayoutManager mLinearLayoutManager; private PlacesAutoCompleteAdapter mAutoCompleteAdapter; ImageView删除; GoogleApiClient mGoogleApiClient;
查看RootView;
int preferedUserId; String preferedPassengerGcm; PreferenceData preferenceData;
public AutoCompletePlacesFragment(){//必需的空公共构造函数}
@Override public void onCreate(Bundle savedInstanceState){}
@Override public View onCreateView(LayoutInflater inflater,ViewGroup container,Bundle savedInstanceState){//为此片段buildGoogleApiClient()扩展布局; RootView = inflater.inflate(R.layout.fragment_auto_complete_places,container,false);
mAutocompleteView = (EditText) RootView.findViewById(R.id.autocomplete_places);
mAutocompleteView.setOnClickListener(this);
delete=(ImageView) RootView.findViewById(R.id.cross);
mAutoCompleteAdapter = new PlacesAutoCompleteAdapter(RootView.getContext(), R.layout.searchview_adapter,
mGoogleApiClient, BOUND, null);
mRecyclerView=(RecyclerView) RootView.findViewById(R.id.recyclerView);
mLinearLayoutManager=new LinearLayoutManager(RootView.getContext());
mRecyclerView.setLayoutManager(mLinearLayoutManager);
mRecyclerView.setAdapter(mAutoCompleteAdapter);
delete.setOnClickListener(this);
mAutocompleteView.addTextChangedListener(new TextWatcher() {
public void onTextChanged(CharSequence s, int start, int before,
int count) {
if (!s.toString().equals("") && mGoogleApiClient.isConnected()) {
mAutoCompleteAdapter.getFilter().filter(s.toString());
} else if (!mGoogleApiClient.isConnected()) {
Toast.makeText(RootView.getContext(), getResources().getString(R.string.internet_error), Toast.LENGTH_SHORT).show();
// Log.e(Constants.PlacesTag,getResources().getString(R.string.internet_error));
}
}
public void beforeTextChanged(CharSequence s, int start, int count,
int after) {
}
public void afterTextChanged(Editable s) {
}
});
mRecyclerView.addOnItemTouchListener(
new AutoCompleteItemClickListener(this, new AutoCompleteItemClickListener.OnItemClickListener() {
@Override
public void onItemClick(View view, int position) {
final PlacesAutoCompleteAdapter.PlaceAutocomplete item = mAutoCompleteAdapter.getItem(position);
final String placeId = String.valueOf(item.placeId);
Log.i("TAG", "Autocomplete item selected: " + item.description);
/*
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(new ResultCallback<PlaceBuffer>() {
@Override
public void onResult(PlaceBuffer places) {
if (!places.getStatus().isSuccess()) {
// Request did not complete successfully
places.release();
return;
}
if (places.getCount() == 1) {
//Do the things here on Click.....
Toast.makeText(RootView.getContext(), String.valueOf(places.get(0).getLatLng()), Toast.LENGTH_SHORT).show();
Fragment fragmentObject = new PassengerFragmentMap();
Bundle args = new Bundle(5);
args.putString("destination",item.description.toString());
args.putDouble("destLat", places.get(0).getLatLng().latitude);
args.putDouble("destLong",places.get(0).getLatLng().longitude);
fragmentObject.setArguments(args);
preferenceData.setCurrentCabRequestDestinationPreferences(item.description.toString());
android.support.v4.app.FragmentManager fm = getFragmentManager();
if(fm!=null) {
fm.beginTransaction()
.replace(R.id.container, fragmentObject)
.commit();
}
} else {
Toast.makeText(RootView.getContext(), getResources().getString(R.string.internet_error), Toast.LENGTH_SHORT).show();
}
}
});
Log.i("TAG", "Clicked: " + item.description);
Log.i("TAG", "Called getPlaceById to get Place details for " + item.placeId);
}
})
);
return RootView;
}
// TODO: Rename method, update argument and hook method into UI event
public void onButtonPressed(Uri uri) {
}
@Override
public void onAttach(Context context) {
super.onAttach(context);
}
@Override
public void onDetach() {
super.onDetach();
}
public interface OnFragmentInteractionListener {
// TODO: Update argument type and name
void onFragmentInteraction(Uri uri);
}
protected synchronized void buildGoogleApiClient() {
mGoogleApiClient = new GoogleApiClient.Builder(getActivity())
.addConnectionCallbacks(this)
.addOnConnectionFailedListener(this)
.addApi(LocationServices.API)
.addApi(Places.GEO_DATA_API)
.build();
}
@Override
public void onConnected(Bundle bundle) {
Log.v("Google API Callback", "Connection Done");
}
@Override
public void onConnectionSuspended(int i) {
Log.v("Google API Callback", "Connection Suspended");
Log.v("Code", String.valueOf(i));
}
@Override
public void onConnectionFailed(ConnectionResult connectionResult) {
Log.v("Google API Callback","Connection Failed");
Log.v("Error Code", String.valueOf(connectionResult.getErrorCode()));
Toast.makeText(getActivity(), getResources().getString(R.string.internet_error),Toast.LENGTH_SHORT).show();
}
@Override
public void onClick(View v) {
if(v==delete){
mAutocompleteView.setText("");
}
}
@Override
public void onResume() {
super.onResume();
if (!mGoogleApiClient.isConnected() && !mGoogleApiClient.isConnecting()){
Log.v("Google API","Connecting");
mGoogleApiClient.connect();
}
}
public void onLocationSelected(){
}
}
这是PlacesAutoCompleteAdapter.java(只需复制粘贴,无需更改)
public class PlacesAutoCompleteAdapter
extends RecyclerView.Adapter<PlacesAutoCompleteAdapter.PredictionHolder> implements Filterable {
private static final String TAG = "PlacesAutoCompleteAdapter";
private ArrayList<PlaceAutocomplete> mResultList;
private GoogleApiClient mGoogleApiClient;
private LatLngBounds mBounds;
private AutocompleteFilter mPlaceFilter;
private Context mContext;
private int layout;
public PlacesAutoCompleteAdapter(Context context, int resource, GoogleApiClient googleApiClient,
LatLngBounds bounds, AutocompleteFilter filter) {
mContext = context;
layout = resource;
mGoogleApiClient = googleApiClient;
mBounds = bounds;
mPlaceFilter = filter;
}
/**
* Sets the bounds for all subsequent queries.
*/
public void setBounds(LatLngBounds bounds) {
mBounds = bounds;
}
/**
* 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.
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();
}
}
};
return filter;
}
private ArrayList<PlaceAutocomplete> getAutocomplete(CharSequence constraint) {
if (mGoogleApiClient.isConnected()) {
Log.i("", "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(mContext, "Error contacting API: " + status.toString(),
Toast.LENGTH_SHORT).show();
Log.e("", "Error getting autocomplete prediction API call: " + status.toString());
autocompletePredictions.release();
return null;
}
Log.i("", "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.getDescription()));
}
// Release the buffer now that all data has been copied.
autocompletePredictions.release();
return resultList;
}
Log.e("", "Google API client is not connected for autocomplete query.");
return null;
}
@Override
public PredictionHolder onCreateViewHolder(ViewGroup viewGroup, int i) {
LayoutInflater layoutInflater = (LayoutInflater) mContext.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
View convertView = layoutInflater.inflate(layout, viewGroup, false);
PredictionHolder mPredictionHolder = new PredictionHolder(convertView);
return mPredictionHolder;
}
@Override
public void onBindViewHolder(PredictionHolder mPredictionHolder, final int i) {
mPredictionHolder.mPrediction.setText(mResultList.get(i).description);
/*mPredictionHolder.mRow.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
mGetLatLonCallback.getLocation(resultList.get(i).toString());
}
});*/
}
@Override
public int getItemCount() {
if(mResultList != null)
return mResultList.size();
else
return 0;
}
public PlaceAutocomplete getItem(int position) {
return mResultList.get(position);
}
public class PredictionHolder extends RecyclerView.ViewHolder {
private TextView mPrediction;
private RelativeLayout mRow;
public PredictionHolder(View itemView) {
super(itemView);
mPrediction = (TextView) itemView.findViewById(R.id.address);
mRow=(RelativeLayout)itemView.findViewById(R.id.predictedRow);
}
}
/**
* 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();
}
}
}
这是AutoCompleteItemClickListener.java(只需复制粘贴,无需更改)
public class AutoCompleteItemClickListener implements RecyclerView.OnItemTouchListener {
private OnItemClickListener mListener;
public interface OnItemClickListener {
public void onItemClick(View view, int position);
}
GestureDetector mGestureDetector;
public AutoCompleteItemClickListener(AutoCompletePlacesFragment context, OnItemClickListener listener) {
mListener = listener;
mGestureDetector = new GestureDetector(context.getActivity(), new GestureDetector.SimpleOnGestureListener() {
@Override
public boolean onSingleTapUp(MotionEvent e) {
return true;
}
});
}
@Override
public boolean onInterceptTouchEvent(RecyclerView view, MotionEvent e) {
View childView = view.findChildViewUnder(e.getX(), e.getY());
if (childView != null && mListener != null && mGestureDetector.onTouchEvent(e)) {
mListener.onItemClick(childView, view.getChildLayoutPosition(childView));
return true;
}
return false;
}
@Override
public void onTouchEvent(RecyclerView view, MotionEvent motionEvent) { }
@Override
public void onRequestDisallowInterceptTouchEvent(boolean disallowIntercept) {
}
}