In the past two years, there is a trend to provide a default architecture to be used for Android apps. And suddenly you see a lot of: architecture components, kotlin, mvvm, livedata, observables, etc.

So you start playing in small personal projects and finally it gets to some project at work.

While there are a lot of examples “common” implementations such as accessing rest APIs, you may be faced with a different issue: how about content providers? And more specifically, how to know if a URI of a content provider has changed, notifying my view to update itself?

Searching the wild web I could not find anything… so what should I do?! I had no hope.

Illustration by Chioma Ebinama.

Luckily there is always an option and it is quite simple actually: what if I implement my own LiveData to observe a Content Provider’s URI!?

TL&DR

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:

Really simple! See the details bellow.

LiveData implementation

Android’s LiveData

How do I do that? If you check LiveData’s source, you’ll see it is an abstract class:

https://developer.android.com/reference/androidx/lifecycle/LiveData.html

LiveData is a data holder class that can be observed within a given lifecycle. This means that an Observer can be added…

We could just implement it, attach an observer to it and listen to ContentProvider URI changes. The later requires us to implement an ContentObserver for the provided uri:

https://developer.android.com/reference/android/content/ContentResolver.html#registerContentObserver(android.net.Uri,%20boolean,%20android.database.ContentObserver)

public final void registerContentObserver (Uri uri, 
                boolean notifyForDescendants, 
                ContentObserver observer)

We need an Uri and an ContentObserver, which we’ll create later.

Looks simple, no!? Let’s do it:

Note we created an Abstract class, so you can implement the custom get provider values if needed.

How do we attach our ContentObserver to the LiveData? We must first override the method where LiveData is started (and stopped):

Now we just implement our observer:

Really simple, no!? We just create the object implementation of ContentObserver and whenever onChange() is called, we post the value to your LiveData! Also note that we unregistered the observer to avoid memory leaks.


That’s it… No, wait a second: how do I use it?

Well, as an example, let’s implement it for Android’s contacts provider:

ContactsLiveData will be notified whenever there is a change in your contact list (don’t forget to add android.permission.READ_CONTACTS to your Android’s manifest if you are running this sample).

Don’t forget to implement getContentProviderValue() for your needs.

That’s simple as that! Let me know if you have any doubts. Suggestions are also welcome!

Publicado originalmente no Medium.