I have a flow in a view model which emits the user’s location every 15 seconds
val locations = MutableStateFlow<List<StoreLocation>>(emptyList())
private val _locations = MutableStateFlow<List<SortableLocation>>(emptyList())
val locations: StateFlow<List<SortableLocation>>
get() = _locations.asStateFlow()
private val userLocation: StateFlow<Location?> = flow {
while (currentCoroutineContext().isActive) {
Timber.v("Updating user location")
emit(getLocation())
delay(15000L)
}
}.stateIn(
viewModelScope,
SharingStarted.WhileSubscribed(5000L),
null
)
init {
viewModelScope.launch {
combine(userLocation, cachedLocations) { androidLocation, cachedLocations ->
Timber.v("Updating sortable locations")
_locations.emit(getSortedLocations(androidLocation, cachedLocations))
}.collect()
}
}
fun updateLocations() {
viewModelScope.launch {
Timber.v("Updating sortable locations")
val androidLocation = getLocation()
val cachedLocations = cachedLocations.value
locations.value = getSortedLocations(androidLocation, cachedLocations)
}
}
In my ui layer, I collect with lifecycle.
@Composable
fun Screen() {
val locations by viewModel.locations.collectAsStateWithLifecycle()
}
When the app is backgrounded the while loop in the userLocation
flow continues to run. How can I update the user location every 15 seconds using flows but only when the app is foregrounded? Do I need to use a Lifecycle scope in the ui layer?