Skip to content

Instantly share code, notes, and snippets.

@oakkub
Last active July 8, 2020 06:37
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save oakkub/1933cf95801c154c9e3a48b589570bc8 to your computer and use it in GitHub Desktop.
Save oakkub/1933cf95801c154c9e3a48b589570bc8 to your computer and use it in GitHub Desktop.
class LocationRequestHelper(private val context: Context,
private val locationRequest: LocationRequest,
lifecycle: Lifecycle,
private val onResult: (LocationResult) -> Unit) : LifecycleObserver {
private val locationClient by lazy { FusedLocationProviderClient(context) }
private val settingsClient by lazy { LocationServices.getSettingsClient(context) }
private val locationSettingRequest by lazy {
LocationSettingsRequest.Builder()
.setAlwaysShow(true)
.addLocationRequest(locationRequest)
.build()
}
private val locationCallback = object : LocationCallback() {
override fun onLocationResult(locationResult: com.google.android.gms.location.LocationResult) {
super.onLocationResult(locationResult)
val location = locationResult.locations.firstOrNull() ?: return
if (location.isFromMockProvider) {
onResult(LocationResult.MockLocationNotAllow)
return
}
onResult(LocationResult.Success(location))
}
}
init {
lifecycle.addObserver(this)
}
@SuppressLint("MissingPermission")
@OnLifecycleEvent(value = Lifecycle.Event.ON_CREATE)
fun startDetecting() {
if (!LocationUtils.isEnabled(context)) {
onResult(LocationResult.LocationDisabled)
return
}
settingsClient.checkLocationSettings(locationSettingRequest)
.addOnSuccessListener {
// All location settings are satisfied. The client can initialize
// location requests here.
locationClient.removeLocationUpdates(locationCallback)
locationClient.requestLocationUpdates(locationRequest, locationCallback, Looper.getMainLooper())
}
.addOnFailureListener {
onResult(getLocationResultSettingsFailure(it as ApiException))
}
}
@OnLifecycleEvent(value = Lifecycle.Event.ON_DESTROY)
fun stopDetecting() {
locationClient.removeLocationUpdates(locationCallback)
}
private fun getLocationResultSettingsFailure(exception: ApiException): LocationResult = when (exception.statusCode) {
LocationSettingsStatusCodes.RESOLUTION_REQUIRED -> {
// Location settings are not satisfied. But could be fixed by showing the
// user a dialog.
try {
// Cast to a resolvable exception.
LocationResult.RecoverableError(exception as ResolvableApiException)
} catch (e: IntentSender.SendIntentException) {
// Ignore the error.
LocationResult.Error(e)
}
}
LocationSettingsStatusCodes.SETTINGS_CHANGE_UNAVAILABLE -> {
// Location settings are not satisfied. However, we have no way to fix the
// settings so we won't show the dialog.
LocationResult.Error(exception)
}
else -> {
LocationResult.Error(IllegalStateException("Unknown error occurred: LocationSettingsStatusCodes.SETTINGS_CHANGE_UNAVAILABLE"))
}
}
}
sealed class LocationResult {
data class Success(val location: Location) : LocationResult()
data class Error(val exception: Exception) : LocationResult()
data class RecoverableError(val resolvable: ResolvableApiException) : LocationResult()
object MockLocationNotAllow : LocationResult()
object LocationDisabled : LocationResult()
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment