Main navigation

Google Maps Distance Calculator using Google Directions in Google Maps Android API

adsense

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.

Creating new project for Google Maps Distance Calculator

Please follow following steps:

  1. Open Android Studio and make a new project with name “Google Maps Distance Calculator” or “Google Maps Retrofit” 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. Google_Map_Activity

  4. Leave all things remaining same and Click Finish.

Now you will be able to see three files:

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

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 through which you will configure google play services.

Google Maps Distance Calculator

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

Google Maps Search Nearby

Click on Go to credentials. Below screen will appear.

Google Maps Distance Calculator

Create your key by clicking Create. Now a key will be created but there is one big change here as compared to our previous Google Maps tutorials. Here you will need a Server Key. So to generate a Server Key click on Create Credentials and then API Key as shown in the following image:

Google Maps Distance Calculator

Click on Server Key. Below screen will appear:

Google Maps Distance Calculator

Click Create and copy the Server Key generated. You shall copy and paste this key 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

<resources>
    <!--
    TODO: Before you run your application, you need a Google Maps API key.

    To get one, follow this link, follow the directions and press "Create" at the end:

    https://console.developers.google.com/flows/enableapi?apiid=maps_android_backend&keyType=CLIENT_SIDE_ANDROID&r=xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx%3Bcom.androidtutorialpoint.googlemapsdistancecalculator

    You can also add your credentials to an existing key, using this line:
    xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx;com.androidtutorialpoint.googlemapsdistancecalculator

    Alternatively, follow the directions here:
    https://developers.google.com/maps/documentation/android/start#get-key

    Once you have your key (it starts with "AIza"), replace the "google_maps_key"
    string in this file.
    -->
    <string name="google_maps_key" templateMergeStrategy="preserve" translatable="false">AIzaSyBwGDnq_Ceg2ibDPSOv2dtxyin7n3LQPv0</string>
</resources>

Also one more thing to do here is to enable corresponding directions API. In the following image click Google Maps Directions API and then enable it:

Google Maps Distance Calculator

Code Inside AndroidManifest.xml of Google Maps Distance Calculator App

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

<?xml version="1.0" encoding="utf-8"?>
<manifest package="com.androidtutorialpoint.googlemapsdistancecalculator"
          xmlns:android="https://schemas.android.com/apk/res/android">

    <!--
         The ACCESS_COARSE/FINE_LOCATION permissions are not required to use
         Google Maps Android API v2, but you must specify either coarse or fine
         location permissions for the 'MyLocation' functionality. 
    -->
    <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>

    <application
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:supportsRtl="true"
        android:theme="@style/AppTheme">

        <!--
             The API key for Google Maps-based APIs is defined as a string resource.
             (See the file "res/values/google_maps_api.xml").
             Note that the API key is linked to the encryption key used to sign the APK.
             You need a different API key for each encryption key, including the release key that is used to
             sign the APK for publishing.
             You can define the keys for the debug and release targets in src/debug/ and src/release/. 
        -->
        <meta-data
            android:name="com.google.android.geo.API_KEY"
            android:value="@string/google_maps_key"/>

        <activity
            android:name=".MapsActivity"
            android:label="@string/title_activity_maps">
            <intent-filter>
                <action android:name="android.intent.action.MAIN"/>

                <category android:name="android.intent.category.LAUNCHER"/>
            </intent-filter>
        </activity>
    </application>

</manifest>

Code inside activity_maps.xml:

Here we will add two buttons each for Driving and Walking mode such that when user clicks on Driving mode then route, distance and duration will be calculated according to Driving mode. Similarly in case of Walking. So you will always find that for walking mode, duration is always more and distance is always less than driving mode. We will also add a Text to show distance and time between origin and destination in Google Maps Distance Calculator App. For this, we will use FrameLayout .

activity_maps.xml

<FrameLayout
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    xmlns:android="https://schemas.android.com/apk/res/android">


    <fragment android:id="@+id/map"
              android:name="com.google.android.gms.maps.SupportMapFragment"
              xmlns:android="https://schemas.android.com/apk/res/android"
              xmlns:tools="https://schemas.android.com/tools"
              android:layout_width="match_parent"
              android:layout_height="match_parent"
              tools:context="com.androidtutorialpoint.googlemapsdistancecalculator.MapsActivity"/>

    <LinearLayout xmlns:android="https://schemas.android.com/apk/res/android"
                  xmlns:tools="https://schemas.android.com/tools"
                  android:layout_width="match_parent"
                  android:layout_height="wrap_content"
                  android:orientation="vertical">

        <TextView
            android:id="@+id/show_distance_time"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:textColor="#ff0000"
            android:textColorHighlight="@android:color/primary_text_dark"
            android:textSize="30dp" />

        <LinearLayout xmlns:android="https://schemas.android.com/apk/res/android"
                      xmlns:tools="https://schemas.android.com/tools"
                      android:layout_width="match_parent"
                      android:layout_height="wrap_content"
                      android:layout_alignParentBottom="true">
            <Button
                android:id="@+id/btnDriving"
                android:layout_width="0dp"
                android:layout_height="wrap_content"
                android:layout_weight="1"
                android:text="Driving Mode" />

            <Button
                android:id="@+id/btnWalk"
                android:layout_width="0dp"
                android:layout_height="wrap_content"
                android:layout_weight="1"
                android:text="Walking Mode" />
        </LinearLayout>

    </LinearLayout>
</FrameLayout>

Note: Please see your build.gradle file. It should have following code:

dependencies {

    compile fileTree(dir: 'libs', include: ['*.jar'])
    testCompile 'junit:junit:4.12'
    compile 'com.android.support:appcompat-v7:23.1.1'
    compile 'com.google.android.gms:play-services:8.4.0'
    compile 'com.squareup.retrofit:retrofit:2.0.0-beta2'
    compile 'com.google.code.gson:gson:1.7.2'
    compile 'com.squareup.retrofit:converter-gson:2.0.0-beta2'
    compile 'com.squareup.okhttp:okhttp:2.4.0'

}

Fourth line compile ‘com.google.android.gms:play-services:8.4.0’ is responsible for inserting Google Play Services. Please make sure this line is present in build.gradle. Remaining lines after 4th line are responsible for adding Retrofit Android library files. Sync the Project.

Implementation of Google Maps Distance Calculator using Retrofit

To make it clear we first have to see how URL of Google Maps Distance Calculator API is implemented. Click on following link:

Google Maps Distance Calculator Response

This is what will return by Google Server when we provide origin and destination coordinates to Google. As you could see in the link we have JSON Object and Array as data returned from Google Maps. We have to capture this data in our App and accordingly draw route and print distance and duration. You can read more about this URL at Google developer site. To capture this data using Retrofit Android, we have to make POJO Class. This class is actually composed of Getter and Setter methods.

Adding POJO Class

Add following classes in a separate folder named POJO at path …/GoogleMapsDistanceCalculator/app/src/main/java/com/androidtutorialpoint/googlemapsdistancecalculator/POJO

Post all the POJO files here

File structure will finally look like this:

Google Maps Distance Calculator

These POJO classes are used to get attribute values from server.

Interface Declaration

Make a new interface named RetrofitMaps.java and add following code:

package com.androidtutorialpoint.googlemapsdistancecalculator;

import com.androidtutorialpoint.googlemapsdistancecalculator.POJO.Example;

import retrofit.Call;
import retrofit.http.GET;
import retrofit.http.Query;

/**
 * Created by navneet on 17/7/16.
 */
public interface RetrofitMaps {

    /*
     * Retrofit get annotation with our URL
     * And our method that will return us details of student.
     */
    @GET("api/directions/json?key=AIzaSyC22GfkHu9FdgT9SwdCWMwKX1a4aohGifM")
    Call<Example> getDistanceDuration(@Query("units") String units, @Query("origin") String origin, @Query("destination") String destination, @Query("mode") String mode);

}

In the above interface @GET is used to call server (corresponding to URL). It is predefined part of Retrofit android library, only end part of URL will be added here. Here we have added key as part of the URL while rest of the variable (units, origin, mode and destination) will be passed at run time using Query in getDistanceDuration(). getDistanceDuration method is used to get details of the points returned from Google Server and Example is a POJO class to store that response. Also Origin and Destination will be provided according to the coordinates on which user clicks on map and mode will be provided according to the switch user choose (Driving or Walking).

MapsActivity.java

This is one of the most important part of our Google Maps Distance Calculator App and hence we will debug this code bit by bit. At the end of the tutorial you can see full code. First of all we will ask for user permission. Beginning in Android 6.0 (API level 23), users grant permissions to apps while the app is running, not when they install the app. This approach streamlines the app install process, since the user does not need to grant permissions when they install or update the app

public static final int MY_PERMISSIONS_REQUEST_LOCATION = 99;
    public boolean checkLocationPermission(){
        if (ContextCompat.checkSelfPermission(this,
                Manifest.permission.ACCESS_FINE_LOCATION)
                != PackageManager.PERMISSION_GRANTED) {

            // Asking user if explanation is needed
            if (ActivityCompat.shouldShowRequestPermissionRationale(this,
                    Manifest.permission.ACCESS_FINE_LOCATION)) {

                // Show an explanation to the user *asynchronously* -- don't block
                // this thread waiting for the user's response! After the user
                // sees the explanation, try again to request the permission.

                //Prompt the user once explanation has been shown
                ActivityCompat.requestPermissions(this,
                        new String[]{Manifest.permission.ACCESS_FINE_LOCATION},
                        MY_PERMISSIONS_REQUEST_LOCATION);


            } else {
                // No explanation needed, we can request the permission.
                ActivityCompat.requestPermissions(this,
                        new String[]{Manifest.permission.ACCESS_FINE_LOCATION},
                        MY_PERMISSIONS_REQUEST_LOCATION);
            }
            return false;
        } else {
            return true;
        }
    }

Drawing Route and Calculating Distance and Duration of Google Maps Distance Calculator

Now we will first build Retrofit and then show the response from Google Server.

private void build_retrofit_and_get_response(String type) {

        String url = "https://maps.googleapis.com/maps/";

        Retrofit retrofit = new Retrofit.Builder()
                .baseUrl(url)
                .addConverterFactory(GsonConverterFactory.create())
                .build();

        RetrofitMaps service = retrofit.create(RetrofitMaps.class);

        Call<Example> call = service.getDistanceDuration("metric", origin.latitude + "," + origin.longitude,dest.latitude + "," + dest.longitude, type);

        call.enqueue(new Callback<Example>() {
            @Override
            public void onResponse(Response<Example> response, Retrofit retrofit) {

                try {
                    //Remove previous line from map
                    if (line != null) {
                        line.remove();
                    }
                    // This loop will go through all the results and add marker on each location.
                    for (int i = 0; i < response.body().getRoutes().size(); i++) {
                        String distance = response.body().getRoutes().get(i).getLegs().get(i).getDistance().getText();
                        String time = response.body().getRoutes().get(i).getLegs().get(i).getDuration().getText();
                        ShowDistanceDuration.setText("Distance:" + distance + ", Duration:" + time);
                        String encodedString = response.body().getRoutes().get(0).getOverviewPolyline().getPoints();
                        List<LatLng> list = decodePoly(encodedString);
                        line = mMap.addPolyline(new PolylineOptions()
                                        .addAll(list)
                                        .width(20)
                                        .color(Color.RED)
                                        .geodesic(true)
                        );
                    }
                } catch (Exception e) {
                    Log.d("onResponse", "There is an error");
                    e.printStackTrace();
                }
            }

            @Override
            public void onFailure(Throwable t) {
                Log.d("onFailure", t.toString());
            }
        });

    }

Above function build_retrofit_and_get_response will be called when a user clicks on Walking or Driving switch. Corresponding to the type of switch clicked, mode will be selected to calculate distance and time. First of all, we build Retrofit using Retrofit.Builder() and converted JSON data into accessible data object using GsonConverterFactory. You can read more about GSON. After this we passed our interface RetrofitMaps to the retrofit to get the details. Now comes the last but most important part i.e. Executing call and displaying distance and time according to the mode selected and drawing route.
Calls may be executed synchronously with execute(), or asynchronously with enqueue(). enqueue() will Asynchronously send the request and notify callback of its response or if an error occurred talking to the server, creating the request, or processing the response. If response comes then onResponse will be automatically called. If response doesn’t come out then onFailure will be called and reason of failure will be printed in Google Maps Distance Calculator App.

While calling getDistanceDuration we are passing latitude and longitude coordinates of Origin and Destination, between which we want to calculate distance and duration. Also mode of travel is provided as Driving or Walking. After getting response from server onResponse is called automatically. In this method we are first removing any previous route drawn using line.remove(). Then a loop is initiated to get distance and duration of travel. We get all data through getter methods defined in POJO Classes. For Example to get the distance in Google Maps Distance Calculator App, we used getter methods getRoutes(), getLegs() and getDistance(). Also route is drawn between origin and destination using mMap.addPolyline().

So Finally our tutorial of Google Maps Distance Calculator App is complete. You can see full code of MainActivity.java here:

MainActivity.java

We would suggest you to turn on GPS and Internet Connection. Run this App on any real android device. Tap on Google Map to select origin and destination. Select either Walking or Driving mode. According to mode selected, it will display Distance and Duration of travel between origin and destination along with route drawn as shown in following figure:

Google Maps Distance Calculator

You can see demo of Google Maps Distance Calculator in the Youtube video given at the start of tutorial. We have tried to explain each and every step but still if you have any doubt then please comment. Also we are open to suggestions of any future tutorials. All the best 🙂 .



What’s Next

Now you can learn how to show current user location in our tutorial of How to get current location in Android Google Map. You can also learn how to display nearby places in our tutorial of Google Maps Nearby Places API using Retrofit Android.

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


Android Tutorial Point Download Now


Reader Interactions

Comments

  1. How to add turn-by-turn navigation to this project.When I checked the map API that we using here it is having details about the route in the field named “html_instructions”. I wanna develop an app having turn-by-turn navigation in which the pointer moves according to our movement like google map navigation.And this live movement of one person should be able to share with another person,so that he can track that person lively,like Uber monitor the ride of our friends or family.What else should I add to this project to fulfill my requirements?

      • Thanks for your reply.I have already added this part. I am getting current location and it is getting updated when we move.Please help me to create a link that I can share with my friends so that they can track my location in map lively.

      • I got an error in getLegs() and getOverviewPolyline() and getDuration() as undefined , is it anything forgotten ? Thank you

        String distance = response.body().getRoutes().get(i).getLegs().get(i).getDistance().getText();

        String time = response.body().getRoutes().get(i).getLegs().get(i).getDuration().getText();
        ShowDistanceDuration.setText(“Distance:” + distance + “, Duration:” + time);

        String encodedString = response.body().getRoutes().get(0).getOverviewPolyline().getPoints();

  2. great tutorial but i have problem on this line
    Call call = service.getDistanceDuration(“metric”, origin.latitude + “,” + origin.longitude, dest.latitude + “,” + dest.longitude, type);

    this line is not integrate it require com…..POJO.Example; but it have only Example
    where are problem ?

    • the problem arising from that package name ,try to ensure the package name of Example class that you are imported.(Package name may different from Source code)

        • Hi Abulhasan,

          Try downloading our code through “Download Now” Button given in tutorial and run it. It will surely work. Then you can compare your code with the one we provided. All the Best !!

  3. Hi,

    Today, I;m very happy because I was searching for this tutorial and finally, I found on your site.

    You have explained in detail with code.

    Thanks for sharing this

  4. Your step by step information makes your blog different than other blogs. I really enjoyed this article and I would love to share on google+, facebook, and twitter.

  5. Your every articles on google map are worth reading.

    I will share this articles with my friends and on social media.

  6. some time when i click on drive mode button then not gave the distance and time ? only first time gave the time and sistance.

  7. Hi, this tutorial is nice and very useful for me.
    I have one more doubt, how to compare two routes. If my friend is driving from chennai to trichy, and I am also driving from chennai to trichy, how to compare and get to know that these two routes are same. Thanks in advance.

  8. Hello thanks for this article
    i have an issue ! when i click on the buttons nothing happens !
    i made a little change that the map appears on a fragment not an activity everything works but the button onclick!

  9. Without using the setRoutes() of Examples, how is the response.body().getRoutes() returning values for you guys. I am getting empty array.

  10. Hello thanks for the article
    it’s work properly but i want to draw the route from current location to destination.
    i had already enable the current location marker but how to pass that coordinates as origin. And i used retrofit to call the API.

  11. Thanks a lot androidtutorialspopint.com
    i’have learning all the android conceote through your articles.
    it helped me a lot.
    keep posting… keep helping(actually you r doing)…
    THANKS AGAIN

  12. Greate post. Keep poting such kind of information on your page.
    Im really impressed by your blog.
    Heyy there, You’ve performed a fanntastic job.

    I’ll definitely digg it annd iin my view suggest to
    my friends. I’m confident they will be benefited from this website.

  13. I discovered your weblog website on google and examine a few of your early posts. Continue to maintain up the superb operate. I simply further up your RSS feed to my MSN Information Reader. Looking for forward to studying extra from you afterward!…

  14. Hello. Can you update this project with speed between these two points on the map, something like car tracker? Is it possible?

  15. Call call = service.getDistanceDuration(“metric”, origin.latitude + “,” + origin.longitude, dest.latitude + “,” + dest.longitude, type);

    I am getting an error of null pointer exception in my code as well as in your code that I have downloaded from your code. Please help me with that

  16. Call call = service.getDistanceDuration(“metric”, origin.latitude + “,” + origin.longitude, dest.latitude + “,” + dest.longitude, type); getting null pointer exception in this line

  17. Sir your tutorials are the best. I have one question. Is possible fromJSON file get directions in listview above map fragment instead calculating distance and time.
    For example: (user picked two places)
    1.drive straight 1km
    2.turn left and drive 5km
    3.turn left and drive 2km

  18. Sir,
    can I call retrofit periodically inside button’s onClickListener.
    Is there any command for it.
    Thanks

  19. If I wish to do multiple destination, how to total up the route distance and time? Can you show me the codes for me? Because i can’t add up the distances and times after convert them into double.

Leave a Reply

Advertisment ad adsense adlogger