2

I'm trying to implement a functionality in my app which uses the Google Maps API Directions to draw a path (from A to B) in the map. For some reason it seems that the application can't even make the request.

This is what logcat reports: enter image description here

This is the class that I am using to do it:

public class DrawPath {

    static InputStream is = null;
    static JSONObject jObj = null;
    static String json = "";

    MainActivity actividadPrincipal;


    public DrawPath(MainActivity actividadPrincipal){
        this.actividadPrincipal = actividadPrincipal;
    }


    private List<LatLng> decodePoly(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;
    }

    public void drawPath(String  result) {

        try {
                //Tranform the string into a json object
               final JSONObject json = new JSONObject(result);
               JSONArray routeArray = json.getJSONArray("routes");
               JSONObject routes = routeArray.getJSONObject(0);
               JSONObject overviewPolylines = routes.getJSONObject("overview_polyline");
               String encodedString = overviewPolylines.getString("points");
               List<LatLng> list = decodePoly(encodedString);

               for(int z = 0; z<list.size()-1;z++){
                    LatLng src= list.get(z);
                    LatLng dest= list.get(z+1);
                    Polyline line = actividadPrincipal.googleMap.addPolyline(new PolylineOptions()
                    .add(new LatLng(src.latitude, src.longitude), new LatLng(dest.latitude,   dest.longitude))
                    .width(2)
                    .color(Color.BLUE).geodesic(true));
                }
        } 
        catch (JSONException e) {

        }
    } 

    // Parser Class
    public String getJSONFromUrl(String url) {

        // Making HTTP request
        try {
            // defaultHttpClient
            DefaultHttpClient httpClient = new DefaultHttpClient();
            HttpPost httpPost = new HttpPost(url);

            HttpResponse httpResponse = httpClient.execute(httpPost);
            HttpEntity httpEntity = httpResponse.getEntity();
            is = httpEntity.getContent();           

        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        } catch (ClientProtocolException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
        try {
            BufferedReader reader = new BufferedReader(new InputStreamReader(
                    is, "iso-8859-1"), 8);
            StringBuilder sb = new StringBuilder();
            String line = null;
            while ((line = reader.readLine()) != null) {
                sb.append(line + "\n");
            }

            json = sb.toString();
            is.close();
        } catch (Exception e) {
            Log.e("Buffer Error", "Error converting result " + e.toString());
        }
        return json;

    }

    //First of all we will get source and destination points between which we have to draw route. Then we will pass these attribute to getJSONFromUrl function.
    public String makeURL (double sourcelat, double sourcelog, double destlat, double destlog ){
        StringBuilder urlString = new StringBuilder();
        urlString.append("http://maps.googleapis.com/maps/api/directions/json");
        urlString.append("?origin="+Double.toString(sourcelat)+","+Double.toString( sourcelog));// from
        urlString.append("&destination="+Double.toString(destlat)+","+Double.toString(destlog));// to
        urlString.append("&sensor=false");
        urlString.append("&mode=driving");
        urlString.append("&alternatives=true");
        return urlString.toString();
 }
}

Adapted from this Answer : Draw path between two points using Google Maps Android API v2
Now, I have checked the Directions Api Documentation and haven't found anything related to this problem.

This is how I call the functions above from the bottom of onCreate (I havent designed a button yet)

//test
    DrawPath dPath = new DrawPath(this);
    String path = dPath.makeURL(markers.get(0).marker.getPosition().latitude,
            markers.get(0).marker.getPosition().longitude,
            markers.get(1).marker.getPosition().latitude, 
            markers.get(1).marker.getPosition().longitude);
    dPath.drawPath(path);   

I have checked the link and I see nothing wrong with it. Perhaps I'm missing a permission? But it would throw an exception in that case.

I tried changing http to https and adding "&key=myApiKey" at the end of the request as sugested by @3amoura, but got same errors.

UPDATE
After fixing minor stuff and hardcoding the url to request to http://maps.googleapis.com/maps/api/directions/json?origin=Granada&destination=Malaga&sensor=false it works, so the problem is in the makeUrl, I must be making it wrong

Community
  • 1
  • 1
Victor
  • 907
  • 2
  • 17
  • 42
  • Did you generated api key from the google console regarding the Direction API and used it in your manifest file ? – Omar HossamEldin Oct 13 '14 at 23:45
  • Oops, I didn't know I needed another API Key. Gonna check that right now. **EDIT**: I have one API Key asigned to my project, do I need one? I can't find anything about it – Victor Oct 13 '14 at 23:47

2 Answers2

1

It also return distance as well as route, only you need to call method drawPath(),

Step 1. // Declare these variable globally

GoogleMap googleMap;
Polyline line;
Double starting_lat,starting_lng;

Step 1. //** call this where you want to draw route and pass here starting latitude and longitude,

          String urlTopass1 = makeURL(starting_lat,
                starting_lng, location.getLatitude(),
                location.getLongitude());
           new connectAsyncTask(urlTopass1).execute();

//**

Step 2.

private class connectAsyncTask extends AsyncTask<Void, Void, String> {
        String url;
    connectAsyncTask(String urlPass) {
        url = urlPass;
        Log.e("test", " :---- 000 " + url);
    }

    @Override
    protected void onPreExecute() {

        super.onPreExecute();

    }

    @Override
    protected String doInBackground(Void... params) {
        JSONParser jParser = new JSONParser();
        String json = jParser.getJSONFromUrl(url);
        return json;
    }

    @Override
    protected void onPostExecute(String result) {
        super.onPostExecute(result);
        // progressDialog.hide();
        if (result != null) {
            drawPath(result);
        }
    }
}

Step 3.

public String makeURL(double sourcelat, double sourcelog, double destlat,
        double destlog) {
    StringBuilder urlString = new StringBuilder();
    urlString.append("http://maps.googleapis.com/maps/api/directions/json");
    urlString.append("?origin=");// from
    urlString.append(Double.toString(sourcelat));
    urlString.append(",");
    urlString.append(Double.toString(sourcelog));
    urlString.append("&destination=");// to
    urlString.append(Double.toString(destlat));
    urlString.append(",");
    urlString.append(Double.toString(destlog));
    urlString.append("&sensor=false&mode=driving&alternatives=true");
    return urlString.toString();
}

public class JSONParser {

    InputStream is = null;
    JSONObject jObj = null;
    String json = "";

    // constructor
    public JSONParser() {
    }

    public String getJSONFromUrl(String url) {

        // Making HTTP request
        try {
            DefaultHttpClient httpClient = new DefaultHttpClient();
            HttpPost httpPost = new HttpPost(url);

            HttpResponse httpResponse = httpClient.execute(httpPost);
            HttpEntity httpEntity = httpResponse.getEntity();
            is = httpEntity.getContent();

        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        } catch (ClientProtocolException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
        try {
            BufferedReader reader = new BufferedReader(
                    new InputStreamReader(is, "iso-8859-1"), 8);
            StringBuilder sb = new StringBuilder();
            String line = null;
            while ((line = reader.readLine()) != null) {
                sb.append(line + "\n");
            }

            json = sb.toString();
            is.close();
        } catch (Exception e) {
            Log.e("Buffer Error", "Error converting result " + e.toString());
        }
        return json;

    }
}

Step 4.

public void drawPath(String result) {
    try {

        if (line != null) {
            Log.i("removing line", "removed");
            googleMap.clear();
        }

        googleMap.addMarker(new MarkerOptions().position(passLatLng).icon(
                BitmapDescriptorFactory.defaultMarker()));
        marer= googleMap
                .addMarker(new MarkerOptions().position(driverLatLng).icon(
                        BitmapDescriptorFactory
                                .fromResource(R.drawable.icon)));
        try {

            final JSONObject json = new JSONObject(result);

            Log.e("test", "json  :p==  " + json);
            JSONArray routeArray = json.getJSONArray("routes");
            JSONObject routes = routeArray.getJSONObject(0);
            Log.e("test", "routes :==  " + routes);

            JSONArray newTempARr = routes.getJSONArray("legs");
            JSONObject newDisTimeOb = newTempARr.getJSONObject(0);
            Log.e("test", "newDisTimeOb :==  " + newDisTimeOb);

            JSONObject distOb = newDisTimeOb.getJSONObject("distance");

            String tempDist[] = distOb.getString("text").toString()
                    .split(" ");

            double tempDoubleDist = Double.valueOf(tempDist[0].replace(",",
                    ""));
            totalKm = String.valueOf(tempDoubleDist);

            int dist = (int) tempDoubleDist;

            JSONObject overviewPolylines = routes
                    .getJSONObject("overview_polyline");
            String encodedString = overviewPolylines.getString("points");
            List<LatLng> list = decodePoly(encodedString);

            PolylineOptions options = new PolylineOptions().width(5)
                    .color(Color.BLUE).geodesic(true);
            for (int z = 0; z < list.size(); z++) {
                LatLng point = list.get(z);
                options.add(point);
            }
            line = googleMap.addPolyline(options);
            Log.e("checking LatLng of pass bef moveCamera", ""
                    + passLatLng.latitude + "," + passLatLng.longitude);
            googleMap.moveCamera(CameraUpdateFactory.newLatLng(passLatLng));
            if (dist > 2 && dist <= 5) {
                googleMap.animateCamera(CameraUpdateFactory.zoomTo(13.0f));
                mapZoomLevel = 12;
            } else if (dist > 5 && dist <= 10) {
                googleMap.animateCamera(CameraUpdateFactory.zoomTo(12.0f));
                mapZoomLevel = 11;
            } else if (dist > 10 && dist <= 20) {
                googleMap.animateCamera(CameraUpdateFactory.zoomTo(11.0f));
                mapZoomLevel = 11;
            } else if (dist > 20 && dist <= 40) {
                googleMap.animateCamera(CameraUpdateFactory.zoomTo(10.0f));
                mapZoomLevel = 10;
            } else if (dist > 40 && dist < 100) {
                googleMap.animateCamera(CameraUpdateFactory.zoomTo(9.0f));
                mapZoomLevel = 9;
            } else if (dist > 100 && dist < 200) {
                googleMap.animateCamera(CameraUpdateFactory.zoomTo(8.0f));
                mapZoomLevel = 8;
            } else if (dist > 200 && dist < 400) {
                googleMap.animateCamera(CameraUpdateFactory.zoomTo(7.0f));
                mapZoomLevel = 7;
            } else if (dist > 400 && dist < 700) {
                googleMap.animateCamera(CameraUpdateFactory.zoomTo(6.0f));
                mapZoomLevel = 7;
            } else if (dist > 700 && dist < 1000) {
                googleMap.animateCamera(CameraUpdateFactory.zoomTo(5.0f));
                mapZoomLevel = 6;
            } else if (dist > 1000) {
                googleMap.animateCamera(CameraUpdateFactory.zoomTo(4.0f));
                mapZoomLevel = 5;
            } else {
                googleMap.animateCamera(CameraUpdateFactory.zoomTo(14.0f));
                mapZoomLevel = 14;
            }

        } catch (JSONException e) {
            e.printStackTrace();
        }
    } catch (Exception e) {
        e.printStackTrace();
    }
}

Step 5.

private List<LatLng> decodePoly(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;
}
Victor
  • 907
  • 2
  • 17
  • 42
Saveen
  • 4,120
  • 14
  • 38
  • 41
  • Can you introduce what is the link about? Link-only-answers are not encouraged. – Nikola Despotoski Oct 14 '14 at 04:06
  • I tried changing the decoding of the polyline as you suggested but it changes nothing, probably because it doesn't have anything to do with the issue where, since the program doesnt even perform the request – Victor Oct 14 '14 at 14:27
  • What are you doing man I have send you full code.. And still you struggling .. I can't imagain – Saveen Oct 14 '14 at 16:31
  • Just look this url ... http://stackoverflow.com/questions/17425499/how-to-draw-interactive-polyline-on-route-google-maps-v2-android – Saveen Oct 14 '14 at 17:24
  • Man, the code you are showing me is the exact same code I've got – Victor Oct 14 '14 at 22:17
  • @Victor please follow these steps again and tell me where is problem now, thanks – Saveen Oct 15 '14 at 04:17
  • I followed the steps and the problem is the same as the one in picture one – Victor Oct 15 '14 at 21:41
  • I have tried to change the request url to this http://maps.googleapis.com/maps/api/directions/json?origin=Granada&destination=Malaga&sensor=false and it works! the problem now is to make it work with the latitude and longitude. There must be something wrong – Victor Oct 15 '14 at 21:52
  • Okay, the problem was in the way makeUrl was making the url, I changed it to a simpler way and now it works – Victor Oct 15 '14 at 22:03
0

The problem was in the way makeUrl was making the url, I changed it to a simpler way and now it works.

    public String makeURL (double sourcelat, double sourcelog, double destlat, double destlog ){
        String url = "https://maps.googleapis.com/maps/api/directions/json" +
                "?origin="+Double.toString(sourcelat)+","+Double.toString(sourcelog) +
                "&destination="+Double.toString(destlat)+","+Double.toString(destlog) +
                "&sensor=false" +
                "&mode=walking" +
                "&alternatives=true";

        return url;
 }
Victor
  • 907
  • 2
  • 17
  • 42