https://kotlinlang.org logo
#android
Title
# android
r

ribesg

03/04/2019, 1:23 PM
Is there a good Kotlin wrapper for the Google Play Services Location API mess?
b

Bino

03/04/2019, 1:38 PM
r

ribesg

03/04/2019, 1:51 PM
Everything looks wrong about this code 🤮
b

Bino

03/04/2019, 2:21 PM
wanna tell me what in specific it is, you don’t like?
r

ribesg

03/04/2019, 2:36 PM
Why are you passing negative values to the location manager
b

Bino

03/04/2019, 2:43 PM
Thats a valid point, fixed it right now. Anything else you might change?
l

louiscad

03/04/2019, 10:33 PM
Not yet, but here's how to get a fresh location with a suspend call (be sure to catch the exceptions):
Copy code
import android.Manifest
import android.location.Location
import androidx.annotation.RequiresPermission
import com.google.android.gms.location.LocationCallback
import com.google.android.gms.location.LocationRequest
import com.google.android.gms.location.LocationResult
import com.google.android.gms.location.LocationServices
import kotlinx.coroutines.CompletableDeferred
import kotlinx.coroutines.tasks.await
import splitties.init.appCtx
import splitties.mainthread.mainLooper

@RequiresPermission(Manifest.permission.ACCESS_FINE_LOCATION)
suspend fun getCurrentLocation(): Location {
    val request = LocationRequest().apply { numUpdates = 1; ... /* Put other config for your use case */ }
    val locationClient = LocationServices.getFusedLocationProviderClient(appCtx)
    val locationAsync = CompletableDeferred<Location>()
    locationClient.requestLocationUpdates(request, object : LocationCallback() {
        override fun onLocationResult(result: LocationResult) {
            locationAsync.complete(result.lastLocation)
        }
    }, mainLooper).await()
    return locationAsync.await()
}
b

Bino

03/05/2019, 8:33 AM
Thanks @louiscad. The repo is a simple showcase, how to use lifecycle observer for location updates. But I could add a coroutine to fetch last known user location as another use-case to the sample
l

louiscad

03/05/2019, 8:43 AM
Just edited my snippet, was missing
LocationRequest
config. @ribesg Is this what you was looking for?
r

ribesg

03/05/2019, 9:16 AM
@louiscad does that show the popup if the GPS is disabled?
l

louiscad

03/05/2019, 9:19 AM
@ribesg No, but it's possible to make a version that does so. Do you struggle making it?
r

ribesg

03/05/2019, 9:22 AM
@louiscad well what you did in your snippet isn’t hard, the hard part is showing such popup. I don’t want to redirect users to the settings, I want to use the popup which directly enables the GPS, that’s what I did in my gist https://gist.github.com/Ribesg/58f5ba76270b139cf581a666bc2f66f5
An invisible activity is the only solution I see unless I missed something
r

ribesg

03/05/2019, 10:16 AM
@louiscad
DialogFragment
has
onActivityResult
?
l

louiscad

03/05/2019, 10:16 AM
@ribesg Yes, like all `Fragment`s.
l

louiscad

03/05/2019, 10:18 AM
Just be sure to not rely on
onActivityResult
in case the Activity was restarted, or the process was killed and restarted with the Activity
You can use
getResolution()
instead, and start it from the Fragment
r

ribesg

03/05/2019, 10:19 AM
Ok, I’ll look into that, thanks
l

louiscad

03/05/2019, 10:21 AM
@ribesg This (decompiled with in-IDE JetBrains decompiler) shows how
startResoltuionForResult
just uses the
PendingIntent
. A
Fragment
has the same abilities thanks to its host `Activity`:
Copy code
public final void startResolutionForResult(Activity var1, int var2) throws SendIntentException {
        if (this.hasResolution()) {
            var1.startIntentSenderForResult(this.zzi.getIntentSender(), var2, (Intent)null, 0, 0, 0);
        }
    }
r

ribesg

03/05/2019, 1:54 PM
I’ll just drop the idea of using the google location API, it’s a mess and adds too many corner cases
😐 1
👍 1
Aaaaand now I read and see that the “Vanilla” way is much slower, less accurate, depends on device manufacturer and uses more power, nice.
l

louiscad

03/06/2019, 9:30 PM
In my case, I just detect with system API (not Play Services) if location is enabled, and if not, I take the user to the settings. I agree that it should be simpler. I'll let you know if I could make it a single suspending function that handles taking the user to settings.
…and also handles continuing if user enables through quick settings.
r

ribesg

03/07/2019, 8:59 AM
That’s what I’m doing too now, showing an alert and sending to settings https://gist.github.com/Ribesg/5e02ee49431ea31d8e7d4f6f51d0bff1
5 Views