如何观察协程流程的ContentProvider变化

use*_*324 2 android android-contentprovider kotlin kotlin-coroutines kotlin-flow

我有一个通过内容提供商从数据库获取数据的流程。

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))
    }
  }
Run Code Online (Sandbox Code Playgroud)

那么当ContentProvider数据发生变化(onChange被调用)时,如何触发重新获取数据呢?

val contentObserver = object : ContentObserver(null) {
      override fun onChange(selfChange: Boolean) {
        super.onChange(selfChange)
      }
    }
Run Code Online (Sandbox Code Playgroud)

Zak*_*ikh 6

您可以使用回调流程

@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)
    }
}
Run Code Online (Sandbox Code Playgroud)

那么你可以做这样的事情

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

}
Run Code Online (Sandbox Code Playgroud)

我在medium.com 上写了一篇文章,解释了如何将 kotlin Flow 与MediaStore/ContentResolver结合使用。

文章 https://medium.com/@sheikhzakirahmad/kotlin-flow-contentresolver-and-mediastore-the-key-to-effortless-media-access-in-android-fad56db16fdd

您可以在这里找到完整的代码。 https://github.com/prime-zs/Audiofy2