web-dev-qa-db-ja.com

コンテンツプロバイダーの変更を監視する方法は? android

私は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. オブザーバーのonChange()でnotifyAppWidgetViewDataChanged()を呼び出します。

  3. ウィジェットを削除して、新しいウィジェットを配置します。

それでおしまい。

15
herbertD

ContentObserver クラスを使用できます。そのクラスを実装し、getContentResolver().registerContentObserver()メソッドを使用してオブザーバーを登録する必要があります。

17
Cristian