Я пытаюсь создать карту с виджетами PlaceAutocomplete, наложенными на него. Функция этого представления заключается в вычислении расстояния от моего текущего местоположения до местоположения, которое я выбрал в виджета PlaceAutocomplete.PlaceAutocomplete Widget on MapView Fragment
Чтобы объяснить себя лучше, мне нужен такой же фрагмент, как и в приложении Google Maps. Пока я создал фрагмент, который отображает карту. Этот вид затем накладывается виджлом PlaceAutocomplete.
В настоящее время я могу получить свое текущее местоположение, когда я начинаю просмотр карты. (снимок экрана 1) Однако, когда я пытаюсь найти место назначения (снимок экрана 2), виджет просто показывает выбранный вами пункт назначения, не вызывая API Google Directions API, чтобы получить маршрут маршрута от моего местоположения до места назначения. (скриншот 3)
Из моего логарифма я вижу, что метод создания URL-адреса и вызова API Google Directions API даже не вызывается.
Вот мой код:
public class GeoFragment extends Fragment implements PlaceSelectionListener, GoogleApiClient.ConnectionCallbacks, GoogleApiClient.OnConnectionFailedListener, LocationListener {
GoogleMap map;
SupportMapFragment mapFragment;
private LocationRequest lr;
private GoogleApiClient apiClient;
private static View view;
private Location location;
int PLACE_AUTOCOMPLETE_REQUEST_CODE = 1;
int RESULT_OK = 2;
int RESULT_CANCELED = 3;
private final static int PLAY_SERVICES_RESOLUTION_REQUEST = 1000;
final String GOOGLE_KEY;
int PLACE_PICKER_REQUEST = 1;
double currentLatitude;
double currentLongitude;
SupportPlaceAutocompleteFragment searcher;
String placeString;
public GeoFragment() {
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
buildGoogleApiClient();
if (view != null) {
ViewGroup parent = (ViewGroup) view.getParent();
if (parent != null)
parent.removeView(view);
}
try {
view = inflater.inflate(R.layout.layout_map, container, false);
mapFragment = ((SupportMapFragment) this.getChildFragmentManager().findFragmentById(R.id.mapView));
searcher = (SupportPlaceAutocompleteFragment) this.getChildFragmentManager().findFragmentById(R.id.info_text);
//searcher.setBoundsBias(new LatLngBounds(new LatLng(), new LatLng()));
map = mapFragment.getMap();
map.getUiSettings().setAllGesturesEnabled(true);
map.getUiSettings().setMyLocationButtonEnabled(true);
map.setMyLocationEnabled(true);
map.getUiSettings().setZoomControlsEnabled(false);
map.animateCamera(CameraUpdateFactory.zoomIn());
map.animateCamera(CameraUpdateFactory.zoomTo(15), 2000, null);
map.moveCamera(CameraUpdateFactory.newLatLngZoom(new LatLng(currentLatitude, currentLongitude), 19));
MapsInitializer.initialize(this.getActivity());
} catch (InflateException e) {
Toast.makeText(getActivity(), "Problems inflating the view !",
Toast.LENGTH_LONG).show();
} catch (NullPointerException e) {
Log.e("GServices Error", e.toString());
}
return view;
}
protected synchronized void buildGoogleApiClient() {
apiClient = new GoogleApiClient.Builder(getActivity().getApplicationContext())
.addApi(LocationServices.API)
.addApi(Places.GEO_DATA_API)
.addApi(Places.PLACE_DETECTION_API)
.addConnectionCallbacks(this)
.addOnConnectionFailedListener(this)
.build();
}
private boolean checkPlayServices() {
int resultCode = GooglePlayServicesUtil
.isGooglePlayServicesAvailable(getActivity().getApplicationContext());
if (resultCode != ConnectionResult.SUCCESS) {
if (GooglePlayServicesUtil.isUserRecoverableError(resultCode)) {
GooglePlayServicesUtil.getErrorDialog(resultCode, getActivity(), PLAY_SERVICES_RESOLUTION_REQUEST).show();
}
return false;
}
return true;
}
@Override
public void onStart() {
super.onStart();
if (apiClient != null) {
apiClient.connect();
}
}
@Override
public void onStop() {
super.onStop();
if (apiClient.isConnected()) {
apiClient.disconnect();
}
}
@Override
public void onPause() {
super.onPause();
stopLocationUpdates();
}
@Override
public void onResume() {
super.onResume();
checkPlayServices();
// Resuming the periodic location updates
if (apiClient.isConnected()) {
startLocationUpdates();
}
}
protected void startLocationUpdates() {
LocationServices.FusedLocationApi.requestLocationUpdates(
apiClient, lr, this);
}
protected void stopLocationUpdates() {
LocationServices.FusedLocationApi.removeLocationUpdates(
apiClient, this);
}
public void getCoordinates(){
location = LocationServices.FusedLocationApi.getLastLocation(apiClient);
if (location != null) {
currentLatitude = location.getLatitude();
currentLongitude = location.getLongitude();
}
}
@Override
public void onLocationChanged(Location loc) {
location = loc;
getCoordinates();
map.moveCamera(CameraUpdateFactory.newLatLngZoom(new LatLng(currentLatitude, currentLongitude), 19));
}
@Override
public void onConnected(Bundle connectionHint) {
if (location == null) {
lr = LocationRequest.create();
lr.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);
lr.setInterval(1000);
LocationServices.FusedLocationApi.requestLocationUpdates(apiClient, lr, this);
}
//getCoordinates();
}
@Override
public void onConnectionFailed(ConnectionResult result) {
Log.i("Map Connection Failed", "Connection failed: ConnectionResult.getErrorCode() = "
+ result.getErrorCode());
}
public void onConnectionSuspended(int arg0) {
apiClient.connect();
}
public void SearchPlace(String place) throws GooglePlayServicesNotAvailableException, GooglePlayServicesRepairableException {
PlacePicker.IntentBuilder builder = new PlacePicker.IntentBuilder();
startActivityForResult(builder.build(getActivity()), PLACE_PICKER_REQUEST);
callPlaces(currentLongitude, currentLatitude, place);
}
public void callPlaces(final double longitude, final double latitude, final String destination) {
String tag_string_req = "req_places";
String url = "https://maps.googleapis.com/maps/api/directions/json?origin=" + latitude + "," + longitude + "&destination="+ destination +"&alternatives=true&mode=transit®ion=mt&key=" + getResources().getString(R.string.google_places_key);
StringRequest strReq = new StringRequest(Request.Method.GET, url, new Response.Listener<String>() {
@Override
public void onResponse(String response) {
drawPath(response);
}
}, new Response.ErrorListener() {
@Override
public void onErrorResponse(VolleyError error) {
Log.e("Error", "Registration Error: " + error.getMessage());
Toast.makeText(getActivity().getApplicationContext(),
error.getMessage(), Toast.LENGTH_LONG).show();
}
});
AppController.getInstance().addToRequestQueue(strReq);
}
public void drawPath(String result){
try {
final JSONObject jsonObject = new JSONObject(result);
JSONArray routeArray = jsonObject.getJSONArray("routes");
JSONObject routes = routeArray.getJSONObject(0);
JSONObject overviewPolylines = routes.getJSONObject("overview_polyline");
String encodedString = overviewPolylines.getString("points");
String statusString = jsonObject.getString("status");
Log.d("test: ", encodedString);
List<LatLng> list = decodePoly(encodedString);
LatLng last = null;
for (int i = 0; i < list.size()-1; i++) {
LatLng src = list.get(i);
LatLng dest = list.get(i+1);
last = dest;
Log.d("Last latLng:", last.latitude + ", " + last.longitude);
Polyline line = map.addPolyline(new PolylineOptions()
.add(new LatLng(src.latitude, src.longitude), new LatLng(dest.latitude, dest.longitude))
.width(4)
.color(Color.GREEN));
}
Log.d("Last latLng:", last.latitude + ", " + last.longitude);
}catch (JSONException e){
e.printStackTrace();
}
catch(ArrayIndexOutOfBoundsException e) {
System.err.println("Caught ArrayIndexOutOfBoundsException: "+ e.getMessage());
}
}
private List<LatLng> decodePoly(String encoded){
List<LatLng> poly = new ArrayList<LatLng>();
int index = 0;
int length = encoded.length();
int latitude = 0;
int longitude = 0;
while(index < length){
int b;
int shift = 0;
int result = 0;
do {
b = encoded.charAt(index++) - 63;
result |= (b & 0x1f) << shift;
shift += 5;
} while (b >= 0x20);
int destLat = ((result & 1) != 0 ? ~(result >> 1) : (result >> 1));
latitude += destLat;
shift = 0;
result = 0;
do {
b = encoded.charAt(index++) - 63;
result |= (b & 0x1f) << shift;
shift += 5;
} while (b > 0x20);
int destLong = ((result & 1) != 0 ? ~(result >> 1) : (result >> 1));
longitude += destLong;
poly.add(new LatLng((latitude/1E5),(longitude/1E5)));
}
return poly;
}
@Override
public void onPlaceSelected(Place place) {
Log.i("Destination", "Place Selected: " + place.getName());
placeString = place.getName().toString();
CharSequence attributions = place.getAttributions();
if (!TextUtils.isEmpty(attributions)) {
try {
SearchPlace(placeString);
} catch (GooglePlayServicesNotAvailableException e) {
e.printStackTrace();
} catch (GooglePlayServicesRepairableException e) {
e.printStackTrace();
}
} else {
searcher.setText("Where shall we take you today?");
}
}
@Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
searcher.onActivityResult(requestCode, resultCode, data);
}
@Override
public void onError(Status status) {
Log.e("TAG", "onError: Status = " + status.toString());
}
}
Может кто-то пожалуйста, помогите мне с этим вопросом?
Любая помощь приветствуется :)
Edit: Этот фрагмент является частью вкладками приложения, так что я не могу использовать активность вместо фрагмент. Поэтому в фрагменте необходимо создать вид mapview и PlaceAutocomplete Widget. Я также хотел бы, чтобы виджет PlaceAutocomplete накладывал карту. Я нашел обучающие программы с виджетами PlaceAutocomplete в отдельном упражнении. Это не то решение, которое я ищу.