Android Get Current Location Using Fused Location Provider

In this article, we will talk about what a fused location provider is and how to use it to get the current location using a sample Android application. We need not explicitly choose either GPS provider or Network location provider, as the “Fused Location Provider” automatically chooses the underlying technology and gives the best location as per the need.

Fused Location Provider

  • The fused location provider is one of the location APIs in Google Play services that intelligently combines different signals to provide the location information that your app needs.
  • It manages the underlying location technologies, such as GPS provider and Wi-Fi, and provides a simple API so that you can specify requirements at a high level, like high accuracy or low power.
  • It also optimizes the device’s use of battery power.

FusedLocationProviderClient

FusedLocationProviderClient is the main entry point for interacting with the fused location provider. With this, your app no longer needs to manually manage connections to Google Play Services through GoogleApiClient.

Advantages with FusedLocationProviderClient :

  • It takes the complete connection logic under the hood. The user no longer needs to initialize GoogleApiClient nor does he need to manage the connection logic.
  • It returns the result as a Task object which is easy to manage and share.
  • User need not wait until the connection is established to request for a Location. When requesting for the current location the API call automatically waits until the connection is established thereby minimizing the chances of an IllegalStateException.

Note : It’s recommended to use Google Play services version 11.6.0 or higher, which includes bug fixes for this class.

getLastLocation() : getLastlocation() is one of the method provided by FusedLocationProviderClient class which returns the best most recent location currently available.The precision of the location returned by this call is determined by the permission setting you put in your app manifest.

The getLastLocation() method returns a Task that you can use to get a Location object with the latitude and longitude coordinates of a geographic location.

onMapready(): This method is called when the map is ready to be used.

OnMapReadyCallbackCallback interface for when the map is ready to be used.

Once an instance of this interface is set on a MapFragment or MapView object, the onMapReady(GoogleMap) method is triggered when the map is ready to be used and provides a non-null instance of GoogleMap.

Let’s create an example that shows how to get the current device location using FusedLocationProviderClient.

Creating Android Project

1 . Create a new project GetCurrentLocationOnMap in Android Studio from File ⇒ New Project and fill the project details.

Getting the Google Maps API key

To integrate google map in your application firstly you have to generate the API key in Google API Console .

2 . Go to  Google API Console and generate a new API key corresponding to your SHA1 and application package name.

3 . Open AndroidManifest.xml and add the generated API key to your project above the   </application > tag as shown below :

AndroidManifest.xml 

<application
    android:allowBackup="true"
    android:icon="@mipmap/ic_launcher"
    android:label="@string/app_name"
    android:roundIcon="@mipmap/ic_launcher_round"
    android:supportsRtl="true"
    android:theme="@style/AppTheme">
    <activity android:name=".MainActivity">
        <intent-filter>
            <action android:name="android.intent.action.MAIN" />

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

    <meta-data
        android:name="com.google.android.geo.API_KEY"
        android:value="YOUR API KEY"/>

</application>

4 . Open build.gradle and add the following dependencies as shown below :

build.gradle

dependencies {
    implementation fileTree(dir: 'libs', include: ['*.jar'])
    
    implementation 'com.google.android.gms:play-services-maps:17.0.0'
   
    implementation 'com.google.android.gms:play-services-location:17.0.0'
}

Specify app permissions

5 . Open AndroidManifest.xml and add the following permissions to your application to use location services.

  • INTERNET
  • ACCESS_FINE_LOCATION
  • ACCESS_COARSE_LOCATION

AndroidManifest.xml

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.example.getcurrentlocationonmap">

    <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
    <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
    <uses-permission android:name="android.permission.INTERNET" />

    <application
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:roundIcon="@mipmap/ic_launcher_round"
        android:supportsRtl="true"
        android:theme="@style/AppTheme">
        <activity android:name=".MainActivity">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

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

        <meta-data
            android:name="com.google.android.geo.API_KEY"
            android:value="YOUR API KEY"/>

    </application>

</manifest>

 

6 . Open activity_main.xml and add the fragment for the map as shown below:

activity_main.xml

<fragment
    xmlns:android="http://schemas.android.com/apk/res/android"
    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"
    tools:context="com.example.getcurrentlocationonmap.MainActivity" />

7 . As of Android Marshmallow Location permissions need to be explicitly approved by the user before the app begins to collect device location.

8 . We had already mentioned that FusedLocationProviderClient takes care of all the connection logic on its own. Therefore we don’t need to initialize GoogleApiClient nor do we need to implement connection callbacks. We only need to initialize the FusedLocationProviderClient as shown below:

fusedLocationProviderClient = LocationServices.getFusedLocationProviderClient(this);

9 . Once we have FusedLocationProviderClient we can fetch the current location using the getLastLocation() . It returns a Task object which represents an asynchronous operation.

Task task = fusedLocationProviderClient.getLastLocation();

10 . We will add the success callback listener to the Task object which will be invoked once the connection is established and the location is fetched.

task.addOnSuccessListener(new OnSuccessListener() {
    @Override
    public void onSuccess(Location location) {
        if (location != null)
            currentLocation = location;
        Toast.makeText(getApplicationContext(), currentLocation.getLatitude() + "," +
                currentLocation.getLongitude(), Toast.LENGTH_LONG).show();


        SupportMapFragment supportMapFragment = (SupportMapFragment) getSupportFragmentManager().findFragmentById(R.id.map);
        supportMapFragment.getMapAsync(MainActivity.this);

    }
});

11 . You must have noticed we add a null check for location in OnSuccessListener. This is to avoid crashes in some scenarios in which the location can be null. Below are some of these scenarios

  • GPS provider is turned off in the device settings.
  • Location was never recorded on the devices.  This could be the case of a new device or a device that has been restored to factory settings.

Complete Code

12 . Open MainActivity.java and add the below code:

MainActivity.java

package com.example.getcurrentlocationonmap;

import android.Manifest;
import android.content.pm.PackageManager;
import android.location.Location;
import android.os.Bundle;
import android.widget.Toast;
import com.google.android.gms.location.FusedLocationProviderClient;
import com.google.android.gms.location.LocationServices;
import com.google.android.gms.maps.CameraUpdateFactory;
import com.google.android.gms.maps.GoogleMap;
import com.google.android.gms.maps.OnMapReadyCallback;
import com.google.android.gms.maps.SupportMapFragment;
import com.google.android.gms.maps.model.LatLng;
import com.google.android.gms.maps.model.MarkerOptions;
import com.google.android.gms.tasks.OnSuccessListener;
import com.google.android.gms.tasks.Task;
import androidx.annotation.NonNull;
import androidx.core.app.ActivityCompat;
import androidx.fragment.app.FragmentActivity;

public class MainActivity extends FragmentActivity implements OnMapReadyCallback {


    Location currentLocation;
    FusedLocationProviderClient fusedLocationProviderClient;
    private static final int REQUEST_CODE = 200;


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

        fusedLocationProviderClient = LocationServices.getFusedLocationProviderClient(this);
        fetchLastlocation();
    }


    private void fetchLastlocation() {

        if (ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED) {


            ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.ACCESS_FINE_LOCATION}, REQUEST_CODE);
            return;
        }

        Task task = fusedLocationProviderClient.getLastLocation();
        task.addOnSuccessListener(new OnSuccessListener() {
            @Override
            public void onSuccess(Location location) {
                if (location != null)
                    currentLocation = location;
                Toast.makeText(getApplicationContext(), currentLocation.getLatitude() + "," +
                        currentLocation.getLongitude(), Toast.LENGTH_LONG).show();


                SupportMapFragment supportMapFragment = (SupportMapFragment) getSupportFragmentManager().findFragmentById(R.id.map);
                supportMapFragment.getMapAsync(MainActivity.this);

            }
        });
    }

    @Override
    public void onMapReady(GoogleMap googleMap) {
        LatLng latLng = new LatLng(currentLocation.getLatitude(), currentLocation.getLongitude());
        MarkerOptions markerOptions = new MarkerOptions().position(latLng).title("You are here");
        googleMap.animateCamera(CameraUpdateFactory.newLatLng(latLng));
        googleMap.animateCamera(CameraUpdateFactory.newLatLngZoom(latLng, 15));
        googleMap.addMarker(markerOptions);


    }

    @Override
    public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {

        switch (requestCode) {
            case REQUEST_CODE:

                if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
                    fetchLastlocation();
                }
                break;
        }
    }
}

When you run your app it will look like this :

Screenshot_1572340388      Screenshot_1572340433

 

I hope this article will help you in understanding how to use Fusedlocationprovider to get the current location of your device.

2 thoughts on “Android Get Current Location Using Fused Location Provider”

  1. K Pradeep Kumar Reddy

    We will not get onLocationResult() callback when gps is turned off. Is there any way to deal this problem.

    1. Arun Chandravanshi

      Well, this post is for getting the current location and showing it on Google Map since you ask a question related to location change callbacks/listeners so this is the answer to your question:

      It depends on LocationRequest object how you have created, in case if you have used “PRIORITY_HIGH_ACCURACY” it will use GPS(Fine) looks like in your case.

      if you use “PRIORITY_BALANCED_POWER_ACCURACY” then it will use Network(coarse).

      Create LocationRequest :

      LocationRequest locationRequest = new LocationRequest();
      locationRequest.setInterval(1000);
      locationRequest.setFastestInterval(1000);
      locationRequest.setPriority(LocationRequest.PRIORITY_BALANCED_POWER_ACCURACY);

      official documentation: https://developers.google.com/android/reference/com/google/android/gms/location/LocationRequest.html

Leave a Reply