11

I'vはContentprovideを作成し、それがこのようにupdate()メソッドを実装です:どのように私は私のappwidgetにcontentproviderの変更を観察するにはどうすればよいですか?アンドロイド

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

を通知を受けることができますか?ありがとう! I最後に、

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. は)(削除)(のContentProviderのUPDAT()を挿入するコールバックを this.getContext().getContentResolver().notifyChange(URI, null);

を追加します。

  1. 新しいObserverと新しいスレッドを作成して処理します。

  2. ObserverのonChange()でnotifyAppWidgetViewDataChanged()を呼び出します。

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

これだけです。

+1

これを共有いただきありがとうございます。オブザーバーをonEnabledに登録するだけでは不十分だと思います。これは、デバイスを再起動した後にonEnabledが再度呼び出されないためです。私はそれをonReceiveに入れました。 – mtotschnig

答えて

15

ContentObserverクラスを使用できます。そのクラスを実装し、オブザーバを登録するにはgetContentResolver().registerContentObserver()メソッドを使用するだけです。

+0

@Ctristianありがとう! ContentObserverを使用しましたが、コールバックonChange()をコールしませんでした。コードを質問に更新しました。 Observerの使い方と、ウィジェットの更新方法についてちょっと気になっています。再度、感謝します! – herbertD

+2

あなたは 'AppWidgetProvider'の中にオブザーバーを登録できないと思います。代わりに、あなたの 'AppWidgetProvider'からサービスを開始し、そこから' ContentObserver'を登録してください。 – Cristian

+0

私はそれを解決しました。完全なコードは上記で更新されています。ありがとうございました。 – herbertD

関連する問題