Get Even More Visitors To Your Blog, Upgrade To A Business Listing >>

Google Maps Draw Route between two points using Google Directions in Google Map Android API V2

Google Maps Draw Route


In this post we will develop an Android App to draw route on google maps (namely Google Maps Draw Route). Here we will first add our location on google map and then allow user to select two points. A marker will be added to those two points and a route will be drawn.



Pre-requisites:

1) Android Studio installed on your PC (Unix or Windows). You can learn how to install it here .
2) A real time android device (Smartphone or Tablet) configured with Android Studio. .
3) A basic knowledge of Android lifecycle and different classes & functions used in Android Studio.

Before going through this post we will suggest you to first have a look at our post on How to get current location in Android Google Map. That information (inside link) will be used in this post.

Now let’s make it. We hope you would have already made an App to display current user location. So we are not repeating that part now.

Creating new project

Please follow following steps:

  1. Open Android Studio and make a new project with name “Google Maps Draw Route” and company domain application.example.com (I used my company domain i.e androidtutorialpoint.com. Similarly you can use yours).
  2. Click Next and choose android version Lollipop. Again Click Next and Choose Google Maps Activity (as shown in following pic).
  3. Leave all things remaining same and Click Finish.

Now you will be able to see three files:

  1. google_maps_api.xml (…/GoogleMapsDrawRoute/app/src/debug/res/values/google_maps_api.xml)
  2. MapsActivity.java (…/GoogleMapsDrawRoute/app/src/main/java/com/androidtutorialpoint/googlemapsdrawroute/MapsActivity.java)
  3. AndroidManifest.xml ( …/GoogleMapsDrawRoute/app/src/main/AndroidManifest.xml)

Configuring Google Play Services

Open google_maps_api.xml. Here you will find a lot of information along with a link. Copy-Paste this link in your web browser. Make a Gmail account also through which you will configure google play services.

Now at the browser choose “Create New Project” and Click Continue. Following screen will be displayed:

Click on Go to credentials. Below screen will appear.

Create your key by clicking Create. Now a key will be created that you shall copy and paste in google_maps_api.xml. Copy paste it in place where YOUR_KEY_HERE is written:

Code inside google_maps_api.xml is complete.

google_maps_api.xml


LVwrKoLOEMgwUBXGiut0bkFhoAjOiaVemoMlymg

Code Inside AndroidManifest.xml:

If you go inside AndroidManifest.xml then this key will be displayed in meta tags. Here you need to add permissions for accessing location of device. The required permission should be as follows:

ACCESS_NETWORK_STATE – To check network state i.e if we are connected to any network or not.
INTERNET – If we are connected to Internet or not.
ACCESS_COARSE_LOCATION – To determine user’s location using WiFi and mobile. It will give us an approximate location.
ACCESS_FINE_LOCATION – To determine user’s location using GPS. It will give us precise location.
OpenGL ES V2 – Required for Google Maps V2

AndroidManifest.xml

  

Code inside MapsActivity.java:

This is heart of our code. We will divide this code into parts and debug it one by one. Here we won’t discuss code related to getting current user location. You can get that information here.

1) Setting OnClickListener:

  // Setting onclick event listener for the map
        mMap.setOnMapClickListener(new GoogleMap.OnMapClickListener() {

            @Override
            public void onMapClick(LatLng point) {

                // Already two locations
                if (MarkerPoints.size() > 1) {
                    MarkerPoints.clear();
                    mMap.clear();
                }

                // Adding new item to the ArrayList
                MarkerPoints.add(point);

                // Creating MarkerOptions
                MarkerOptions options = new MarkerOptions();

                // Setting the position of the marker
                options.position(point);

                /**
                 * For the start location, the color of marker is GREEN and
                 * for the end location, the color of marker is RED.
                 */
                if (MarkerPoints.size() == 1) {
                    options.icon(BitmapDescriptorFactory.defaultMarker(BitmapDescriptorFactory.HUE_GREEN));
                } else if (MarkerPoints.size() == 2) {
                    options.icon(BitmapDescriptorFactory.defaultMarker(BitmapDescriptorFactory.HUE_RED));
                }


                // Add new marker to the Google Map Android API V2
                mMap.addMarker(options);

                // Checks, whether start and end locations are captured
                if (MarkerPoints.size() >= 2) { 
                    LatLng origin = MarkerPoints.get(0);
                    LatLng dest = MarkerPoints.get(1);

                    // Getting URL to the Google Directions API
                    String url = getUrl(origin, dest);
                    Log.d("onMapClick", url.toString());
                    FetchUrl FetchUrl = new FetchUrl();

                    // Start downloading json data from Google Directions API
                    FetchUrl.execute(url);
                    //move map camera
                    mMap.moveCamera(CameraUpdateFactory.newLatLng(origin));
                    mMap.animateCamera(CameraUpdateFactory.zoomTo(11));
                }

            }
        });

Above code will be executed as soon as user tap on Android screen. It will be used to place marker at the points between which path will be drawn. Coordinates of tapped points will be accessed and stored using MarkerPoints.get() and LatLng origin respectively.Url will be fetched and implemented using Async Task FetchUrl.

2) Async Task:

AsyncTask is an abstract class provided by Android which helps us to use the UI thread properly. This class allows us to perform long/background operations and show its result on the UI thread without having to manipulate threads. You can get more information about it here. Here doInBackground task will be implemented in background and onPostExecute will be shown on GUI.

  // Fetches data from url passed
    private class FetchUrl extends AsyncTask {

        @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.toString());
            } 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);

        }
    }
  

downloadUrl is used to fecth url from web service and result is parsed using ParserTask (Async Task).

3) Code inside downloadUrl:

  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.toString());
            br.close();

        } catch (Exception e) {
            Log.d("Exception", e.toString());
        } finally {
            iStream.close();
            urlConnection.disconnect();
        }
        return data;
    }
  

Data returned from web will be in json format which user can get using HttpURLConnection. You can get more information about how to get data over web here. So this task will return json data returned from web.

4) Code inside Parser Task:

Define a new class with the name ParserTask which will parse the Json data retuned by downloadUrl.

private class ParserTask extends AsyncTask>>> {

        // Parsing the data in non-ui thread
        @Override
        protected List>> doInBackground(String... jsonData) {

            JSONObject jObject;
            List>> routes = null;

            try {
                jObject = new JSONObject(jsonData[0]);
                Log.d("ParserTask",jsonData[0].toString());
                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>> result) {
            ArrayList points;
            PolylineOptions lineOptions = null;

            // Traversing through all the routes
            for (int i = 0; i ();
                lineOptions = new PolylineOptions();

                // Fetching i-th route
                List> path = result.get(i);

                // Fetching all the points in i-th route
                for (int j = 0; j  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.RED);

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

In the above code doInBackground will actually parse the data and onPostExecute will draw route on Google Maps.

5) Parsing data:

Make a separate java class with the name DataParser at the path: GoogleMapsDrawRoute/app/src/main/java/com/androidtutorialpoint/googlemapsdrawroute/

DataParser class


public class DataParser {

    /** Receives a JSONObject and returns a list of lists containing latitude and longitude */
    public List>> parse(JSONObject jObject){

        List>> routes = new ArrayList() ;
        JSONArray jRoutes;
        JSONArray jLegs;
        JSONArray jSteps;

        try {

            jRoutes = jObject.getJSONArray("routes");

            /** Traversing all routes */
            for(int i=0;i();

                /** Traversing all legs */
                for(int j=0;j list = decodePoly(polyline);

                        /** Traversing all points */
                        for(int l=0;l 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 e){
        }


        return routes;
    }


    /**
     * Method to decode polyline points
     * Courtesy : http://jeffreysambells.com/2010/05/27/decoding-polylines-from-google-maps-direction-api-with-java
     * */
    private List decodePoly(String encoded) {

        List poly = new ArrayList();
        int index = 0, len = encoded.length();
        int lat = 0, lng = 0;

        while (index = 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) = 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;
    }
}
  

In the above code, I have added comments wherever required. Still if you have doubt then please ask in comments.

6) Draw route on google maps:

Route is drawn using Google Maps polyline. Add following code in onPostExecute :

onPostExecute

        @Override
        protected void onPostExecute(List>> result) {
            ArrayList points;
            PolylineOptions lineOptions = null;

            // Traversing through all the routes
            for (int i = 0; i ();
                lineOptions = new PolylineOptions();

                // Fetching i-th route
                List> path = result.get(i);

                // Fetching all the points in i-th route
                for (int j = 0; j  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.RED);

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

Finally in the above code points are fetched from result and drawn on Google Map.ArrayList points is used to store position on Google Map. Route is drawn using google maps polyline lineOptions.addAll(points).

You can see full code in following files:

MapsActivity.java
DataParser.java
google_maps_api.xml
AndroidManifest.xml

So finally our app is complete. We would suggest you to turn on GPS and Internet Connection. Run this route maker on any real android device. It will first display your location. Now tap on any two locations and it will show route between them.



What’s Next

You can experiment with different locations around world and even make a list of bars or restaurants near you and draw path between them. Moreover you can learn How to search nearby locations and add marker on places like Restaurants, Schools, Hospitals etc. in Google Maps.

Thanks for reading guys. If you have any doubt or suggestions then please comment. Don’t forget to subscribe our blog for latest android tutorials. Also do Like our Facebook Page or Add us on Twitter. Happy Coding

You can download full code below



CodeProject





The post Google Maps Draw Route between two points using Google Directions in Google Map Android API V2 appeared first on Android Tutorial Point.



This post first appeared on Android Tutorial Point, please read the originial post: here

Share the post

Google Maps Draw Route between two points using Google Directions in Google Map Android API V2

×

Subscribe to Android Tutorial Point

Get updates delivered right to your inbox!

Thank you for your subscription

×