-
-
Save chrisk8er/7616326ef211a1e8d0727e5b5876c028 to your computer and use it in GitHub Desktop.
Android Get User Location Manager
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 LocationManagerImpl @Inject constructor( | |
private val permissionManager: PermissionManager, | |
private val context: Context | |
) : LocationManager { | |
override fun getUserLocationUpdates(): Observable<UserLocation> = | |
if (checkIfGooglePlayAvailable()) getLocationFromGooglePlay() else getLocationFromAndroidSdk() | |
override fun getDefaultLocation(): UserLocation = UserLocation(DEFAULT_LATITUDE, DEFAULT_LONGITUDE) | |
@SuppressLint("MissingPermission") | |
private fun getLocationFromAndroidSdk(): Observable<UserLocation> { | |
return Observable | |
.create { emitter -> | |
val locationManager = | |
context.getSystemService(Context.LOCATION_SERVICE) as android.location.LocationManager | |
val listener = object : LocationListener { | |
override fun onStatusChanged(p0: String?, p1: Int, p2: Bundle?) {} | |
override fun onProviderEnabled(p0: String?) {} | |
override fun onProviderDisabled(p0: String?) {} | |
override fun onLocationChanged(location: Location) { | |
emitter.processLocation(location) | |
} | |
} | |
emitter.setDisposable(Disposables.fromAction { | |
locationManager.removeUpdates(listener) | |
}) | |
if (permissionManager.isLocationsGranted()) { | |
if (locationManager.isProviderEnabled(GPS_PROVIDER) || | |
locationManager.isProviderEnabled(NETWORK_PROVIDER) | |
) { | |
locationManager.requestLocationUpdates( | |
GPS_PROVIDER, | |
LOCATION_UPDATE_TIME, | |
0f, | |
listener | |
) | |
locationManager.requestLocationUpdates( | |
NETWORK_PROVIDER, | |
LOCATION_UPDATE_TIME, | |
0f, | |
listener | |
) | |
val location = locationManager.getLastKnownLocation(GPS_PROVIDER) | |
?: locationManager.getLastKnownLocation(NETWORK_PROVIDER) | |
emitter.processLocation(location) | |
} else { | |
emitter.processError(LocationProviderMissingException) | |
} | |
} else { | |
emitter.processError(LocationPermissionDeniedException) | |
} | |
} | |
} | |
private fun getLocationFromGooglePlay(): Observable<UserLocation> { | |
return Observable.create { emitter -> | |
val fusedLocationClient = LocationServices.getFusedLocationProviderClient(context) | |
fusedLocationClient.flushLocations() | |
val locationCallback = object : LocationCallback() { | |
override fun onLocationResult(locationResult: LocationResult?) { | |
locationResult?.locations?.forEach { | |
emitter.processLocation(it) | |
} | |
} | |
} | |
fusedLocationClient.requestLocationUpdates( | |
LocationRequest().setInterval(LOCATION_UPDATE_TIME), | |
locationCallback, | |
Looper.getMainLooper() | |
) | |
emitter.setDisposable(Disposables.fromAction { | |
fusedLocationClient.removeLocationUpdates(locationCallback) | |
}) | |
if (permissionManager.isLocationsGranted()) { | |
fusedLocationClient.lastLocation | |
.addOnSuccessListener { location -> | |
emitter.processLocation(location) | |
} | |
.addOnFailureListener { exception -> | |
Timber.d(exception) | |
emitter.processError(LocationProviderMissingException) | |
} | |
} else { | |
emitter.processError(LocationPermissionDeniedException) | |
} | |
} | |
} | |
private fun checkIfGooglePlayAvailable(): Boolean = | |
GoogleApiAvailability.getInstance().isGooglePlayServicesAvailable(context) == SUCCESS | |
private fun ObservableEmitter<UserLocation>.processLocation(location: Location?) { | |
if (isDisposed) return | |
location?.let { onNext(UserLocation(it.latitude, it.longitude)) } | |
?: onNext(getDefaultLocation()) | |
} | |
private fun ObservableEmitter<UserLocation>.processError(exception: RuntimeException) { | |
if (!isDisposed) onError(exception) | |
} | |
private companion object { | |
const val LOCATION_UPDATE_TIME = 2000L // in milliseconds | |
// Default location - Moscow | |
const val DEFAULT_LATITUDE = 55.751385 | |
const val DEFAULT_LONGITUDE = 37.615558 | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment