Polylines are not showing between 2 Locations but

2019-05-27 09:54发布

问题:

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);
}

回答1:

I'm assuming that you need Route, Distance and Time. First Create these 3 classes.

  1. 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);
        }
      }
    }
    
  2. 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;
    }
    }
    
  3. 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).



回答2:

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;
    }