10

I'm trying to use LiveData with the Content Provider on Android, however I cannot manage it because the Provider query method is as follows:

public Cursor query

so it returns a Cursor, while I need a LiveData. If I try to change the return type for the query method to

public LiveData<Cursor> query

I get the error:

 "error: query(Uri,String[],String,String[],String) in FaProvider cannot override query(Uri,String[],String,String[],String) in ContentProvider
return type LiveData<Cursor> is not compatible with Cursor"

Is there any solution for using LiveData with Content Provider?

Aniruddh Parihar
  • 3,072
  • 3
  • 21
  • 39
ltedone
  • 639
  • 1
  • 6
  • 12
  • 1
    Create your own implementation of MutableLiveData class, receiving the Content's Provider URI as a parameter. In the onActive() method, register the content provider observer and whenever it's onChange() method is called, post the value to your LiveData: – Faizzy Sep 16 '19 at 07:52

1 Answers1

0

Should be able to wrap the cursor with a mutable live data object like @mohd-faizan mentioned

abstract class ContentProviderLiveData<T>(
private val context: Context,
private val uri: Uri ) : MutableLiveData<T>() {
private lateinit var observer: ContentObserver

override fun onActive() {
    observer = object : ContentObserver(null) {
        override fun onChange(self: Boolean) {
            // Notify LiveData listeners an event has happened
            postValue(getContentProviderValue())
        }
    }

    context.contentResolver.registerContentObserver(uri, true, observer)    }

override fun onInactive() {
    context.contentResolver.unregisterContentObserver(observer)
}

/**
 * Implement if you need to provide [T] value to be posted
 * when observed content is changed.
 */
abstract fun getContentProviderValue(): T

}

More here: https://medium.com/@jmcassis/android-livedata-and-content-provider-updates-5f8fd3b2b3a4

pantos27
  • 629
  • 4
  • 13
  • This is totally wrong solution ... `getContentProviderValue()` would be called on main thread ... and if I correctly understand `getContentProviderValue()` would do a `ContentProvider.query` which obviously should not be called on main thread... I do not see any right solution the only one which I'm aware of is `androidx.loader.app.LoaderManager` implementation ... but is hard to reuse in `ViewModel` – Selvin Mar 03 '22 at 14:07