Created
February 8, 2020 08:04
-
-
Save roscrazy/cbff8abe07d83ad2488045957bd7ae3c to your computer and use it in GitHub Desktop.
AndroidLocationService
This file contains hidden or 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
internal class AndroidLocationService(private val locationManager: LocationManager) : | |
LocationService { | |
override fun requestLocationUpdates(attributes: RxLocationAttributes): Observable<Location> { | |
return Observable.create<Location> { emitter -> | |
log { "AndroidLocationService ObservableOnSubscribe create" } | |
val locationListener = RxLocationListener(emitter) | |
emitter.setCancellable { | |
log { "AndroidLocationService ObservableOnSubscribe canceled" } | |
locationManager.removeUpdates(locationListener) | |
} | |
try { | |
val providers = locationManager.allProviders | |
when (attributes.priority) { | |
Priority.BalancePower -> { | |
fetchLastKnowLocation( | |
arrayOf(LocationManager.NETWORK_PROVIDER, LocationManager.PASSIVE_PROVIDER), emitter | |
) | |
requestLocationUpdates(LocationManager.NETWORK_PROVIDER, providers, locationListener, attributes) | |
requestLocationUpdates(LocationManager.PASSIVE_PROVIDER, providers, locationListener, attributes) | |
} | |
Priority.HighAccuracy -> { | |
fetchLastKnowLocation(arrayOf(LocationManager.GPS_PROVIDER), emitter) | |
requestLocationUpdates(LocationManager.GPS_PROVIDER, providers, locationListener, attributes) | |
} | |
Priority.LowPower -> { | |
fetchLastKnowLocation(arrayOf(LocationManager.NETWORK_PROVIDER), emitter) | |
requestLocationUpdates(LocationManager.NETWORK_PROVIDER, providers, locationListener, attributes) | |
} | |
Priority.NoPower -> { | |
fetchLastKnowLocation(arrayOf(LocationManager.PASSIVE_PROVIDER), emitter) | |
requestLocationUpdates(LocationManager.PASSIVE_PROVIDER, providers, locationListener, attributes) | |
} | |
} | |
log { "AndroidLocationService ObservableOnSubscribe finish created" } | |
} catch (e: Exception) { | |
if (!emitter.tryOnError(e)) { | |
log { e.toString() } | |
} | |
} | |
} | |
.retry { n: Int, e: Throwable -> | |
(n < attributes.retryAttempt && e !is SecurityException) | |
} | |
} | |
private fun fetchLastKnowLocation(providers: Array<String>, emitter: ObservableEmitter<Location>) { | |
providers.forEach { | |
locationManager.getLastKnownLocation(it)?.let { | |
if (!emitter.isDisposed) { | |
emitter.onNext(it) | |
} | |
return | |
} | |
} | |
} | |
@Throws(IllegalStateException::class) | |
private fun requestLocationUpdates( | |
provider: String, | |
providers: MutableList<String>, | |
locationListener: RxLocationListener, attributes: RxLocationAttributes | |
) { | |
if (providers.contains(provider)) { | |
locationManager.requestLocationUpdates( | |
provider, | |
attributes.updateInterval, | |
attributes.smallestDisplacement, | |
locationListener, | |
if (attributes.useCalledThreadToEmitValue) null else Looper.getMainLooper() | |
) | |
} | |
} | |
inner class RxLocationListener(private val emitter: ObservableEmitter<Location>) : | |
LocationListener { | |
override fun onLocationChanged(location: Location?) { | |
if (!emitter.isDisposed && location != null) | |
emitter.onNext(location) | |
} | |
override fun onStatusChanged(s: String, i: Int, bundle: Bundle) {} | |
override fun onProviderEnabled(s: String) {} | |
override fun onProviderDisabled(s: String) {} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment