Get current location

from the CommonsWare Community archives

At April 28, 2021, 2:29pm, grrigore asked:

Hello, Mark!

I have the following case:

I’ve tried to use FusedLocationProviderClient but I think I might not use the best approach. The thing is that I’d like - if possible - to call a method getLocation() that will return the location. I’d rather not implement a service or something else. Is there anything like this?

LE: I want to point out that I am using Kotlin and Coroutines in my implementation.

So I came across this. I guess this might be a solution, but I’d like to hear your opinion on this.


At April 28, 2021, 11:31pm, mmurphy replied:

There may not be a location:

In the FusedLocationProviderClient API, that is a very likely candidate for use from a UI, such as for your “click of a button case”.

There isn’t anything for your “get current location each x seconds” case, strictly speaking. One of the requestLocationUpdates() calls on FusedLocationProvider client is as good as you are going to get for that, in that API.

There are equivalents of those operations on LocationManager, if you would prefer to avoid Play Services.


At April 29, 2021, 6:41am, grrigore replied:

I managed to do something using this piece of code:

@SuppressLint("MissingPermission")
private suspend fun getCurrentLocation(cancellationToken: CancellationToken): Location? {
    return fusedLocationProviderClient.getCurrentLocation(
        LocationRequest.PRIORITY_HIGH_ACCURACY,
        cancellationToken
    ).await()
}

I use this as a one-shot and I also have a repetitive Job that calls the method every x seconds. This seems to be OK for now. I am aware that are situations where Location will be null (as you mentioned), but I guess there’s nothing to do if certain conditions aren’t met.

Do you know anything about CancellationToken? I think I’m using it right…

suspend fun getLocation() = withContext(Dispatchers.IO) {
    val cancellationTokenSource = CancellationTokenSource()
    val location = getCurrentLocation(cancellationTokenSource.token)
    cancellationTokenSource.cancel()
}

AFAIK I have to:

Create a new CancellationTokenSource object each time you execute a new query 
because the cancellation token received from this will work only for this request 
and not afterward. 

At April 29, 2021, 12:10pm, mmurphy replied:

Sorry, I do not use Play Services very much.

FWIW, I like the suspendCancellableCoroutine() approach that Google’s Manuel Vivo demonstrates here. In Manuel’s case, the wrapper is around getLastLocation() rather than getCurrentLocation(), which might influence matters.