Get current location
from the CommonsWare Community archivesAt April 28, 2021, 2:29pm, grrigore asked:
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.
At April 28, 2021, 11:31pm, mmurphy replied:
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.
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.