私が現在取り組んでいるアプリは、カレンダーまたはイベント データベースの変更に対応する必要があるため、以下のオブザーバーは URI に登録されます。
content://com.android.calendar (古いデバイスの場合: content://calendar)
「問題」は、それぞれのデータが変更されたときに、Observer が (時々) 数回呼び出されることです。.../calendars 用と .../events 用の 2 つの個別の ContentResolver を登録すると、複数回呼び出されることがよくあります。次のコードで達成しようとしているのは、ContentResolver 自体が多くのコードを実行するサービスを呼び出すため、これらの複数の呼び出しをバッファリングすることです。そのため、このサービスは、短期間に多数の ContentObserver 呼び出しに対して 1 回だけ呼び出される必要があります。
public class Observer extends ContentObserver{
private Context con;
public Observer(Handler handler, Context con) {
super(handler);
this.con = con;
}
@Override
public void onChange(boolean selfChange) {
Log.i("TS", "Änderung an den Kalendern");
//Gets released after the first Change, waits and checks SharedPrefs in order to buffer multiple Calls in a short period of time!
//Changes get handled in the Service
Thread buffer = new Thread(){
@Override
public void run() {
int check = 1, last = 0;
do{
try {
sleep(5000);
} catch (InterruptedException e) {
e.printStackTrace();
}
last = check;
check = getCurrent();
} while(last != check);
releaseIntent();
}
};
SharedPreferences prefs = con.getSharedPreferences(con.getPackageName(), Context.MODE_PRIVATE);
Editor edit = prefs.edit();
int first = prefs.getInt(Constants.FIRST_ON_CHANGE, 1);
if(first == 1)
buffer.run();
first++;
edit.putInt(Constants.FIRST_ON_CHANGE, first);
edit.commit();
}
//returns the current control-integer from SharedPrefs (for Thread)
private int getCurrent(){
SharedPreferences prefs = con.getSharedPreferences(con.getPackageName(), Context.MODE_PRIVATE);
return prefs.getInt(Constants.FIRST_ON_CHANGE, 1);
}
//releases ContentChanged-Intent for Service, resets SharedPrefs
private void releaseIntent(){
con.getSharedPreferences(con.getPackageName(), Context.MODE_PRIVATE).edit().putInt(Constants.FIRST_ON_CHANGE, 1).commit();
AlarmManager alm = (AlarmManager) con.getSystemService(Context.ALARM_SERVICE);
alm.set(AlarmManager.RTC_WAKEUP, System.currentTimeMillis(), new PendingIntentCreator(con).createContentChangedIntent());
}
}
その問題を解決するための私の考えは、保存された値 (SharedPreferences からの "int first") が 1 に等しい場合にスレッドを生成することでした。そのスレッドがスリープしている間にオブザーバーが別の時間に呼び出されると、値が発生し、スレッドがスリープします。また...
残念ながら、スレッドは他の着信呼び出しをブロックするため、ループが拡張されることはありません。私の元のコードのログは、スレッドが完了した後に SharedPreferences が変更されることを示しました!
- 誰かが私に解決策を持っていますか? (私はスレッド化が初めてです...)
- このバッファリング作業のために別のサービスを実装する必要がありますか?
- 一般: Context を ContentObserver に転送してもよろしいですか?
前もって感謝します!;)