【问题标题】:How to observe contentprovider change? android如何观察 contentprovider 变化?安卓
【发布时间】:2012-06-28 04:11:33
【问题描述】:

我创建了一个 Contentprovide 并像这样实现它的 update() 方法:

@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;
}

如何在我的 appwidget 中获得通知?谢谢!

我正在尝试这个解析器,但没有日志(--------------------更改日期)打印:

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);
        }
    }

所以,我终于通过 4 个步骤解决了:

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

到 ContentProvider 的 updat() insert() delete() 回调。

  1. 创建一个新的观察者和新的线程来处理它。

  2. 在 Observer 的 onChange() 中调用 notifyAppWidgetViewDataChanged()。

  3. 删除小部件并放置一个新小部件。

就是这样。

【问题讨论】:

  • 感谢分享。我认为在 onEnabled 中注册观察者是不够的,因为在设备重启后不会再次调用 onEnabled。我会把它放到 onReceive 中。

标签: android android-contentprovider android-appwidget notify


【解决方案1】:

您可以使用ContentObserver 类。您只需实现该类并使用getContentResolver().registerContentObserver() 方法注册观察者。

【讨论】:

  • @Ctristian 谢谢!而且我使用了 ContentObserver,但它没有调用回调 onChange()。我已将代码更新为问题。我对如何使用 Observer 以及如何更新小部件有点困惑。再次感谢!
  • 我认为您无法在 AppWidgetProvider 中注册观察者。相反,从您的 AppWidgetProvider 启动服务,然后从那里注册您的 ContentObserver
  • 我已经解决了。上面更新了完整的代码。谢谢。
  • @Cristian 我有类似的疑问。在我的应用程序中,我使用内容提供程序 :-android.provider.MediaStore.Images.Media.EXTERNAL_CONTENT_URI 来列出图像文件。现在我希望每当这个内容提供者数据发生变化时,我想向用户发送一条消息。我怎样才能做到这一点。请帮忙
猜你喜欢
  • 1970-01-01
  • 2011-06-27
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-07-03
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多