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

Deepak Prasad
Feb 22, 2019 · 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.

Image for post
Image for post

Welcome to a place where words matter. On Medium, smart voices and original ideas take center stage - with no ads in sight. Watch

Follow all the topics you care about, and we’ll deliver the best stories for you to your homepage and inbox. Explore

Get unlimited access to the best stories on Medium — and support writers while you’re at it. Just $5/month. Upgrade

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store