-
-
Save iosandroiddev/f9b0f344ee4bbfc904e91a11c01fd0ac to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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