Get current location

Hello, Mark!

I have the following case:

  • get the current location at the click of a button
  • get current location each x seconds

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.

There may not be a location:

  • GPS radios are usually powered down to save on battery, unless something is actively looking for a location
  • Even if the GPS radio is powered on, it usually takes a bit to get a fix
  • Even if GPS is trying to get a fix, that may not be possible, due to environmental conditions (e.g., in the downtown area of a large city, in an underground parking garage)
  • Coarse location based on cell towers assumes a cell signal
  • And so on

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.

1 Like

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. 

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.

1 Like