Reputation: 53
I want to show Navigation route between two lat lng point. Start position is may be different from current location. I do this task with Intent but i want to do without intent. Navigation show like Uber cab. I am new in android.Please help me. Thanks in advance.
Upvotes: 0
Views: 2552
Reputation: 1918
I made Just a single funtion to plot Polylines on the route from origin to destination
public void markRoute(LatLng... value){
LatLng startPoint = value[0];
LatLng endPoint = value[1];
LatLng midPoint = value[2];
String url = "";
if(midPoint != null)
url = "https://maps.googleapis.com/maps/api/directions/" +
"json?origin="+startPoint.latitude+","+startPoint.longitude+"&destination="+endPoint.latitude+","+endPoint.longitude+"&" +
"waypoints="+midPoint.latitude+","+midPoint.longitude;
else
url = "https://maps.googleapis.com/maps/api/directions/" +
"json?origin="+startPoint.latitude+","+startPoint.longitude+"&destination="+endPoint.latitude+","+endPoint.longitude;
StringRequest stringRequest = new StringRequest(Request.Method.POST,url ,
new Response.Listener<String>() {
@Override
public void onResponse(String result) {
JSONObject jsonResponse;
try {
jsonResponse = new JSONObject(result);
JSONArray routes = jsonResponse.getJSONArray("routes");
for (int i=0; i<routes.length(); i++) {
PolylineOptions options = new PolylineOptions().width(5).color(Color.BLUE).geodesic(true);
JSONArray legs = routes.getJSONObject(i).getJSONArray("legs");
for (int j=0; j<legs.length(); j++) {
JSONArray steps = legs.getJSONObject(j).getJSONArray("steps");
int lastItem = 0;
for (int k=0; k<steps.length(); k++) {
options.add(new LatLng(steps.getJSONObject(k).getJSONObject("start_location").getDouble("lat"),
steps.getJSONObject(k).getJSONObject("start_location").getDouble("lng")));
lastItem = k;
}
options.add(new LatLng(steps.getJSONObject(lastItem).getJSONObject("end_location").getDouble("lat"),
steps.getJSONObject(lastItem).getJSONObject("end_location").getDouble("lng")));
}
mMap.addPolyline(options);
}
}
catch (JSONException e) {
e.printStackTrace();
}
}
},
new Response.ErrorListener() {
@Override
public void onErrorResponse(VolleyError error) {
}
}){
@Override
protected Map<String,String> getParams(){
Map<String,String> params = new HashMap<String, String>();
return params;
}
};
RequestQueue requestQueue = Volley.newRequestQueue(getApplicationContext());
requestQueue.add(stringRequest);
}
Here mMap
is GoogleMap
, which you get onMapReady()
You can Just call this function as, if single waypoint or mid point is provided.
markRoute(LatLng startPoint, LatLng endPoint, LatLng midPoint)
or it can be also as, if only source and destination provided
markRoute(LatLng startPoint, LatLng endPoint)
from anywhere in your program.
Upvotes: 0
Reputation: 2326
You can give LatLan in getDirectionsUrl(LatLng origin,LatLng dest) function and you can show the route between origin and dest.
XML Code :
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent" >
<RelativeLayout
android:id="@+id/header"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:background="@mipmap/gradiant"
android:layout_alignParentTop="true"
android:padding="6dp">
<TextView
android:id="@+id/activity_registration_txtTitle"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerInParent="true"
android:textSize="16sp"
android:textStyle="bold"
android:text="Event Destination"/>
</RelativeLayout>
<fragment
android:id="@+id/map"
android:layout_below="@+id/header"
android:name="com.google.android.gms.maps.MapFragment"
android:layout_width="match_parent"
android:layout_height="match_parent"
/>
<TextView
android:id="@+id/tv_distance_time"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="@+id/header"
android:layout_alignParentLeft="true"
android:layout_alignParentStart="true" />
</RelativeLayout>
Java Code :
import android.app.Activity;
import android.app.ProgressDialog;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.graphics.Color;
import android.location.Address;
import android.location.Geocoder;
import android.location.Location;
import android.os.AsyncTask;
import android.os.Bundle;
import android.support.v4.app.ActivityCompat;
import android.util.Log;
import android.view.View;
import android.widget.TextView;
import android.widget.Toast;
import com.android.volley.DefaultRetryPolicy;
import com.android.volley.Request;
import com.android.volley.RequestQueue;
import com.android.volley.Response;
import com.android.volley.VolleyError;
import com.android.volley.toolbox.StringRequest;
import com.android.volley.toolbox.Volley;
import com.google.android.gms.common.ConnectionResult;
import com.google.android.gms.common.api.GoogleApiClient;
import com.google.android.gms.location.LocationServices;
import com.google.android.gms.maps.CameraUpdate;
import com.google.android.gms.maps.CameraUpdateFactory;
import com.google.android.gms.maps.GoogleMap;
import com.google.android.gms.maps.MapFragment;
import com.google.android.gms.maps.OnMapReadyCallback;
import com.google.android.gms.maps.model.BitmapDescriptorFactory;
import com.google.android.gms.maps.model.LatLng;
import com.google.android.gms.maps.model.Marker;
import com.google.android.gms.maps.model.MarkerOptions;
import com.google.android.gms.maps.model.PolylineOptions;
import com.mayur.aroundus.EventClass.Event;
import com.mayur.aroundus.Utility.CommonUtility;
import com.mayur.aroundus.Utility.DirectionsJSONParser;
import com.mayur.aroundus.Utility.GPSTracker;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Locale;
import java.util.Map;
public class MapsActivity extends Activity implements OnMapReadyCallback, com.google.android.gms.common.api.GoogleApiClient.ConnectionCallbacks, com.google.android.gms.common.api.GoogleApiClient.OnConnectionFailedListener {
private static final String TAG ="AroundUs" ;
private GoogleMap mMap;
GPSTracker gps;
protected GoogleApiClient mGoogleApiClient;
protected Location mLastLocation;
private double latitude = 0;
private double longitude = 0;
List<Event> lsEvent=new ArrayList<Event>();
String destLatitude,destLongitude;
TextView tvDistanceDuration;
ArrayList<LatLng> markerPoints;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_maps);
GPSTracker gps = new GPSTracker(MapsActivity.this);
if(gps.canGetLocation()) {
System.out.println("Latitude = "+gps.getLatitude()+" Longitude = "+
gps.getLongitude());
}
markerPoints = new ArrayList<LatLng>();
Intent intent = getIntent();
destLatitude = intent.getStringExtra("Latitude");
destLongitude = intent.getStringExtra("Longitude");
buildGoogleApiClient();
}
protected synchronized void buildGoogleApiClient() {
mGoogleApiClient = new GoogleApiClient.Builder(this)
.addConnectionCallbacks(this)
.addOnConnectionFailedListener(this)
.addApi(LocationServices.API)
.build();
}
@Override
protected void onStart() {
super.onStart();
mGoogleApiClient.connect();
}
@Override
protected void onStop() {
super.onStop();
if (mGoogleApiClient.isConnected()) {
mGoogleApiClient.disconnect();
}
}
//Runs when a GoogleApiClient object successfully connects.
@Override
public void onConnected(Bundle connectionHint) {
mLastLocation = LocationServices.FusedLocationApi.getLastLocation(mGoogleApiClient);
if (mLastLocation != null) {
latitude=mLastLocation.getLatitude();
longitude=mLastLocation.getLongitude();
MapFragment mapFragment = (MapFragment) getFragmentManager().findFragmentById(R.id.map);
mapFragment.getMapAsync(MapsActivity.this);
tvDistanceDuration = (TextView) findViewById(R.id.tv_distance_time);
} else {
Toast.makeText(this, "no_location_detected", Toast.LENGTH_LONG).show();
}
}
@Override
public void onConnectionFailed(ConnectionResult result) {
// Refer to the javadoc for ConnectionResult to see what error codes might be returned in
// onConnectionFailed.
Log.i(TAG, "Connection failed: ConnectionResult.getErrorCode() = " + result.getErrorCode());
}
@Override
public void onConnectionSuspended(int cause) {
// The connection to Google Play services was lost for some reason. We call connect() to
// attempt to re-establish the connection.
Log.i(TAG, "Connection suspended");
mGoogleApiClient.connect();
}
@Override
public void onMapReady(GoogleMap googleMap) {
mMap = googleMap;
// Add a marker in Sydney and move the camera
LatLng sydney = new LatLng(latitude, longitude);
mMap.clear();
CameraUpdate cameraUpdate = CameraUpdateFactory.newLatLngZoom(new LatLng(latitude, longitude), 16);
mMap.animateCamera(cameraUpdate);
System.out.println("Latitude "+latitude+ " \n Longitude "+longitude);
mMap.setMyLocationEnabled(true);
LatLng origin = new LatLng(latitude,longitude);
LatLng dest = new LatLng(Double.parseDouble(destLatitude),Double.parseDouble(destLongitude));
// Getting URL to the Google Directions API
String url = getDirectionsUrl(origin, dest);
DownloadTask downloadTask = new DownloadTask();
// Start downloading json data from Google Directions API
downloadTask.execute(url);
}
private void call() {
mMap.setOnMapClickListener(new GoogleMap.OnMapClickListener() {
@Override
public void onMapClick(LatLng latLng) {
LatLng origin = new LatLng(latitude,longitude);
LatLng dest = new LatLng(Double.parseDouble(destLatitude), Double.parseDouble(destLongitude));
// Getting URL to the Google Directions API
String url = getDirectionsUrl(origin, dest);
DownloadTask downloadTask = new DownloadTask();
// Start downloading json data from Google Directions API
downloadTask.execute(url);
}
});
}
public String getLocationStringAddress(LatLng latLng){
Geocoder geocoder = new Geocoder(MapsActivity.this, Locale.getDefault());
String result = null;
try {
// latitude=23.0590869;
// longitude=72.5557736;
latitude=latLng.latitude;
longitude=latLng.longitude;
List<Address> addressList = geocoder.getFromLocation(latitude, longitude, 1);
if (addressList != null && addressList.size() > 0) {
android.location.Address address = addressList.get(0);
StringBuilder sb = new StringBuilder();
// for (int i = 0; i < address.getMaxAddressLineIndex(); i++) {
// sb.append(address.getAddressLine(i)).append("\n");
// }
sb.append(address.getLocality()).append(", ");
// sb.append(address.getPostalCode()).append("\n");
sb.append(address.getCountryName());
result = sb.toString();
}
} catch (IOException e) {
Log.e(TAG, "Unable connect to Geocoder", e);
}
return result;
}
private String getDirectionsUrl(LatLng origin,LatLng dest){
// Origin of route
String str_origin = "origin="+origin.latitude+","+origin.longitude;
// Destination of route
String str_dest = "destination="+dest.latitude+","+dest.longitude;
// Sensor enabled
String sensor = "sensor=false";
// Building the parameters to the web service
String parameters = str_origin+"&"+str_dest+"&"+sensor;
// Output format
String output = "json";
// Building the url to the web service
String url = "https://maps.googleapis.com/maps/api/directions/"+output+"?"+parameters;
return url;
}
/** A method to download json data from url */
private String downloadUrl(String strUrl) throws IOException{
String data = "";
InputStream iStream = null;
HttpURLConnection urlConnection = null;
try{
URL url = new URL(strUrl);
// Creating an http connection to communicate with url
urlConnection = (HttpURLConnection) url.openConnection();
// Connecting to url
urlConnection.connect();
// Reading data from url
iStream = urlConnection.getInputStream();
BufferedReader br = new BufferedReader(new InputStreamReader(iStream));
StringBuffer sb = new StringBuffer();
String line = "";
while( ( line = br.readLine()) != null){
sb.append(line);
}
data = sb.toString();
br.close();
}catch(Exception e){
Log.d("Exception downloading", e.toString());
}finally{
iStream.close();
urlConnection.disconnect();
}
return data;
}
// Fetches data from url passed
private class DownloadTask extends AsyncTask<String, Void, String>{
// Downloading data in non-ui thread
@Override
protected String doInBackground(String... url) {
// For storing data from web service
String data = "";
try{
// Fetching the data from web service
data = downloadUrl(url[0]);
}catch(Exception e){
Log.d("Background Task",e.toString());
}
return data;
}
// Executes in UI thread, after the execution of
// doInBackground()
@Override
protected void onPostExecute(String result) {
super.onPostExecute(result);
ParserTask parserTask = new ParserTask();
// Invokes the thread for parsing the JSON data
parserTask.execute(result);
}
}
/** A class to parse the Google Places in JSON format */
private class ParserTask extends AsyncTask<String, Integer, List<List<HashMap<String,String>>> >{
// Parsing the data in non-ui thread
@Override
protected List<List<HashMap<String, String>>> doInBackground(String... jsonData) {
JSONObject jObject;
List<List<HashMap<String, String>>> routes = null;
try{
jObject = new JSONObject(jsonData[0]);
DirectionsJSONParser parser = new DirectionsJSONParser();
// Starts parsing data
routes = parser.parse(jObject);
}catch(Exception e){
e.printStackTrace();
}
return routes;
}
// Executes in UI thread, after the parsing process
@Override
protected void onPostExecute(List<List<HashMap<String, String>>> result) {
ArrayList<LatLng> points = null;
PolylineOptions lineOptions = null;
MarkerOptions markerOptions = new MarkerOptions();
String distance = "";
String duration = "";
if(result.size()<1){
Toast.makeText(getBaseContext(), "No Points", Toast.LENGTH_SHORT).show();
return;
}
// Traversing through all the routes
for(int i=0;i<result.size();i++){
points = new ArrayList<LatLng>();
lineOptions = new PolylineOptions();
// Fetching i-th route
List<HashMap<String, String>> path = result.get(i);
// Fetching all the points in i-th route
for(int j=0;j<path.size();j++){
HashMap<String,String> point = path.get(j);
if(j==0){ // Get distance from the list
distance = (String)point.get("distance");
continue;
}else if(j==1){ // Get duration from the list
duration = (String)point.get("duration");
continue;
}
double lat = Double.parseDouble(point.get("lat"));
double lng = Double.parseDouble(point.get("lng"));
LatLng position = new LatLng(lat, lng);
points.add(position);
}
// Adding all the points in the route to LineOptions
lineOptions.addAll(points);
lineOptions.width(5);
lineOptions.color(Color.RED);
}
tvDistanceDuration.setText("Distance:"+distance + ", Duration:"+duration);
// Drawing polyline in the Google Map for the i-th route
mMap.addPolyline(lineOptions);
mMap.addMarker(new MarkerOptions()
.position(new LatLng(Double.parseDouble(destLatitude), Double.parseDouble(destLongitude)))
.title(getLocationStringAddress(new LatLng(Double.parseDouble(destLatitude), Double.parseDouble(destLongitude))))
// .snippet(getLocationStringAddress(new LatLng(Double.parseDouble(destLatitude), Double.parseDouble(destLongitude))))
.icon(BitmapDescriptorFactory.fromResource(R.mipmap.map_set_marker)));
}
}
}
Upvotes: 2