Note: Sorry for my bad English because English is not my native language I have used Google Translate for this.
I am working on an Android map app in which a user can find their friends' current location. For storing the current location I am using Firebase real time database. With previous help of Lalit Singh it is showing time and distance now but still not updating the Polylines between 2 different places. My updates code is below.
mapsActivity.java (where i am getting friend location from fire base and updated time, distance and polylines method called)
public void proceed(final View view) {
DatabaseReference ref = FirebaseDatabase.getInstance().getReference().child("Email");
ref.addValueEventListener(new ValueEventListener() {
@Override
public void onDataChange(DataSnapshot dataSnapshot) {
for (DataSnapshot dataSnapshot1 : dataSnapshot.getChildren()) {
UserInformation details = dataSnapshot1.getValue(UserInformation.class);
if (mMap != null) {
mMap.clear();
}
MarkerOptions markerOptions = new MarkerOptions();
LatLng latLng1 = new LatLng(details.getLatitude(), details.getLongitude());
markerOptions.position(latLng1);
markerOptions.title(String.valueOf(latLng1));
mMap.addMarker(markerOptions).setIcon(BitmapDescriptorFactory.defaultMarker(BitmapDescriptorFactory.HUE_GREEN));
mMap.setMapType(GoogleMap.MAP_TYPE_HYBRID);
mMap.moveCamera(CameraUpdateFactory.newLatLng(latLng1));
mMap.animateCamera(CameraUpdateFactory.zoomTo(14));
distance_task.getDirectionsUrl(latLng1, markerOptions.getPosition());
distance_task.setLoadListener(new CalculateDistanceTime.taskCompleteListener() {
@Override
public void taskCompleted(String[] time_distance) {
text1.setText(time_distance[0]); //Distance
text2.setText(time_distance[1]); //Time
}
});
String url = getDirectionsUrl(latLng1, markerOptions.getPosition());
DownloadTask downloadTask = new DownloadTask();
downloadTask.execute(url);
}
}
@Override
public void onCancelled(DatabaseError databaseError) {
}
});
}
CalculateDistanceTime.java (added new Class)
class CalculateDistanceTime { private taskCompleteListener
mTaskListener; private Context mContext;
CalculateDistanceTime(Context context) {
mContext = context; } void setLoadListener(taskCompleteListener taskListener) {
mTaskListener = taskListener; } void 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;
DownloadTask downloadTask = new DownloadTask();
// Start downloading json data from Google Directions API
downloadTask.execute(url); }
private String downloadUrl(String strUrl) throws IOException {
String data = "";
HttpURLConnection urlConnection;
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
try (InputStream iStream = urlConnection.getInputStream()) {
BufferedReader br = new BufferedReader(new InputStreamReader(iStream));
StringBuilder sb = new StringBuilder();
String line;
while ((line = br.readLine()) != null) {
sb.append(line);
}
data = sb.toString();
br.close();
} catch (Exception e) {
Log.d("Excp. while downloading", e.toString());
} finally {
urlConnection.disconnect();
}
return data; }
interface taskCompleteListener {
void taskCompleted(String[] time_distance); }
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);
} }
private class ParserTask extends AsyncTask<String, Integer,
List<HashMap<String, String>>> {
// Parsing the data in non-ui thread
@Override
protected List<HashMap<String, String>> doInBackground(String... jsonData) {
JSONObject jObject;
List<HashMap<String, String>> routes = null;
try {
jObject = new JSONObject(jsonData[0]);
DistanceTimeParser parser = new DistanceTimeParser();
// 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<HashMap<String, String>> result) {
String duration_distance = "";
if (result.size() < 1) {
Log.e("Error : ", "No Points found");
return;
}
String[] date_dist = new String[2];
// Traversing through all the routes
for (int i = 0; i < result.size(); i++) {
// Fetching i-th route
HashMap<String, String> tmpData = result.get(i);
Set<String> key = tmpData.keySet();
Iterator it = key.iterator();
while (it.hasNext()) {
String hmKey = (String) it.next();
duration_distance = tmpData.get(hmKey);
System.out.println("Key: " + hmKey + " & Data: " + duration_distance);
it.remove(); // avoids a ConcurrentModificationException
}
date_dist[i] = duration_distance;
}
mTaskListener.taskCompleted(date_dist);
} } }
DistanceTimeParser.java (added new class)
public class DistanceTimeParser {
public List<HashMap<String, String>> parse(JSONObject jObject) {
List<HashMap<String, String>> routes = new ArrayList<HashMap<String, String>>();
JSONArray jRoutes = null;
JSONArray jLegs = null;
JSONObject jDistance = null;
JSONObject jDuration = null;
try {
jRoutes = jObject.getJSONArray("routes");
jLegs = ((JSONObject) jRoutes.get(0)).getJSONArray("legs");
List<HashMap<String, String>> path = new ArrayList<HashMap<String, String>>();
/** Getting distance from the json data */
jDistance = ((JSONObject) jLegs.get(0)).getJSONObject("distance");
HashMap<String, String> hmDistance = new HashMap<String, String>();
hmDistance.put("distance", jDistance.getString("text"));
/** Getting duration from the json data */
jDuration = ((JSONObject) jLegs.get(0)).getJSONObject("duration");
HashMap<String, String> hmDuration = new HashMap<String, String>();
hmDuration.put("duration", jDuration.getString("text"));
routes.add(hmDistance);
routes.add(hmDuration);
} catch (JSONException e) {
e.printStackTrace();
} catch (Exception e) {
}
return routes;
} }
DirectionsJSONParser.java (added new class)
public class DirectionsJSONParser {
List<List<HashMap<String,String>>> parse(JSONObject jObject){
List<List<HashMap<String, String>>> routes = new ArrayList<>() ;
JSONArray jRoutes ;
JSONArray jLegs ;
JSONArray jSteps ;
try {
jRoutes = jObject.getJSONArray("routes");
for(int i=0;i<jRoutes.length();i++){
jLegs = ( (JSONObject)jRoutes.get(i)).getJSONArray("legs");
List path = new ArrayList<>();
for(int j=0;j<jLegs.length();j++){
jSteps = ( (JSONObject)jLegs.get(j)).getJSONArray("steps");
for(int k=0;k<jSteps.length();k++){
String polyline;
polyline = (String)((JSONObject)((JSONObject)jSteps.get(k)).get("polyline")).get("points");
List<LatLng> list = decodePoly(polyline);
for(int l=0;l<list.size();l++){
HashMap<String, String> hm = new HashMap<>();
hm.put("lat", Double.toString((list.get(l)).latitude) );
hm.put("lng", Double.toString((list.get(l)).longitude) );
path.add(hm);
}
}
routes.add(path);
}
}
} catch (JSONException e) {
e.printStackTrace();
}catch (Exception ignored){
}
return routes;
}
private List<LatLng> decodePoly(String encoded) {
List<LatLng> poly = new ArrayList<>();
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;
} }
These 4 methods added in mapsActivity.java
private String getDirectionsUrl(LatLng origin, LatLng dest) {
String str_origin = "origin=" + origin.latitude + "," + origin.longitude;
String str_dest = "destination=" + dest.latitude + "," + dest.longitude;
String sensor = "sensor=false";
String parameters = str_origin + "&" + str_dest + "&" + sensor;
String output = "json";
return "https://maps.googleapis.com/maps/api/directions/" + output + "?" + parameters;
}
@SuppressLint("NewApi")
public static String downloadUrl(String strUrl) throws IOException {
String data = "";
HttpURLConnection urlConnection;
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
try (InputStream iStream = urlConnection.getInputStream()) {
BufferedReader br = new BufferedReader(new InputStreamReader(iStream));
StringBuilder sb = new StringBuilder();
String line;
while ((line = br.readLine()) != null) {
sb.append(line);
}
data = sb.toString();
br.close();
} catch (Exception e) {
Log.d("Exception while down", e.toString());
} finally {
urlConnection.disconnect();
}
return data;
}
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);
}
}
private class ParserTask extends AsyncTask<String, Integer, List<List<HashMap<String, String>>>> {
@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;
}
@Override
protected void onPostExecute(List<List<HashMap<String, String>>> result) {
ArrayList<LatLng> points = new ArrayList<>();
PolylineOptions lineOptions = new PolylineOptions();
for (int i = 0; i < result.size(); i++) {
List<HashMap<String, String>> path = result.get(i);
for (int j = 0; j < path.size(); j++) {
HashMap<String, String> point = path.get(j);
double lat = Double.parseDouble(point.get("lat"));
double lng = Double.parseDouble(point.get("lng"));
LatLng position = new LatLng(lat, lng);
points.add(position);
}
lineOptions.addAll(points);
lineOptions.width(10);
lineOptions.color(Color.WHITE);
mMap.addPolyline(lineOptions);
}
}
}
mapsActivity.java (my current location in map)
@Override
public void onLocationChanged(Location location) {
Log.d("onLocationChanged", "entered");
mLastLocation = location;
DateFormat dateFormat = new SimpleDateFormat("yyyy/MM/dd HH:mm:ss");
dateFormat.setTimeZone(TimeZone.getTimeZone("UTC"));
Date date = new Date();
mLastUpdateTime = ((dateFormat.format(date).toString()));
saveToFirebase();
if (mCurrLocationMarker != null) {
mCurrLocationMarker.remove();
}
latitude = location.getLatitude();
longitude = location.getLongitude();
LatLng latLng = new LatLng(location.getLatitude(), location.getLongitude());
MarkerOptions markerOptions = new MarkerOptions();
markerOptions.position(latLng);
markerOptions.draggable(false);
markerOptions.title("Current Position");
markerOptions.icon(BitmapDescriptorFactory.defaultMarker(BitmapDescriptorFactory.HUE_MAGENTA));
mCurrLocationMarker = mMap.addMarker(markerOptions);
//move map camera
mMap.moveCamera(CameraUpdateFactory.newLatLng(latLng));
mMap.animateCamera(CameraUpdateFactory.zoomTo(11));
Toast.makeText(MapsActivity.this, "Your Current Location", Toast.LENGTH_LONG).show();
//stop location updates
if (mGoogleApiClient != null) {
LocationServices.FusedLocationApi.removeLocationUpdates(mGoogleApiClient,
this);
Log.d("onLocationChanged", "Removing Location Updates");
}
}
Data Saved in Fire Base Method
public void saveToFirebase() {
DatabaseReference ref = FirebaseDatabase.getInstance().getReference().child("Email").push();
String email = FirebaseAuth.getInstance().getCurrentUser().getEmail();
UserInformation userInformation = new UserInformation(email, mLastLocation.getLatitude(), mLastLocation.getLongitude());
ref.setValue(userInformation);
}
I'm assuming that you need Route, Distance and Time.
First Create these 3 classes.
CalculateDistanceTime.java
import android.content.Context;
import android.os.AsyncTask;
import android.util.Log;
import com.google.android.gms.maps.model.LatLng;
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.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Set;
class CalculateDistanceTime {
private taskCompleteListener mTaskListener;
private Context mContext;
CalculateDistanceTime(Context context) {
mContext = context;
}
void setLoadListener(taskCompleteListener taskListener) {
mTaskListener = taskListener;
}
void 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;
DownloadTask downloadTask = new DownloadTask();
// Start downloading json data from Google Directions API
downloadTask.execute(url);
}
private String downloadUrl(String strUrl) throws IOException {
String data = "";
HttpURLConnection urlConnection;
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
try (InputStream iStream = urlConnection.getInputStream()) {
BufferedReader br = new BufferedReader(new InputStreamReader(iStream));
StringBuilder sb = new StringBuilder();
String line;
while ((line = br.readLine()) != null) {
sb.append(line);
}
data = sb.toString();
br.close();
} catch (Exception e) {
Log.d("Excp. while downloading", e.toString());
} finally {
urlConnection.disconnect();
}
return data;
}
interface taskCompleteListener {
void taskCompleted(String[] time_distance);
}
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);
}
}
private class ParserTask extends AsyncTask<String, Integer, List<HashMap<String, String>>> {
// Parsing the data in non-ui thread
@Override
protected List<HashMap<String, String>> doInBackground(String... jsonData) {
JSONObject jObject;
List<HashMap<String, String>> routes = null;
try {
jObject = new JSONObject(jsonData[0]);
DistanceTimeParser parser = new DistanceTimeParser();
// 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<HashMap<String, String>> result) {
String duration_distance = "";
if (result.size() < 1) {
Log.e("Error : ", "No Points found");
return;
}
String[] date_dist = new String[2];
// Traversing through all the routes
for (int i = 0; i < result.size(); i++) {
// Fetching i-th route
HashMap<String, String> tmpData = result.get(i);
Set<String> key = tmpData.keySet();
Iterator it = key.iterator();
while (it.hasNext()) {
String hmKey = (String) it.next();
duration_distance = tmpData.get(hmKey);
System.out.println("Key: " + hmKey + " & Data: " + duration_distance);
it.remove(); // avoids a ConcurrentModificationException
}
date_dist[i] = duration_distance;
}
mTaskListener.taskCompleted(date_dist);
}
}
}
DistanceTimeParser.java
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
public class DistanceTimeParser {
public List<HashMap<String, String>> parse(JSONObject jObject) {
List<HashMap<String, String>> routes = new ArrayList<HashMap<String, String>>();
JSONArray jRoutes = null;
JSONArray jLegs = null;
JSONObject jDistance = null;
JSONObject jDuration = null;
try {
jRoutes = jObject.getJSONArray("routes");
jLegs = ((JSONObject) jRoutes.get(0)).getJSONArray("legs");
List<HashMap<String, String>> path = new ArrayList<HashMap<String, String>>();
/** Getting distance from the json data */
jDistance = ((JSONObject) jLegs.get(0)).getJSONObject("distance");
HashMap<String, String> hmDistance = new HashMap<String, String>();
hmDistance.put("distance", jDistance.getString("text"));
/** Getting duration from the json data */
jDuration = ((JSONObject) jLegs.get(0)).getJSONObject("duration");
HashMap<String, String> hmDuration = new HashMap<String, String>();
hmDuration.put("duration", jDuration.getString("text"));
routes.add(hmDistance);
routes.add(hmDuration);
} catch (JSONException e) {
e.printStackTrace();
} catch (Exception e) {
}
return routes;
}
}
DirectionsJSONParser.java
import com.google.android.gms.maps.model.LatLng;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
class DirectionsJSONParser {
List<List<HashMap<String,String>>> parse(JSONObject jObject){
List<List<HashMap<String, String>>> routes = new ArrayList<>() ;
JSONArray jRoutes ;
JSONArray jLegs ;
JSONArray jSteps ;
try {
jRoutes = jObject.getJSONArray("routes");
for(int i=0;i<jRoutes.length();i++){
jLegs = ( (JSONObject)jRoutes.get(i)).getJSONArray("legs");
List path = new ArrayList<>();
for(int j=0;j<jLegs.length();j++){
jSteps = ( (JSONObject)jLegs.get(j)).getJSONArray("steps");
for(int k=0;k<jSteps.length();k++){
String polyline;
polyline = (String)((JSONObject)((JSONObject)jSteps.get(k)).get("polyline")).get("points");
List<LatLng> list = decodePoly(polyline);
for(int l=0;l<list.size();l++){
HashMap<String, String> hm = new HashMap<>();
hm.put("lat", Double.toString((list.get(l)).latitude) );
hm.put("lng", Double.toString((list.get(l)).longitude) );
path.add(hm);
}
}
routes.add(path);
}
}
} catch (JSONException e) {
e.printStackTrace();
}catch (Exception ignored){
}
return routes;
}
private List<LatLng> decodePoly(String encoded) {
List<LatLng> poly = new ArrayList<>();
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;
}
}
After simply copying these three files.
What you can do is the following for any MapsActivity.
This is the point where you can use below code in any activity and above code will remain same for every acitivity(Maps for Directions).
Create a global variable CalculateDistanceTime distance_task;
.
Initialize it in the onCreate
as distance_task = new CalculateDistanceTime(this);
Post this 4 methods in your MapsActivity.java.
private String getDirectionsUrl(LatLng origin, LatLng dest) {
String str_origin = "origin=" + origin.latitude + "," + origin.longitude;
String str_dest = "destination=" + dest.latitude + "," + dest.longitude;
String sensor = "sensor=false";
String parameters = str_origin + "&" + str_dest + "&" + sensor;
String output = "json";
return "https://maps.googleapis.com/maps/api/directions/" + output + "?" + parameters;
}
public static String downloadUrl(String strUrl) throws IOException {
String data = "";
HttpURLConnection urlConnection;
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
try (InputStream iStream = urlConnection.getInputStream()) {
BufferedReader br = new BufferedReader(new InputStreamReader(iStream));
StringBuilder sb = new StringBuilder();
String line;
while ((line = br.readLine()) != null) {
sb.append(line);
}
data = sb.toString();
br.close();
} catch (Exception e) {
Log.d("Exception while down", e.toString());
} finally {
urlConnection.disconnect();
}
return data;
}
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);
}
}
private class ParserTask extends AsyncTask<String, Integer, List<List<HashMap<String, String>>>> {
@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;
}
@Override
protected void onPostExecute(List<List<HashMap<String, String>>> result) {
ArrayList<LatLng> points = new ArrayList<>();
lineOptions = new PolylineOptions();
for (int i = 0; i < result.size(); i++) {
List<HashMap<String, String>> path = result.get(i);
for (int j = 0; j < path.size(); j++) {
HashMap<String, String> point = path.get(j);
double lat = Double.parseDouble(point.get("lat"));
double lng = Double.parseDouble(point.get("lng"));
LatLng position = new LatLng(lat, lng);
points.add(position);
}
lineOptions.addAll(points);
lineOptions.width(10);
lineOptions.color(Color.WHITE);
googleMap.addPolyline(lineOptions);
}
}
At this point you have all the needed code.
Now use the following code passing the latlngs of your location and friend's location and you'll have Time Distance and Route.:
distance_task.getDirectionsUrl(latLng1, latLng2);
distance_task.setLoadListener(new CalculateDistanceTime.taskCompleteListener() {
@Override
public void taskCompleted(String[] time_distance) {
text1.setText(time_distance[0]); //Distance
text2.setText(time_distance[1]); //Time
}
});
String url = getDirectionsUrl(latLng1, latLng2);
DownloadTask downloadTask = new DownloadTask();
downloadTask.execute(url);
For displaying Distance and Time, You have to create two TextView
(see text1 and Text2 above).
Add below code and replace with your drawing polylines code, Use this
String url = getUrl(origin, dest);
FetchUrl FetchUrl = new FetchUrl();
// Start downloading json data from Google Directions API
FetchUrl.execute(url);
Use above code where you want to draw directions, origin
& dest
are LatLng object for example below,
LatLng dest = new LatLng(Double.parseDouble(d_lat), Double.parseDouble(d_lng));
Here are the following methods to get directions,
private String getUrl(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
return "https://maps.googleapis.com/maps/api/directions/" + output + "?" + parameters;
}
After this use these below classes,
private class FetchUrl extends AsyncTask<String, Void, String> {
@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]);
Log.d("Background Task data", data);
} catch (Exception e) {
Log.d("Background Task", e.toString());
}
return data;
}
@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]);
Log.d("ParserTask", jsonData[0]);
JSONArray array = jObject.getJSONArray("routes");
JSONObject paths = array.getJSONObject(0);
JSONArray legs = paths.getJSONArray("legs");
JSONObject steps = legs.getJSONObject(0);
JSONObject distance = steps.getJSONObject("distance");
JSONObject duration = legs.getJSONObject(0).getJSONObject("duration");
parsedDistance = distance.getString("text");
if (parsedDistance.contains("km")) {
String[] val = parsedDistance.split(" ");
String val1 = val[0];
distance_from = convertInMiles(val1);
} else {
distance_from = parsedDistance;
}
address = legs.getJSONObject(0).getString("end_address");
time = duration.getString("text");
DataParser parser = new DataParser();
Log.d("ParserTask", parser.toString());
// Starts parsing data
routes = parser.parse(jObject);
Log.d("ParserTask", "Executing routes");
Log.d("ParserTask", routes.toString());
} catch (Exception e) {
Log.d("ParserTask", e.toString());
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;
PolylineOptions lineOptions = null;
// Traversing through all the routes
if (result != null && result.size() > 0) {
for (int i = 0; i < result.size(); i++) {
points = new ArrayList<>();
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);
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(10);
lineOptions.color(Color.BLACK);
p_distance.setText("Distance : " + distance_from);
p_time.setText("ETA :" + time);
if (p_time.getText().toString().length() == 10) {
arrival_time = p_time.getText().toString().substring(5, p_time.getText().toString().length() - 4);
Log.d("arrival_time", arrival_time);
SessionManager.put(Constants.TIME, arrival_time);
} else if (p_time.getText().toString().length() > 10) {
arrival_time = p_time.getText().toString().substring(5, p_time.getText().toString().length() - 5);
Log.d("arrival_time", arrival_time);
SessionManager.put(Constants.TIME, arrival_time);
}
p_address.setText("Address : " + address);
navigation.setVisibility(View.VISIBLE);
Log.d("onPostExecute", "onPostExecute lineoptions decoded");
}
}
// Drawing polyline in the Google Map for the i-th route
if (lineOptions != null) {
mMap.addPolyline(lineOptions);
} else {
Log.d("onPostExecute", "without Polylines drawn");
}
}
}
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();
Log.d("downloadUrl", data);
br.close();
} catch (Exception e) {
Log.d("Exception", e.toString());
} finally {
assert iStream != null;
iStream.close();
assert urlConnection != null;
urlConnection.disconnect();
}
return data;
}