4

To request the last known location of the user's device, we can use the fused location provider to retrieve the device's last known location using getLastLocation(), but using getCurrentLocation() gets a refresher, and more accurate location.

so, how to use the fusedLocationClient.getCurrentLocation() in Kotlin as there is no example illustrated in the documentation?

Ahmed Maad
  • 367
  • 5
  • 16

3 Answers3

5

According to the documentation, the getCurrentLocation() takes two parameters.

The 1st parameter it takes is the priority (e.g. PRIORITY_HIGH_ACCURACY) to request the most accurate locations available, or any other priority that can be found here.

The 2nd parameter it takes is a cancellation token that can be used to cancel the current location request.

From the Google play services reference, a CancellationToken can only be created by creating a new instance of CancellationTokenSource.

so here is the code you need to use when using getCurrentLocation()

class YourActivity : AppCompatActivity() {

    private lateinit var fusedLocationClient: FusedLocationProviderClient

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.your_layout)

        fusedLocationClient = LocationServices.getFusedLocationProviderClient(this)

        fusedLocationClient.getCurrentLocation(LocationRequest.PRIORITY_HIGH_ACCURACY, object : CancellationToken() {
                override fun onCanceledRequested(p0: OnTokenCanceledListener) = CancellationTokenSource().token

                override fun isCancellationRequested() = false
            })
            .addOnSuccessListener { location: Location? ->
                if (location == null)
                    Toast.makeText(this, "Cannot get location.", Toast.LENGTH_SHORT).show()
                else {
                    val lat = location.latitude
                    val lon = location.longitude
                }

            }

    }
}
Ahmed Maad
  • 367
  • 5
  • 16
  • what is `CancellationToken`? – user924 Aug 22 '22 at 08:21
  • How can addOnSuccessListener return an empty location? I don't understand that. If it's a success, then there should be always a location. How can this be retried? – Houman Jan 17 '23 at 11:21
  • As you can see from this [link](https://developer.android.com/training/location/retrieve-current#last-known) that the location object may be null in the following situations: 1- Location is turned off in the device settings because, disabling location also clears the cache. 2- The device never recorded its location (e.g. new device or a device that has been restored to factory settings). 3- Google Play services on the device has restarted, and there is no active Fused Location Provider client that has requested location after the services restarted. @Houman – Ahmed Maad Jan 24 '23 at 12:09
2

I know the question is about Kotlin but I want to add for those searching for Java, based on this example in the documentation:

CancellationTokenSource cancellationTokenSource = new CancellationTokenSource();
fusedLocationClient.getCurrentLocation(Priority.PRIORITY_HIGH_ACCURACY, cancellationTokenSource.getToken())
.addOnSuccessListener(MyActivity.this, new OnSuccessListener<Location>() {
    @Override
    public void onSuccess(Location location) {
        // Got last known location. In some rare situations this can be null.
        if (location != null) {
            //do your thing
        }
        Log.w(TAG, "No current location could be found");
    }
});
Ryan M
  • 18,333
  • 31
  • 67
  • 74
Anatol Bivol
  • 890
  • 7
  • 20
  • Actually it's not that rare that this returns null. Why does this happen? – Houman Jan 17 '23 at 11:17
  • Not helpful but this is what [the docs](https://developers.google.com/android/reference/com/google/android/gms/location/FusedLocationProviderClient#getCurrentLocation(com.google.android.gms.location.CurrentLocationRequest,%20com.google.android.gms.tasks.CancellationToken)) have to say about `null` being returned : "Returns a single location fix representing the best estimate of the current location of the device. This may return a historical location if a recent enough location fix exists, or may compute a fresh location. If unable to retrieve a current location fix, null will be returned." – Anatol Bivol Jan 17 '23 at 15:32
1
fusedLocationClient.getCurrentLocation(Priority.PRIORITY_HIGH_ACCURACY, object : CancellationToken() {
    override fun onCanceledRequested(listener: OnTokenCanceledListener) = CancellationTokenSource().token

    override fun isCancellationRequested() = false
})
.addOnSuccessListener {
    if (it == null)
        Toast.makeText(this, "Cannot get location.", Toast.LENGTH_SHORT).show()
    else {
        val lat = it.latitude
        val lon = it.longitude
    }

}
Shivanand Darur
  • 3,158
  • 1
  • 26
  • 32