Search code examples
androidandroid-contentprovidercontentobserver

Android - Auto update app icon badge counter from content provider?


I have used this solution to add a badge counter to my app icon. I am using the counter to show how many items there are in the app's queue_table that are waiting to be sent to the server.

First of all, I have create a MyBootReceiver class that updates the badge count when the device boots. This part works fine.

The part I need advice on is the right way to keep the badge count updated whenever the queue is updated. (The queue can be updated by various components of the app - e.g., from the user manually adds items to the queue and from MyIntentService sending queued items to the server).

My queue_table is accessible via a ContentProvider in the app, so what I essentially need to know is the best way to monitor this content provider for changes (so the badge icon can be updated accordingly).

I am wondering if the best (or only) solution would be for me to create a MyApplication class that registers a ContentObserver in its onCreate method - e.g.,

MyApplication.java

@Override
public void onCreate() {
    super.onCreate();

    /*
     * Register for changes in queue_table, so the app's badge number can be updated in MyObserver#onChange()
     */
    Context context = getApplicationContext();
    ContentResolver cr = context.getContentResolver();
    boolean notifyForDescendents = true;
    myObserver = new MyObserver(new Handler(), context);
    cr.registerContentObserver(myContentProviderUri, notifyForDescendents, myObserver);


}

Also, if I do use such a solution, would I need to worry about unregistering myObserver and, if so, how would I do that in MyApplication?


Solution

  • The way I did it was to use a ContentObserver in my MyApplication class.

    If you don't have a MyApplication class already, you need to specify it in your manifest file by adding the android:name=".MyApplication" attribute to your <application /> element.

    Then you create the the MyApplication class that contains a ContentObserver like this:

    package com.example.myapp;
    
    import android.app.Application;
    import android.content.ContentResolver;
    import android.content.Context;
    import android.database.ContentObserver;
    import android.net.Uri;
    import android.os.Handler;
    
    public class MyApplication extends Application {
    
        private static String LOG_TAG = MyApplication.class.getSimpleName();
    
        public MyApplication() {
            super();
        }
    
        private MyContentObserver myContentObserver = null;
    
        @Override
        public void onCreate() {
            super.onCreate();
    
    
            /*
             * Register for changes in tables associated with myUri, so the app's badge number can be updated in MyContentObserver#onChange()
             */
            myContentObserver = new MyContentObserver(new Handler(), this);
            ContentResolver cr = getContentResolver();
            boolean notifyForDescendents = true;
            Uri[] myUri = ...;
            cr.registerContentObserver(myUri, notifyForDescendents, myContentObserver);
    
        }
    
        private class MyContentObserver extends ContentObserver {
    
            public MyContentObserver(Handler handler, Context context) {
                super(handler);
            }
    
            @Override
            public void onChange(boolean selfChange) {
                this.onChange(selfChange, null);
            }
    
            @Override
            public void onChange(boolean selfChange, Uri uri) {
    
                Utilities.updateBadgeCount();
    
            }
    
        }
    
    }