Android Example: Display Current Location on Google Map with FusedLocationProviderClient

Spread knowledge

This article is updated and uses the latest FusedLocationProviderClient API to fetch current location

Maps in mobile applications have taken customer experience to a whole new level. Whether its displaying the current location or showing directions to your business office, maps have always been very useful. The good news here is even though displaying the complete world map inside your app might sound a very complex task thanks to Google its ridiculously easy

In this tutorial we will deal with the basics of Google Location and Map APIs. We will register our project in Google Developer Console and obtain the API key . Using the API key we will show the Map in our app and with the help of FusedLocationProvider API mark the current location on the map.

Create a Activity:

In this example we will be showing our map inside a Activity . Hence we should create a Activity class which extends Fragment Activity. This activity will be named MapsActivity

public class MapsActivity extends FragmentActivity {

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_maps);

    }
}

Fetching Current Location:

Basically there are two methods for obtaining location in Android

  1. Android Framework – LocationManager API
  2. Google Play Services – FusedLocationProvider API

Android docs encourages us to use FusedLocation APIs as they are found to be more accurate and easy to implement

Check for permissions :

As of Android Marshmallow device location permission should to be asked at runtime rather than at install time (You can read more about this here ). If you plan to target Marshmallow devices you need to follow the steps below

  • Add the following to AndroidManifest.xml
    <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>
  •  Basically before fetching user location you need to check if the user has granted location permissions for this app. If the permission is not granted you can explicity request using ActivityCompat.requestPermissions() API. User will then see a system dialog with two option “YES” and “NO”
//Checking if the user has granted location permission for this app
if (ActivityCompat.checkSelfPermission(this, android.Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission(this, android.Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {

    /*
    Requesting the Location permission
    1st Param - Activity
    2nd Param - String Array of permissions requested
    3rd Param -Unique Request code. Used to identify these set of requested permission
    */
    ActivityCompat.requestPermissions(this, new String[] {
        android.Manifest.permission.ACCESS_FINE_LOCATION
    }, LOCATION_REQUEST_CODE);
    return;
}
  •  Once any of the option on the dialog is clicked onRequestPermissionResult is invoked. You need to override this in your MapsActivity
public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {
    switch (requestCode) {
        case LOCATION_REQUEST_CODE:
            if (grantResults.length > 0 && grantResults[0] == PERMISSION_GRANTED) {
                //Permission Granted
            } else
                Toast.makeText(this, "Location Permission Denied", Toast.LENGTH_SHORT).show();
            break;

    }

}

Current Location with FusedLocationProviderClient

  • From version 11.6.0 Google now recommends us to use FusedLocationProviderClient to fetch current location. Unlike FusedLocationProviderApi this takes care of all the connection logic on its own.

    We have a separate article about FusedLocationProviderClient explaining its benefits along with an example. I highly recommend you to read it.

  • Add the following dependency to build.gradle
implementation 'com.google.android.gms:play-services-location:11.6.0'
  • In the code snippet below we fetch the user’s current location with FusedLocationProviderClient in the activity’s onCreate method. For this example I am not explaining each step of fetching current location as it is out of scope for this tutorial. If you wish to understand it read this  tutorial which explains fetching current location in Android.
public class MapsActivity extends FragmentActivity {

    private Location currentLocation;

    private FusedLocationProviderClient fusedLocationProviderClient;

    private static final int LOCATION_REQUEST_CODE = 101;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        fusedLocationProviderClient = LocationServices.getFusedLocationProviderClient(this);
        if (ActivityCompat.checkSelfPermission(MapsActivity.this, android.Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission(MapsActivity.this, android.Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
            ActivityCompat.requestPermissions(this, new String[] {android.Manifest.permission.ACCESS_FINE_LOCATION}, LOCATION_REQUEST_CODE);
            return;
        }
        fetchLastLocation();
    }

    private void fetchLastLocation(){
        Task<Location> task = fusedLocationProviderClient.getLastLocation();
        task.addOnSuccessListener(new OnSuccessListener<Location>() {
            @Override
            public void onSuccess(Location location) {
                if (location != null) {
                    currentLocation = location;
                    Toast.makeText(MapsActivity.this,currentLocation.getLatitude()+" "+currentLocation.getLongitude(),Toast.LENGTH_SHORT).show();
                    SupportMapFragment supportMapFragment= (SupportMapFragment) getSupportFragmentManager().findFragmentById(R.id.map);
                    supportMapFragment.getMapAsync(MapsActivity.this);
                }else{
                    Toast.makeText(MapsActivity.this,"No Location recorded",Toast.LENGTH_SHORT).show();
                }
            }
        });
    }

    @Override
    public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResult) {
        switch (requestCode) {
            case LOCATION_REQUEST_CODE:
                if (grantResult.length > 0 && grantResult[0] == PackageManager.PERMISSION_GRANTED) {
                    fetchLastLocation();
                } else {
                    Toast.makeText(MapsActivity.this,"Location permission missing",Toast.LENGTH_SHORT).show();
                }
                break;

        }
    }
}

The above code will give us the current location of the device. But as we are planning to show that location inside a map we now need to integrate Google Maps in our application

Register your App

In order for your app to show Google maps you will have to register it with Google Developer Console. Steps on how to register your app are mentioned here

Integrate Google Maps:

Once you have your API key you can now go ahead and begin the integration.

  • Before beginning as always we need to add the Google services dependency for Maps in our build.gradle
implementation 'com.google.android.gms:play-services-maps:11.6.0'
  • Add the following to AndroidManifest.xml under the application tag

    <meta-data
     android:name="com.google.android.geo.API_KEY"
     android:value="@string/google_maps_key" />
  • Create a file by the name google_maps_api.xml in the res>values folder.You will have to add the API Key created in the first step in this file.
<resources>
    <string name="google_maps_key" templateMergeStrategy="preserve" translatable="false">[YOUR-API-KEY]</string>
</resources>
  • Add the following fragment to the layout file for your MapsActivity. Placing the SupportMapFragment is the simplest way of displaying a map in your app. SupportMapFragment is basically a wrapper around a MapView to automatically handle the necessary life cycle needs.
<fragment
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:map="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:id="@+id/map"
    android:name="com.google.android.gms.maps.SupportMapFragment"
    android:layout_width="match_parent"
    android:layout_height="match_parent"/>

Note: You can also display a map by using a MapView in your own activity. But then you will have to explicitly handle all the lifecycle callbacks while  MapFragment handles these for you.

  • Now initialize the SupportMapFragment object from the activity’s layout file using findFragmentById as shown below. Then attach OnMapReadyCallback listener on the object using getMapAsync(OnMapReadyCallback) API. This listener will notify you when the map is ready by invoking onMapReady along with a GoogleMap object.  GoogleMap is the main class of the Google Maps Android API and is the entry point for all methods related to the map
    SupportMapFragment supportMapFragment= (SupportMapFragment) getSupportFragmentManager().findFragmentById(R.id.map);
    supportMapFragment.getMapAsync(MapsActivity.this);
  • As seen in the above code snippet your MapActivity will act as the listener and therefore should implement OnMapReadyCallback interface and override onMapReady method.
public class MapActivity extends AppCompatActivity implements OnMapReadyCallback {

    ...    
  
    @Override
    public void onMapReady(GoogleMap googleMap) {

    }
}
  • As already mentioned onMapReady is invoked when the map is ready. Therefore we can then mark the current location on the map as shown below
@Override
 public void onMapReady(GoogleMap googleMap) {

     LatLng latLng = new LatLng(currentLocation.getLatitude(),currentLocation.getLongitude());
     //MarkerOptions are used to create a new Marker.You can specify location, title etc with MarkerOptions
     MarkerOptions markerOptions = new MarkerOptions().position(latLng).title("You are Here");

     googleMap.animateCamera(CameraUpdateFactory.newLatLng(latLng));

     //Adding the created the marker on the map
     googleMap.addMarker(markerOptions);

 }

Complete Activity

We explained the complete logic in steps above, now let us have a look at the complete activity

public class MapsActivity extends FragmentActivity implements OnMapReadyCallback {

    private Location currentLocation;

    private FusedLocationProviderClient fusedLocationProviderClient;

    private static final int LOCATION_REQUEST_CODE =101;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        fusedLocationProviderClient = LocationServices.getFusedLocationProviderClient(this);
        if (ActivityCompat.checkSelfPermission(MapsActivity.this, android.Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission(MapsActivity.this, android.Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
            ActivityCompat.requestPermissions(this, new String[] {android.Manifest.permission.ACCESS_FINE_LOCATION}, LOCATION_REQUEST_CODE);
            return;
        }
        fetchLastLocation();
    }

    private void fetchLastLocation(){
        Task<Location> task = fusedLocationProviderClient.getLastLocation();
        task.addOnSuccessListener(new OnSuccessListener<Location>() {
            @Override
            public void onSuccess(Location location) {
                if (location != null) {
                    currentLocation = location;
                    Toast.makeText(MapsActivity.this,currentLocation.getLatitude()+" "+currentLocation.getLongitude(),Toast.LENGTH_SHORT).show();
                    SupportMapFragment supportMapFragment= (SupportMapFragment) getSupportFragmentManager().findFragmentById(R.id.map);
                    supportMapFragment.getMapAsync(MapsActivity.this);
                }else{
                    Toast.makeText(MapsActivity.this,"No Location recorded",Toast.LENGTH_SHORT).show();
                }
            }
        });
    }

    @Override
    public void onMapReady(GoogleMap googleMap) {

        LatLng latLng = new LatLng(currentLocation.getLatitude(),currentLocation.getLongitude());
        //MarkerOptions are used to create a new Marker.You can specify location, title etc with MarkerOptions
        MarkerOptions markerOptions = new MarkerOptions().position(latLng).title("You are Here");

        googleMap.animateCamera(CameraUpdateFactory.newLatLng(latLng));

        //Adding the created the marker on the map
        googleMap.addMarker(markerOptions);

    }

    @Override
    public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResult) {
        switch (requestCode) {
            case LOCATION_REQUEST_CODE:
                if (grantResult.length > 0 && grantResult[0] == PackageManager.PERMISSION_GRANTED) {
                    fetchLastLocation();
                } else {
                    Toast.makeText(MapsActivity.this,"Location permission missing",Toast.LENGTH_SHORT).show();
                }
                break;

        }
    }
}

Conclusion

That’s it! I hope this tutorial helped you. If YES please share it with your friends. Don’t forget to like and comment. Also if you want to learn how to customize Google Maps in your application read this.

Want to know how to further customize Google map inside in your Android application ? Read this 

Want to know how to track location changes while travelling on your device. Read this


Spread knowledge

8 Replies to “Android Example: Display Current Location on Google Map with FusedLocationProviderClient”

  1. Got it working, having banged my head against other code for literally days. Very, very grateful to you! Just one thing – FusedLocationApi is deprecated. Any chance of an update?

  2. java.lang.NullPointerException: Attempt to invoke virtual method ‘double android.location.Location.getLatitude()’ on a null object reference
    at com.example.myapplication.MapsActivity.onMapReady(MapsActivity.java:166)

  3. I tried your code and it’s working fine but GPS is not turning on while clicking on allow button from the location services dialog. Can you do coding for enabling the gps to turn on.

Leave a Reply

Your email address will not be published. Required fields are marked *