Tutorial

Android Google Map - Drawing Route Between two points

Published on August 3, 2022
author

By Anupam Chugh

Android Google Map - Drawing Route Between two points

In this tutorial, we’ll be creating an android application that draws a possible google map route between two points. We’ll be using Google Maps Directions API in our application.

Android Google Map - Drawing Route

Create a new Google Map API Key from the API console using the steps demonstrated in this tutorial. Create a New Android Studio Project and select the template as Google Maps Activity. Add the API key inside the google_maps_api.xml file that resides inside debug->res->values folder This is how the application should look if you’re using the latest Android Studio. android google maps drawing route between two points

Android Google Maps Drawing Path Project Structure

drawing path between two points in google maps android The DirectionsJSONParser.java file is the one that parses the locations and returns the route. decodePoly() method is then invoked to get the polyline data that’s later drawn on the map.

Android Google Maps Drawing Route Code

The MainActivity.java code is given below.

public class MapsActivity extends FragmentActivity implements OnMapReadyCallback {

    private GoogleMap mMap;
    ArrayList markerPoints= new ArrayList();

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_maps);
        // Obtain the SupportMapFragment and get notified when the map is ready to be used.
        SupportMapFragment mapFragment = (SupportMapFragment) getSupportFragmentManager()
                .findFragmentById(R.id.map);
        mapFragment.getMapAsync(this);
    }

    @Override
    public void onMapReady(GoogleMap googleMap) {
        mMap = googleMap;
        LatLng sydney = new LatLng(-34, 151);
        //mMap.addMarker(new MarkerOptions().position(sydney).title("Marker in Sydney"));
        mMap.moveCamera(CameraUpdateFactory.newLatLngZoom(sydney, 16));

        mMap.setOnMapClickListener(new GoogleMap.OnMapClickListener() {
            @Override
            public void onMapClick(LatLng latLng) {

                if (markerPoints.size() > 1) {
                    markerPoints.clear();
                    mMap.clear();
                }

                // Adding new item to the ArrayList
                markerPoints.add(latLng);

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

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

                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 = (LatLng) markerPoints.get(0);
                    LatLng dest = (LatLng) markerPoints.get(1);

                    // Getting URL to the Google Directions API
                    String url = getDirectionsUrl(origin, dest);

                    DownloadTask downloadTask = new DownloadTask();

                    // Start downloading json data from Google Directions API
                    downloadTask.execute(url);
                }

            }
        });

    }

    private class DownloadTask extends AsyncTask {

        @Override
        protected String doInBackground(String... url) {

            String data = "";

            try {
                data = downloadUrl(url[0]);
            } catch (Exception e) {
                Log.d("Background Task", e.toString());
            }
            return data;
        }

        @Override
        protected void onPostExecute(String result) {
            super.onPostExecute(result);

            ParserTask parserTask = new ParserTask();


            parserTask.execute(result);

        }
    }

    private class ParserTask extends AsyncTask<String, Integer, List<List<HashMap>>> {

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

            JSONObject jObject;
            List<List<HashMap>> routes = null;

            try {
                jObject = new JSONObject(jsonData[0]);
                DirectionsJSONParser parser = new DirectionsJSONParser();

                routes = parser.parse(jObject);
            } catch (Exception e) {
                e.printStackTrace();
            }
            return routes;
        }

        @Override
        protected void onPostExecute(List<List<HashMap>> result) {
            ArrayList points = null;
            PolylineOptions lineOptions = null;
            MarkerOptions markerOptions = new MarkerOptions();

            for (int i = 0; i < result.size(); i++) {
                points = new ArrayList();
                lineOptions = new PolylineOptions();

                List<HashMap> path = result.get(i);

                for (int j = 0; j < path.size(); j++) {
                    HashMap 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(12);
                lineOptions.color(Color.RED);
                lineOptions.geodesic(true);

            }

// Drawing polyline in the Google Map for the i-th route
            mMap.addPolyline(lineOptions);
        }
    }

    private String getDirectionsUrl(LatLng origin, LatLng dest) {

        // Origin of route
        String str_origin = "origin=" + origin.latitude + "," + origin.longitude;

        // Destination of route
        String str_dest = "destination=" + dest.latitude + "," + dest.longitude;

        // Sensor enabled
        String sensor = "sensor=false";
        String mode = "mode=driving";

        // Building the parameters to the web service
        String parameters = str_origin + "&" + str_dest + "&" + sensor + "&" + mode;

        // Output format
        String output = "json";

        // Building the url to the web service
        String url = "https://maps.googleapis.com/maps/api/directions/" + output + "?" + parameters;
        

        return url;
    }

    private String downloadUrl(String strUrl) throws IOException {
        String data = "";
        InputStream iStream = null;
        HttpURLConnection urlConnection = null;
        try {
            URL url = new URL(strUrl);

            urlConnection = (HttpURLConnection) url.openConnection();

            urlConnection.connect();

            iStream = urlConnection.getInputStream();

            BufferedReader br = new BufferedReader(new InputStreamReader(iStream));

            StringBuffer sb = new StringBuffer();

            String line = "";
            while ((line = br.readLine()) != null) {
                sb.append(line);
            }

            data = sb.toString();

            br.close();

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

We’ve called an onMapClickListener on the google map object. It’s used to set a marker on the clicked location and store that location in an ArrayList. The ArrayList is used to store the source and destination markers only. The getDirectionsUrl() is called the Directions API URL with the output and parameters as shown below. "https://maps.googleapis.com/maps/api/directions/" + output + "?" + parameters; The output variable holds a “json” string and the parameter string is created as: String parameters = str_origin + "&" + str_dest + "&" + sensor + "&" + mode; We’ve set the mode=driving in the current application. The other modes of transport are:

  • driving (default)
  • walking
  • bicycling
  • transit

The output of the application is given below: android google maps draw path This brings an end to this tutorial. You can download the final project from the link below, add your own Google Map API key.

Download Android Google Maps Draw Route Project

Thanks for learning with the DigitalOcean Community. Check out our offerings for compute, storage, networking, and managed databases.

Learn more about our products

About the author(s)

Category:
Tutorial
Tags:

While we believe that this content benefits our community, we have not yet thoroughly reviewed it. If you have any suggestions for improvements, please let us know by clicking the “report an issue“ button at the bottom of the tutorial.

Still looking for an answer?

Ask a questionSearch for more help

Was this helpful?
 
JournalDev
DigitalOcean Employee
DigitalOcean Employee badge
April 1, 2017

the for loop in onPostExecute isnt getting executed. Please tell me how.

- Anirudh Kaluri

JournalDev
DigitalOcean Employee
DigitalOcean Employee badge
June 29, 2017

i didn’t find DirectionsJSONParser file

- lathiya bhautik

JournalDev
DigitalOcean Employee
DigitalOcean Employee badge
July 7, 2017

Every thing is great, but it doesnt zooms at current location… How to do that?? Please reply ASAP !

- kana

    JournalDev
    DigitalOcean Employee
    DigitalOcean Employee badge
    August 12, 2017

    Hello. thx for your great post. How can i add more than one location and add polyline for it ?

    - Amin

    JournalDev
    DigitalOcean Employee
    DigitalOcean Employee badge
    August 14, 2017

    Hi, Can we mark for more than one locations?

    - Emil

      JournalDev
      DigitalOcean Employee
      DigitalOcean Employee badge
      August 31, 2017

      i found error here, Error:Execution failed for task ‘:app:transformClassesWithDexForDebug’. > com.android.build.api.transform.TransformException: com.android.ide.common.process.ProcessException: java.util.concurrent.ExecutionException: com.android.dex.DexIndexOverflowException: method ID not in [0, 0xffff]: 65536 what must i do …?

      - fajarra

      JournalDev
      DigitalOcean Employee
      DigitalOcean Employee badge
      October 5, 2017

      Cant see a directional route between my marker points…getting a straight line instead… Please help me fix the issue

      - Sjhivani

        JournalDev
        DigitalOcean Employee
        DigitalOcean Employee badge
        January 28, 2018

        nice and clean . thanks

        - erfan

          JournalDev
          DigitalOcean Employee
          DigitalOcean Employee badge
          May 15, 2018

          For me the route is not getting drawn, what could be the issue?

          - Amrut

          JournalDev
          DigitalOcean Employee
          DigitalOcean Employee badge
          May 19, 2018

          Where is DirectionJsonparser.java code?

          - Keshav

            Join the Tech Talk
            Success! Thank you! Please check your email for further details.

            Please complete your information!

            Become a contributor for community

            Get paid to write technical tutorials and select a tech-focused charity to receive a matching donation.

            DigitalOcean Documentation

            Full documentation for every DigitalOcean product.

            Resources for startups and SMBs

            The Wave has everything you need to know about building a business, from raising funding to marketing your product.

            Get our newsletter

            Stay up to date by signing up for DigitalOcean’s Infrastructure as a Newsletter.

            New accounts only. By submitting your email you agree to our Privacy Policy

            The developer cloud

            Scale up as you grow — whether you're running one virtual machine or ten thousand.

            Get started for free

            Sign up and get $200 in credit for your first 60 days with DigitalOcean.*

            *This promotional offer applies to new accounts only.