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

North Border Software




Home Tutorials Hints & Tips About
Share on Facebook Share on Twitter

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.


private val MY_PERMISSION_FINE_LOCATION = 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

if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {

   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) {

      MY_PERMISSION_FINE_LOCATION ->

         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()

            finish()

         }

   }

}


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

© 2015 North Border Software All rights reserved
Privacy and Cookies Terms of Use Disclaimer Copyright
North Border Software Logo

Android Apps and Training