Buscar ruta con Androids API de Google Maps

Quiero poder mostrar la ruta entre dos puntos geográficos definidos por el usuario utilizando la API de Google Maps para Android. También quiero ser capaz de permitir que el usuario elija qué tipo de ruta para mostrar, ya sea a pie, en bicicleta, coche, etc Además, quiero ser capaz de calcular el tiempo y la distancia que tomaría para utilizar esta ruta. He intentado buscar en la web y buscar otras preguntas stackoverflow, pero no sirvió. ¿Cómo iba a hacer esto? ¿Cómo podría ser capaz de codificar esto.

//—-EDITAR—-//

También me gustaría obtener información de tráfico, como rutas ocupadas, congestión, etc.

3 Solutions collect form web for “Buscar ruta con Androids API de Google Maps”

Código de ejemplo de enrutamiento de Google Maps para Android usando la biblioteca de Wrapper

Utilizar la entrada Gradle de Android Studio:

compile 'com.github.jd-alexander:library:1.1.0' 

MainActivity.java

 import android.Manifest; import android.content.pm.PackageManager; import android.graphics.Color; import android.location.Location; import android.location.LocationListener; import android.location.LocationManager; import android.support.design.widget.FloatingActionButton; import android.support.design.widget.Snackbar; import android.support.v4.app.ActivityCompat; import android.support.v4.app.FragmentActivity; import android.os.Bundle; import android.view.View; import android.widget.TextView; import android.widget.Toast; import com.directions.route.Route; import com.directions.route.RouteException; import com.directions.route.Routing; import com.directions.route.RoutingListener; 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.LatLngBounds; import com.google.android.gms.maps.model.Marker; import com.google.android.gms.maps.model.MarkerOptions; import com.google.android.gms.maps.model.Polyline; import com.google.android.gms.maps.model.PolylineOptions; import java.util.ArrayList; import java.util.Iterator; import java.util.List; public class MainActivity extends FragmentActivity implements OnMapReadyCallback, LocationListener, GoogleMap.OnMarkerClickListener, RoutingListener { private GoogleMap mMap = null; private LocationManager locationManager = null; private FloatingActionButton fab = null; private TextView txtDistance, txtTime; //Global UI Map markers private Marker currentMarker = null; private Marker destMarker = null; private LatLng currentLatLng = null; private Polyline line = null; //Global flags private boolean firstRefresh = true; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_map); Constants.POINT_DEST = new LatLng(18.758663, 73.382025); //Lonavala destination. //Load the map fragment on UI SupportMapFragment mapFragment = (SupportMapFragment) getSupportFragmentManager().findFragmentById(R.id.map); mapFragment.getMapAsync(this); txtDistance = (TextView)findViewById(R.id.txt_distance); txtTime = (TextView)findViewById(R.id.txt_time); fab = (FloatingActionButton)findViewById(R.id.fab); fab.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { MainActivity.this.getRoutingPath(); Snackbar.make(v, "Fetching Route", Snackbar.LENGTH_SHORT).show(); } }); } @Override protected void onResume() { super.onResume(); firstRefresh = true; //Ensure the GPS is ON and location permission enabled for the application. locationManager = (LocationManager) getSystemService(LOCATION_SERVICE); if (!PermissionCheck.getInstance().checkGPSPermission(this, locationManager)) { //GPS not enabled for the application. } else if (!PermissionCheck.getInstance().checkLocationPermission(this)) { //Location permission not given. } else { Toast.makeText(MainActivity.this, "Fetching Location", Toast.LENGTH_SHORT).show(); try { locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 0, 0, this); locationManager.requestLocationUpdates(LocationManager.NETWORK_PROVIDER, 5000, 0, this); } catch(Exception e) { Toast.makeText(MainActivity.this, "ERROR: Cannot start location listener", Toast.LENGTH_SHORT).show(); } } } @Override protected void onPause() { if (locationManager != null) { //Check needed in case of API level 23. if (ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) { } try { locationManager.removeUpdates(this); } catch (Exception e) { } } locationManager = null; super.onPause(); } @Override protected void onStop() { super.onStop(); } @Override public void onMapReady(GoogleMap googleMap) { mMap = googleMap; //mMap.getUiSettings().setZoomControlsEnabled(true); mMap.getUiSettings().setCompassEnabled(true); mMap.getUiSettings().setAllGesturesEnabled(true); mMap.setOnMarkerClickListener(this); } /** * @desc LocationListener Interface Methods implemented. */ @Override public void onLocationChanged(Location location) { double lat = location.getLatitude(); double lng = location.getLongitude(); currentLatLng = new LatLng(lat, lng); if(firstRefresh) { //Add Start Marker. currentMarker = mMap.addMarker(new MarkerOptions().position(currentLatLng).title("Current Position"));//.icon(BitmapDescriptorFactory.fromResource(R.drawable.location))); firstRefresh = false; destMarker = mMap.addMarker(new MarkerOptions().position(Constants.POINT_DEST).title("Destination"));//.icon(BitmapDescriptorFactory.fromResource(R.drawable.location))); mMap.moveCamera(CameraUpdateFactory.newLatLng(Constants.POINT_DEST)); mMap.animateCamera(CameraUpdateFactory.zoomTo(15)); getRoutingPath(); } else { currentMarker.setPosition(currentLatLng); } } @Override public void onStatusChanged(String provider, int status, Bundle extras) {} @Override public void onProviderEnabled(String provider) {} @Override public void onProviderDisabled(String provider) {} /** * @desc MapMarker Interface Methods Implemented. */ @Override public boolean onMarkerClick(Marker marker) { if(marker.getTitle().contains("Destination")) { //Do some task on dest pin click } else if(marker.getTitle().contains("Current")) { //Do some task on current pin click } return false; } /** *@desc Routing Listener interface methods implemented. **/ @Override public void onRoutingFailure(RouteException e) { Toast.makeText(MainActivity.this, "Routing Failed", Toast.LENGTH_SHORT).show(); } @Override public void onRoutingStart() { } @Override public void onRoutingSuccess(ArrayList<Route> list, int i) { try { //Get all points and plot the polyLine route. List<LatLng> listPoints = list.get(0).getPoints(); PolylineOptions options = new PolylineOptions().width(5).color(Color.BLUE).geodesic(true); Iterator<LatLng> iterator = listPoints.iterator(); while(iterator.hasNext()) { LatLng data = iterator.next(); options.add(data); } //If line not null then remove old polyline routing. if(line != null) { line.remove(); } line = mMap.addPolyline(options); //Show distance and duration. txtDistance.setText("Distance: " + list.get(0).getDistanceText()); txtTime.setText("Duration: " + list.get(0).getDurationText()); //Focus on map bounds mMap.moveCamera(CameraUpdateFactory.newLatLng(list.get(0).getLatLgnBounds().getCenter())); LatLngBounds.Builder builder = new LatLngBounds.Builder(); builder.include(currentLatLng); builder.include(Constants.POINT_DEST); LatLngBounds bounds = builder.build(); mMap.animateCamera(CameraUpdateFactory.newLatLngBounds(bounds, 50)); } catch (Exception e) { Toast.makeText(MainActivity.this, "EXCEPTION: Cannot parse routing response", Toast.LENGTH_SHORT).show(); } } @Override public void onRoutingCancelled() { Toast.makeText(MainActivity.this, "Routing Cancelled", Toast.LENGTH_SHORT).show(); } /** * @method getRoutingPath * @desc Method to draw the google routed path. */ private void getRoutingPath() { try { //Do Routing Routing routing = new Routing.Builder() .travelMode(Routing.TravelMode.DRIVING) .withListener(this) .waypoints(currentLatLng, Constants.POINT_DEST) .build(); routing.execute(); } catch (Exception e) { Toast.makeText(MainActivity.this, "Unable to Route", Toast.LENGTH_SHORT).show(); } } } 

Constantes.java

 /** * @class Constants * @desc Constant class for holding values at runtime. */ public class Constants { //Map LatLong points public static LatLng POINT_DEST = null; } 

Activity_map.xml

 <android.support.design.widget.CoordinatorLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:map="http://schemas.android.com/apk/res-auto" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent"> <LinearLayout android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical"> <LinearLayout android:id="@+id/viewA" android:layout_width="match_parent" android:layout_height="match_parent" android:layout_weight="0.1" android:orientation="horizontal"> <fragment android:id="@+id/map" android:name="com.google.android.gms.maps.SupportMapFragment" android:layout_width="match_parent" android:layout_height="match_parent" tools:context="com.packagename.MainActivity" /> </LinearLayout> <LinearLayout android:id="@+id/viewB" android:layout_width="match_parent" android:layout_height="match_parent" android:layout_weight="0.9" android:gravity="center|left" android:paddingLeft="20dp" android:background="#FFFFFF" android:orientation="vertical" > <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:textSize="16dp" android:text="Distance ?" android:paddingTop="3dp" android:paddingLeft="3dp" android:paddingBottom="3dp" android:id="@+id/txt_distance" /> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:textSize="17dp" android:paddingLeft="3dp" android:text="Duration ?" android:id="@+id/txt_time" /> </LinearLayout> </LinearLayout> <android.support.design.widget.FloatingActionButton android:id="@+id/fab" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_margin="16dp" android:clickable="true" android:src="@android:drawable/ic_dialog_map" app:layout_anchor="@id/viewA" app:layout_anchorGravity="bottom|right|end"/> </android.support.design.widget.CoordinatorLayout> 

He aquí un código para ayudarte.

 String url= "http://maps.googleapis.com/maps/api/directions/json?origin=" + origin.latitude + "," + origin.longitude +"&destination=" + destination.latitude + "," + destination.longitude + "&sensor=false"; 

Para obtener los datos con androidhttpclient, haga algo como esto:

 HttpResponse response; HttpGet request; AndroidHttpClient client = AndroidHttpClient.newInstance("somename"); request = new HttpGet(url); response = client.execute(request); InputStream source = response.getEntity().getContent(); String returnValue = buildStringIOutils(source); return returnValue; 

Donde buildStringIOUtils es:

 private String buildStringIOutils(InputStream is) { try { return IOUtils.toString(is, "UTF-8"); } catch (IOException e) { e.printStackTrace(); return null; } } 

A continuación, puede extraer la polilínea real de la respuesta JSON con algo como esto:

 JSONObject result = new JSONObject(returnValue); JSONArray routes = result.getJSONArray("routes"); long distanceForSegment = routes.getJSONObject(0).getJSONArray("legs").getJSONObject(0).getJSONObject("distance").getInt("value"); JSONArray steps = routes.getJSONObject(0).getJSONArray("legs") .getJSONObject(0).getJSONArray("steps"); List<LatLng> lines = new ArrayList<LatLng>(); for(int i=0; i < steps.length(); i++) { String polyline = steps.getJSONObject(i).getJSONObject("polyline").getString("points"); for(LatLng p : decodePolyline(polyline)) { lines.add(p); } } 

Donde el método decodePolyline es el siguiente:

  /** POLYLINE DECODER - http://jeffreysambells.com/2010/05/27/decoding-polylines-from-google-maps-direction-api-with-java **/ private List<LatLng> decodePolyline(String encoded) { List<LatLng> poly = new ArrayList<LatLng>(); int index = 0, len = encoded.length(); int lat = 0, lng = 0; while (index < len) { int b, shift = 0, result = 0; do { b = encoded.charAt(index++) - 63; result |= (b & 0x1f) << shift; shift += 5; } while (b >= 0x20); int dlat = ((result & 1) != 0 ? ~(result >> 1) : (result >> 1)); lat += dlat; shift = 0; result = 0; do { b = encoded.charAt(index++) - 63; result |= (b & 0x1f) << shift; shift += 5; } while (b >= 0x20); int dlng = ((result & 1) != 0 ? ~(result >> 1) : (result >> 1)); lng += dlng; LatLng p = new LatLng((double) lat / 1E5, (double) lng / 1E5); poly.add(p); } return poly; } 

A continuación, puede agregar la polilínea al mapa con esto:

 Polyline polylineToAdd = mMap.addPolyline(new PolylineOptions().addAll(lines).width(3).color(Color.RED)); 

Para cambiar el modo, agregue esto a la url (consulte https://developers.google.com/maps/documentation/directions/ ): & mode = YOUR_MODE

La conducción (por defecto) indica las direcciones de conducción estándar utilizando la red de carreteras.

Caminar las peticiones de caminar direcciones a través de caminos peatonales y aceras (donde esté disponible).

Ciclismo solicita las direcciones en bicicleta a través de caminos de bicicleta y calles preferidas (donde esté disponible).

Direcciones de tránsito por tránsito público (donde esté disponible).

Editar: Acerca de "También me gustaría obtener información de tráfico, como rutas de ocupado, congestión, etc" No he mirado en esto, pero mi código debe comenzar muy bien.

Edit2: Esto se encuentra en las direcciones de google api: "Para Direcciones de conducción: Los clientes de Maps for Business pueden especificar el departure_time para recibir la duración del viaje teniendo en cuenta las condiciones actuales del tráfico.El departure_time debe establecerse en unos minutos de la hora actual.

Prueba la API de Google Direcciones . Es un servicio web que ofrece guías paso a paso en formato JSON con toda la información para llegar desde el punto A al B en automóvil, tránsito o en los pies.

Para codificar que siguen el enlace en el comentario de estocásticamente.

  • ¿Una clave API de Google Maps caduca después de un tiempo determinado?
  • Android Studio - Mapa de Google aún en blanco en un dispositivo Android real
  • ¿Cuándo puedes llamar a GoogleMap.moveCamera después de onMapReady de OnMapReadyCallback?
  • Google google mapv2 icono de la URL
  • Android googlemaps V2 - Desactivar desplazamiento en panorámica o zoom
  • No se encontró el recurso de servicio de Google Play
  • Configuración de un LongClickListener en un marcador de mapa
  • Puedo cambiar mi ubicación en los mapas de Android
  • FlipAndroid es un fan de Google para Android, Todo sobre Android Phones, Android Wear, Android Dev y Aplicaciones para Android Aplicaciones.