Skip to content

Instantly share code, notes, and snippets.

@michaelbukachi
Created December 30, 2020 19:11
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save michaelbukachi/95f6b6cf70900101523a1f6e3e04b6d7 to your computer and use it in GitHub Desktop.
Save michaelbukachi/95f6b6cf70900101523a1f6e3e04b6d7 to your computer and use it in GitHub Desktop.
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