Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
package farmdrive.ripe.utils
import android.Manifest
import android.content.Context
import android.content.pm.PackageManager
import android.location.Location
import androidx.core.app.ActivityCompat
import com.google.android.gms.common.ConnectionResult
import com.google.android.gms.common.GoogleApiAvailability
import com.google.android.gms.location.*
import farmdrive.ripe.domain.models.RResult
import kotlinx.coroutines.ExperimentalCoroutinesApi
import kotlinx.coroutines.suspendCancellableCoroutine
import timber.log.Timber
import kotlin.coroutines.resume
@ExperimentalCoroutinesApi
suspend fun FusedLocationProviderClient.requestLocationUpdateFlow(context: Context): Location = suspendCancellableCoroutine { continuation ->
if (ActivityCompat.checkSelfPermission(
context,
Manifest.permission.ACCESS_FINE_LOCATION
) != PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission(
context,
Manifest.permission.ACCESS_COARSE_LOCATION
) != PackageManager.PERMISSION_GRANTED
) {
Timber.e("Permission not granted")
continuation.cancel(Exception("Permission not granted"))
}
val locationRequest = LocationRequest.create()
.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY)
.setInterval(10 * 1000) // 10 seconds, in milliseconds
.setFastestInterval(1 * 1000)
val locationCallback = object: LocationCallback() {
override fun onLocationResult(p0: LocationResult?) {
removeLocationUpdates(this)
if (continuation.isActive) {
p0?.let {
continuation.resume(it.lastLocation)
}
continuation.cancel()
}
}
}
continuation.invokeOnCancellation {
removeLocationUpdates(locationCallback)
}
requestLocationUpdates(locationRequest, locationCallback, null)
}
class LocationUtils(private val context: Context) {
suspend fun getLatitudeAndLongitude(): RResult<Pair<Double, Double>> {
val googleAvailability = GoogleApiAvailability.getInstance()
val result = googleAvailability.isGooglePlayServicesAvailable(context)
return if (result == ConnectionResult.SUCCESS) {
val client = LocationServices.getFusedLocationProviderClient(context)
try {
if (ActivityCompat.checkSelfPermission(
context,
Manifest.permission.ACCESS_FINE_LOCATION
) != PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission(
context,
Manifest.permission.ACCESS_COARSE_LOCATION
) != PackageManager.PERMISSION_GRANTED
) {
Timber.e("Permission not granted")
throw Exception()
}
val location: Location = client.requestLocationUpdateFlow(context)
RResult.Success(Pair(location.latitude, location.longitude))
} catch (e: Exception) {
Timber.e(e)
RResult.Error("Unable to fetch current location.")
}
} else {
googleAvailability.showErrorNotification(context, result)
RResult.Error("Google play services is unavailable.")
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment