'How to observe ContentProvider changes for coroutine flow

I have a flow to fetch data from database via content provider.

fun getDataFlow(): Flow<Result> {
    return flow {
      emit(Result.Loading)

      // fetchAll() is the method to fetch data via contentResolover.query()
      val results = fetchAll()
      emit(Result.Success(categories))
    }.catch { e ->
      emit(Result.Error(e))
    }
  }

So how to trigger refetching data when ContentProvider data changed (onChange get called)?

val contentObserver = object : ContentObserver(null) {
      override fun onChange(selfChange: Boolean) {
        super.onChange(selfChange)
      }
    }


Solution 1:[1]

you can use callback flow

@ExperimentalCoroutinesApi
fun ContentResolver.register(uri: Uri) = callbackFlow<Boolean> {
    val observer = object : ContentObserver(null) {
        override fun onChange(selfChange: Boolean) {
            trySend(selfChange)
        }
    }
    registerContentObserver(uri, false, observer)
    
    invokeOnClose { 
        unregisterContentObserver(observer)
    }
}

then u can do something like this

getDataFlow().combine(ContentResolver.register("YOUR_URI")){data, isSelfChange -> 

}

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 Sheikh Zakir Ahmad