|
/** |
|
* Wraps the LocationServices and fused location provider in callbackFlow |
|
* |
|
* Derived in part from https://github.com/android/location-samples/blob/main/LocationUpdatesBackgroundKotlin/app/src/main/java/com/google/android/gms/location/sample/locationupdatesbackgroundkotlin/data/MyLocationManager.kt |
|
* and https://github.com/googlecodelabs/kotlin-coroutines/blob/master/ktx-library-codelab/step-06/myktxlibrary/src/main/java/com/example/android/myktxlibrary/LocationUtils.kt |
|
*/ |
|
class SharedLocationManager constructor( |
|
private val context: Context, |
|
externalScope: CoroutineScope |
|
) { |
|
... |
|
// Set up the Fused Location Provider and LocationRequest |
|
private val fusedLocationClient: ... |
|
private val locationRequest = ... |
|
|
|
@ExperimentalCoroutinesApi |
|
@SuppressLint("MissingPermission") |
|
private val _locationUpdates = callbackFlow<Location> { |
|
val callback = object : LocationCallback() { |
|
override fun onLocationResult(result: LocationResult?) { |
|
result ?: return |
|
Log.d(TAG, "New location: ${result.lastLocation.toText()}") |
|
// Send the new location to the Flow observers |
|
trySend(result.lastLocation) |
|
} |
|
} |
|
... |
|
Log.d(TAG, "Starting location updates") |
|
|
|
fusedLocationClient.requestLocationUpdates( |
|
locationRequest, |
|
callback, |
|
Looper.getMainLooper() |
|
).addOnFailureListener { e -> |
|
close(e) // in case of exception, close the Flow |
|
} |
|
|
|
awaitClose { |
|
Log.d(TAG, "Stopping location updates") |
|
fusedLocationClient.removeLocationUpdates(callback) // clean up when Flow collection ends |
|
} |
|
}.shareIn( |
|
externalScope, |
|
replay = 0, |
|
started = SharingStarted.WhileSubscribed() |
|
) |
|
|
|
@ExperimentalCoroutinesApi |
|
fun locationFlow(): Flow<Location> { |
|
return _locationUpdates |
|
} |
|
} |