Getting GPS location using FusedLocationProvider and LiveData easily in background (Kotlin, Android)

Deepak Prasad
Feb 22 · 2 min read

Getting GPS location is one of the most important and necessary aspects of developing apps in Android.

For a brief overview, we will be trying to get GPS location in such a way that we do not need to write the boilerplate code every time we try to access the location. Also, we will be using Singleton pattern to save the instance of FusedLocationProvider to avoid it being instantiated every time we try and fetch location.

LiveData will help us observe the location every time an update is received. Also it fully coordinates with the lifecycle of its parent (Activity, Fragments).

Step 1

Add permissions in the manifest.

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

Step 2

Create your LocationUtils class and add an instance variable of FusedLocationProviderClient.

private var fusedLocationProviderClient: FusedLocationProviderClient ?= null

Step 3

Using Singleton pattern, get the instance of the above FusedLocationProviderClient variable.

// using singleton pattern to get the locationProviderClient
fun getInstance(appContext: Context): FusedLocationProviderClient{
    if(fusedLocationProviderClient == null)
        fusedLocationProviderClient = LocationServices.getFusedLocationProviderClient(appContext)
    return fusedLocationProviderClient!!
}

Now we have created the instance of FusedLocationProvider. Only one such instance will exist.

Step 4

Add another instance variable of type MutableLiveData<Location>.

private var location : MutableLiveData<Location> = MutableLiveData()

Create a function that returns the above location variable.

fun getLocation() : LiveData<Location> {
    fusedLocationProviderClient!!.lastLocation
        .addOnSuccessListener {loc: Location? ->
            location.value = loc

        }

    return location
}

Full Code:

class LocationUtils{

    private var fusedLocationProviderClient: FusedLocationProviderClient ?= null
    private var location : MutableLiveData<Location> = MutableLiveData()

    // using singleton pattern to get the locationProviderClient
    fun getInstance(appContext: Context): FusedLocationProviderClient{
        if(fusedLocationProviderClient == null)
            fusedLocationProviderClient = LocationServices.getFusedLocationProviderClient(appContext)
        return fusedLocationProviderClient!!
    }

    fun getLocation() : LiveData<Location> {
        fusedLocationProviderClient!!.lastLocation
            .addOnSuccessListener {loc: Location? ->
                location.value = loc

            }

        return location
    }

}

Step 5

Get the location in an Activity or Fragment in the following manner:

LocationUtils().getInstance(appContext)
LocationUtils().getLocation().observe(this, Observer {loc: Location? ->
    location = loc!!
    // Yay! location recived. Do location related work here    Log.i(TAG,"Location: ${location.latitude}  ${location.longitude}")
    
})

Therefore, we get our location easliy.

Note: This is my first post on Medium. Forgive me if any errors might have crept in. Feel free to give any feedback .

Thank You for reading.