Grokking Android

Getting Down to the Nitty Gritty of Android Development

Use Android’s ContentObserver in Your Code to Listen to Data Changes

By 27 Comments

When you are using a content provider as a client, chances are that you want to know whenever the data changes. That’s what Android’s class ContentObserver is for.

To use the ContentObserver you have to take two steps:

Implement a subclass of ContentObserver

ContentObserver is an abstract class with no abstract methods. Its two onChange() methods are implemented without any logic. And since these are called whenever a change occurs, you have to override them.

Since Google added one of the two overloaded onChange() methods as recently as API-level 16, this method’s default behavior is to call the other, older method.

Here is, what a normal implementation would look like:

class MyObserver extends ContentObserver {		
   public MyObserver(Handler handler) {

   public void onChange(boolean selfChange) {
      this.onChange(selfChange, null);

   public void onChange(boolean selfChange, Uri uri) {
      // do
      // depending on the handler you might be on the UI
      // thread, so be cautious!

Some things are important with the above code. The first thing you must know, is that the second method is only available from API level 16 onwards. That’s why I added the SuppressLint annotation. The code works fine on older devices, but in this case Android obviously always calls the old one. So your code should not rely on a URI to work properly.

Also notice the Handler parameter in the constructor. This handler is used to deliver the onChange() method. So if you created the Handler on the UI thread, the onChange() method will be called on the UI thread as well. In this case avoid querying the ContentProvider in this method. Instead use an AsyncTask or a Loader.

If you pass a null value to the constructor, Android calls the onChange() method immediately – regardless of the current thread used. I think it’s best to always use a handler when creating the ContentObserver object.

Register your content observer to listen for changes

To register your ContentObserver subclass you simply have to call the ContentResolver's registerContentObserver() method:


It takes three parameters. The first is the URI to listen to. I cover the URI in more detail in the next section.

The second parameter indicates whether all changes to URIs that start with the given URI should trigger a method call or just changes to exactly this one URI. This can be handy for say the ContactsContract URI with its many descendants. But it can also be detrimental in that the actual change, that caused the method call, is even more obscure to you.

The third parameter is an instance of your ContentObserver implementation.

The URIs you can observe

As described in my introduction to content providers content URIs can be directory-based or id-based.

Both of these URI-types can be used for your content observer. If you have a detail screen you would use an id-based URI for your observer, and when you use a list of data a directory-based URI is more appropriate.

This does not always work, though. ContactsContract for example always triggers a change, whenever any contact was changed, even if you are listening to a more specific URI. It depends on the correct implementation of the content provider. I have filed a bug report for the ContactsContract provider. Please vote for this issue, if you agree.

When you write a content provider for your app, take care of notifying the correct URI. Only if you do so, the feedback mechanism described here works. This is important for your observers – or if the provider is exported for your clients’ observers as well. And it is also important for Loaders. See my post about how to write content providers to learn more about this.

Note: If you use Loaders you do not need to listen to changes yourself. In this case Android registers a ContentObserver and triggers your LoaderCallbacks onLoadFinished() method for any changes.

Do not forget to unregister your content observer

When you have registered a content observer, it is your responsibility to also unregister it. Otherwise you would create a memory leak and your Activity would never be garbage collected.

To unregister you call the unregisterContentObserver() method of the ContentResolver:


You register your observer in the onResume() lifecycle method and you unregister it in the onPause() method.

This is not relevant to ContentObservers alone but applies to everything you register. As a general rule of thumb: Whenever you start coding registerXYZ() immediately also add the code to unregisterXYZ(). Otherwise you might later forget about it and inadvertently create memory leaks.

Sometimes you wish you would know more about the changes

The main downside with content observers is, that you do not get any additional information about what has changed. For directory-based URIs it would be nice to get a list of IDs that have changed. Some providers can have many records and re-reading all records, if only a few have changed, is a waste of resources in a mobile environment. Also some hint of the type of change would be nice. Like if a record was deleted or inserted.

The ContentProvider responsible for the change knows all this. So this would be no problem to add. Of course it has to be added in a backwards-compatible way.

API level 16 added a URI to the onChange() method, but this isn’t sufficient for updates of multiple records and also doesn’t tell you anything about the type of change.

Wrapping up

This quick tip showed you how to leverage Android’s ContentObserver. This makes it easy to react to updates of the data you are using.

As you have seen, it is pretty easy to implement the ContentObserver subclass. You have also seen that you can register it to listen to id-based as well as directory-based URIs.

Of course this works only, if the content provider for the URI you are observing, is correctly implemented and notifies clients of changes. If you are implementing a content provider yourself, have a look at my tutorial on writing a content provider for how to do so.

Wolfram Rittmeyer lives in Germany and has been developing with Java for many years.

In recent years he shifted his attention to Android and blogs about anything interesting that came up while developing for Android.

You can find him on Google+ and Twitter.

27 thoughts on “Use Android’s ContentObserver in Your Code to Listen to Data Changes”

  1. Doesn’t one need this only when not using Loaders?

    1. Yes. As I have stated in the post, you do not need content observers for data that you have loaded via Loaders.

      But there might still be a need for them, if you need to know about changes of other data like some data of the in-built content providers. Or if fields in your database link to fields of the standard providers (e.g. the lookup uri of a contact).

      1. Hi Wolfram,

        Thanks for the great post! I noticed that you mentioned that if I use a Loader (i.e. a CursorLoader) I don’t need to register a ContentObserver. However, I’ve noticed that in my app, I have an activity that simply emulates a submission form. When the user hits submit, it makes an insertion into the database table and calls finish(), which resumes my previous activity, which is displaying results from that same database table. However, the LoaderCallbacks aren’t being called automatically. I’ve had to explicitly put the initLoader() call in my onResume() method. Is this expected?

      2. Wonderful great going, I love your work and look forward for more work from your side. I am a regular visitor of this site and by now have suggested many people.

  2. Wolfram, your post was very helpful. I just got my content observer for contacts working – to the extent that it notifies my app when a contact changes. Hurray!

    I’d like to point out a clarification that may also help others. I found your call:

    this.onChange(selfChange, null)

    ambiguous, not being sure what “this” is (in my code, it turned out to be the observer, which caused a stack overflow). What worked for me is

    handler.sendMessage (msg)

    where “msg” is whatever info you want to pass to your activity. In total, I used this code:

    public void onChange (boolean selfChange)
    Message msg = handler.obtainMessage();
    msg.what = CONTACTS_CHANGED; // final int defined elsewhere
    msg.obj = null;
    handler.sendMessage (msg);

    My next challenge is figuring out how to detect which contact was changed. As you said, the provider does not give you anything 🙁

    I hope you find this useful.

    1. Peri, did you find a way to figure out which contact that was changed?

      1. No. I don’t think Google expected Contacts to be used in a way where other apps would want to know about individual changes.

    2. Hi,

      OnChange() only get called when app is in stack of running applications. It doesn’t get called if i start application. Any idea how to implement it.

  3. Hi

    when ever there is changes in setting for when we changes the state of Bluetooth it should raise alert and revert back to old state. can u help me in this .

  4. Hi,
    Supposing I use Supposing I use AsyncTaskLoader, do I need to register a ContentObserver?
    Also, how do I register content observer for my database.


    1. Wolfram Rittmeyer

      ContentObservers are only for content providers. If you use SQLite directly and have a custom AsyncTaskLoader implementation you cannot use it – but you might want to look at Mark Murhpy’s SQLiteCursorLoader. Even if you do not want to use this library have a look at the sources to see how he implements this with a Loader.

      If you have multiple place that might be interested in content changes an event bus solution might be handy. Use one db abstraction to only change the database from there and have all modification methods submit an event bus notification. See Otto or EventBus for more on this.

  5. Mohamed Elmanasrah

    thanks for good informations

  6. Hi Wolfram,
    Thanks for the useful post. Have a doubt in my particular case on how or whether to use a ContentObserver. ( Might be a silly question but please bear with me as I m new into Android ).

    I have used a Loader to Load the Contacts from DB asynchronously. Before loading I will be checking the ContactsUri Contacts whether they are registered users with mobile numbers. So basically the workflow is like Loading all the contents from Content provider , check with SQLite Db if not exist insert. Then Read this User Contacts from DB through a loader asynchronisly. Now , what I need is to get notified to the App whether there is any change for the Contacts in the Phone if so trigger the update to DB.

    Can you please let me know if I can use the same logic here

    1. There is no proper solution for that – because any long-running service would require an ongoing notification. Unless the user cares very much about what the service does, this is not recommended. So in your case: Don’t do that!

      Some ways to mitigate it, would be to periodically check for changes. But, please, use one of the non-wakeup types in your AlarmManager. (RTC or ELAPSED_REALTIME). There is no need to wake up a device for these checks. If you expect changes to happen frequently and your app must be correct, there is no other way than to additionally also check at app startup time (that is in your Application subclass). Asynchronously, of course 🙂

      While you app is running you can listen to the events in your Application subclass. So the AlarmManager is only necessary when your app is not running. See my tutorial about (un)registering BroadcastReceivers in code.

      1. Thanks for the suggestion. I had implemented the logic already using the Application subclass and checks each time when the App loads.

  7. Thank you for writing this informative tutorial for the ContentObserver callback. Having read this and many other threads on the subject, it’s my opinion that using a ContentObserver in an Activity is of minimal value (you are constantly unregistering it when the Activity is paused) and using it in a Service is of questionable value since the service can be destroyed at any time. I suspect that the most valuable use of a ContentObserver is in a custom widget (e.g. custom listview) where the underlying data come from a Content Provider.

    It seems to me that the best method of being notified of data changes by a content provider is via a Broadcast Receiver. Unfortunately, I’ve not found any concrete documentation on the intents broadcast by the providers.

    There isn’t really a question here except to ask for your comments on this observation.

    1. Basically I agree: They are only of use for longlived components. E.g. in retained fragments.

      Keep in mind, that ContentObservers are at the heart of Loaders. So obviously they are not useless 🙂

  8. Very useful post, thanks a lot.
    but i was wondering that if i want to register ContentObserver to listen to sms changes in (background), how to do that ?

    I must to register the Observer within a Service ? , what the most appropriate way to listen to content for 24/7 ?

    Best regards,

    1. For SMS you need a BroadcastReceiver. But with Android 4.4 handling changed dramatically and receiving text messages only works for the default app for text messages.

      This blog post on Android’s developer page describes the changes to SMS messaging in Android 4.4 perfectly.

      Broadcast receivers, BTW, are notfied all the time (disregarding Android Doze mode for the moment). So for them to receive messages no long running service is needed.

      1. Yes, that’s right for Incoming SMS i used broadcast receiver but there’s no receiver for Outgoing SMS, so that i needed to put an observer with URI “content://sms” to listen to the changes.

        1. If you’re the default app, shouldn’t you know when you sent one?

          But assuming you just want to deal with other apps sending text messages, then there’s the question of what you want to do and where you want to do it?

          You can only listen, when the ContentObserver is active. But most likely your ContentObserver won’t be active when the user sends her text message. So you basically are stuck to check when your component is active again for any changes that happened in the meantime. A bit cumbersome, but achievable by quering the content provider. You just have to check for any text messages with the DATE_SENT column set to a newer date than that of your last check.

  9. Thanks for awesome sharing.

    P.S. I want to follow you.. Where is your twitter link?

  10. Thanks for your post! I am writing an app widget and I want it to be notified as telephone call log updated. I’ve implemented ContentObserver but looks like in several hours it stops working. I see no reason for that. I see that on Samsung api 16.

    1. Wolfram Rittmeyer

      A ContentObserver is only alive for as long as the component you added it to is alive. That is normal and expected behaviour and in this case it is not something Samsung screwed up.

      Either create a long-living service or create a BroadcastReceiver to be notified when the phone state changes. I strongly suggest to use the second option.

  11. I am trying to check if the GPS is getting disabled at runtime by this procedure.. I am using the uri Settings.Secure.LOCATION_MODE and the handler created with Looper.getMainLooper().
    Still unable to receive notifications..

    1. Wolfram Rittmeyer

      Why not listen to the PROVIDERS_CHANGED_ACTION?

      Be careful though that misused implicit broadcasts can needlessly waste system resources when your app is in the background. For this reasons Android O is going to change how those are treated. Find out more about this in Mark Murphy’s CommonsBlog.

Leave a Reply

Your email address will not be published. Required fields are marked *