Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to observe contentprovider change? android

I'v created a Contentprovide and implements it's update() method like this:

@Override
public int update(Uri uri, ContentValues values, String selection, String[] selectionArgs) {
    final SQLiteDatabase db = mHelper.getWritableDatabase();
    int count = db.update(InslideDB.FOLDER_TABLE, values, selection, selectionArgs);

    /* To notify the observer */
    this.getContext().getContentResolver().notifyChange(URI, null);  
    return count;
}

How can I get notified in my appwidget? Thanks!

I'm trying this Resolver but no Log (--------------------Date Changed) print:

class DataProviderObserver extends ContentObserver {
    private AppWidgetManager mAppWidgetManager;
    private ComponentName mComponentName;

    DataProviderObserver(AppWidgetManager mgr, ComponentName cn, Handler h) {
        super(h);
        mAppWidgetManager = mgr;
        mComponentName = cn;
    }

    @Override
    public void onChange(boolean selfChange) {
        super.onChange(selfChange);  //NOTE: Have to call this. dwy.

        // The data has changed, so notify the widget that the collection view needs to be updated.
        // In response, the factory's onDataSetChanged() will be called which will requery the
        // cursor for the new data.

        Log.d("PresenterWidgetProvider", "--------------------Date Changed");

        mAppWidgetManager.notifyAppWidgetViewDataChanged(
                mAppWidgetManager.getAppWidgetIds(mComponentName), R.id.inslide_grid);
    }
}


public class PresenterWidgetProvider extends AppWidgetProvider{

    private static final String AUTHORITY = "com.apps.slide";

    static final Uri CONTENT_URI = Uri.parse("content://" + AUTHORITY + "/folder");

    public static final String EXTRA_INSLIDE_PATH = "EXTRA_WIDGET_PATH";
    private static HandlerThread sWorkerThread;
    private static Handler sWorkerQueue;
    private static DataProviderObserver sDataObserver;

    public PresenterWidgetProvider () {

        // Start the worker thread to update Content Provider.
        sWorkerThread = new HandlerThread("PresenterWidgetProvider worker");
        sWorkerThread.start();
        sWorkerQueue = new Handler(sWorkerThread.getLooper());

    }

    @Override
    public void onEnabled(Context context) {
        // Register for external updates to the data to trigger an update of the widget.  When using
        // content providers, the data is often updated via a background service, or in response to
        // user interaction in the main app.  To ensure that the widget always reflects the current
        // state of the data, we must listen for changes and update ourselves accordingly.
        final ContentResolver r = context.getContentResolver();
        if (sDataObserver == null) {
            final AppWidgetManager mgr = AppWidgetManager.getInstance(context);
            final ComponentName cn = new ComponentName(context, PresenterWidgetProvider.class);
            sDataObserver = new DataProviderObserver(mgr, cn, sWorkerQueue);
            r.registerContentObserver(CONTENT_URI, true, sDataObserver);
            Log.d("PresenterWidgetProvider", "--------------------onEnabled. sDataObserver = " + sDataObserver);
        }
    }

So, I finally solved it by 4 steps:

  1. Add this.getContext().getContentResolver().notifyChange(URI, null);

to ContentProvider's updat() insert() delete() callbacks.

  1. Create a new Observer and new Thread to handle it.

  2. Call notifyAppWidgetViewDataChanged() in Observer's onChange().

  3. Delete the widget and place a new one.

That's it.

like image 242
herbertD Avatar asked Jun 28 '12 04:06

herbertD


People also ask

How do I use ContentObserver on Android?

To use the ContentObserver you have to take two steps: Implement a subclass of ContentObserver. Register your content observer to listen for changes.

What is Android ContentProvider?

Content providers are one of the primary building blocks of Android applications, providing content to applications. They encapsulate data and provide it to applications through the single ContentResolver interface. A content provider is only required if you need to share data between multiple applications.

How can I access my content provider from another application?

After creating the content provider , specify the content provider in the manifest file. You can mention content provider using the tag. Inside the provider tag dont forget to mention the name and authorities attributes. This declaration should be ..


1 Answers

You can use the ContentObserver class. You just have to implement that class and use the getContentResolver().registerContentObserver() method to register the observer.

like image 110
Cristian Avatar answered Oct 27 '22 08:10

Cristian