Home Tutorials Hints & Tips

Android Location Services in Kotlin Part 2 - Getting the Last Location

In this easy to follow three part series, we look at how to code Android location based services in Kotlin using the Fused Location Provider Client. In this part we get the last location of the device using a onSuccessListener and deal with run time permissions.

In part 1, we created a basic project framework and created the layout. In this part we go on to look at how the last known location of the device can be recalled and the User Interface updated with that location. We will also go onto the handle the runtime permissions.

First, we will create some code to add onClickListeners to the toggle button and simply have them change the text in the UI at to reflect the button states. In Kotlin, we do not need to use the findViewByID method. The ID of the view can be referenced directly.

tbGps_Balanced.setOnClickListener {

   if (tbGps_Balanced.isChecked) {

      //using GPS only

      tvSensor.text = "GPS"

   } else {

      //using balanced power accuracy

      tvSensor.text = "Cell Tower and WiFi"



tbLocationOnOff.setOnClickListener {

   if (tbLocationOnOff.isChecked) {

      //location update on

      tvUpdates.text = "On"

   } else {

      //location update off

      tvUpdates.text = "Off"



Next, we need to code a Kotlin variable to create an instance of the FusedLocationProviderClient Class:

private var fusedLocationProviderClient: FusedLocationProviderClient? = null

In the onCreate function, just after the onClickListeners for the ToggleButtons, we need to associate the variable with the getFusedLocationProviderClient method in the LocationServices Class.

fusedLocationProviderClient = LocationServices.getFusedLocationProviderClient(this)

We need to set up an onSuccessListener after requesting the last location of the device. Essentially, we will update the User Interface if we successfully get the last known location. There are other similar listeners such as the onFailureListener and we can use that to execute some code in the event we fail to get the last known location of the device. However, in this tutorial we will use only the onSuccessListener. We will need a not-null assertion operator (!!).

fusedLocationProviderClient!!.lastLocation.addOnSuccessListener {location ->


This will require a runtime permissions check if we are compiling against Android API 23 or higher. API 23 is Marshmallow or Android 6.0. Granting runtime permissions is covered later.

Within the onSuccessListener, you need to add code to update the User Interface, first checking that the location is not null.

if (location != null) {

   //update UI

   tvLatitude.text = location.latitude.toString()

   tvLongitude.text = location.longitude.toString()

   if (location.hasAccuracy()) {

      tvAccuracy.text = location.accuracy.toString()

   } else {

      tvAccuracy.text = "No Accuracy Available"


   if (location.hasAltitude()) {

      tvAltitude.text = location.altitude.toString()

   } else {

      tvAltitude.text = "No Altitude Available"


   if (location.hasSpeed()) {

      tvSpeed.text = location.speed.toString()

   } else {

      tvSpeed.text = "No Speed Available"



Some sensors are not able to return an accuracy, altitude or speed, so it is best to check that the location has these entities by using the hasAccuracy, hasSpeed and hasAltitude methods.

Next, we need to handle the permissions check. We need to check whether the permission to use the fine location has been granted. If it has, we need not do anything more and we can retrieve the last known location of the device. Otherwise, we must prompt the user to grant permission. If they deny permission, we will simply close the app.

First create an integer immutable to represent the requestCode. There is a common callback method to handle all permissions and so we need to identify which permission is being passed to the onRequestPermissionsResult method. The value of the integer is nominal and I chose 101.


Enter the following code to check if the permission to use the fine location has been granted:

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

   //Place code here for onSuccessListener

} else {

   //request permissions


   requestPermissions(arrayOf(android.Manifest.permission.ACCESS_FINE_LOCATION), MY_PERMISSION_FINE_LOCATION)



You will notice a API check surrounding the requestPermissions method. This is needed as the app may support a minimum release below API 23. The requestPermissions method prompts the user to allow or deny permission.

The final task is to complete the callback function to take action based on the user response.

override fun onRequestPermissionsResult(requestCode: Int, permissions: Array<out String>, grantResults: IntArray) {

   super.onRequestPermissionsResult(requestCode, permissions,    grantResults)

   when (requestCode) {


         if (grantResults[0] == PackageManager.PERMISSION_GRANTED) {

            //permission granted. No need to do anything

         } else {

            Toast.makeText(applicationContext, "This app requires location permissions to be granted", Toast.LENGTH_SHORT).show()





If the user grants permission we do not need to do anything, simply carry on. If the user denies permission, we will close the app. I used a when statement as there may be a need to add code to handle more permissions in the future, so we need a option for each requestCode.  

The app is ready to test. The screenshot below shows that the last known location was found, and the data displayed in the User Interface.

Android Kotlin Location Screenshot

In part 3 for we will learn how to turn on location updates.

After this tutorial your MainActivity.kt should look like the one below:

Download Download project files

Privacy and Cookies Disclaimer Copyright
© 2015 - 2018 North Border Tech Training All rights reserved