the app I'm currently working on has to react on changes in the calendar or event database, therefore the Observer below gets registered with the URI:
content://com.android.calendar (for older Devices: content://calendar)
The "problem" is that the Observer gets (sometimes) called several times, when respective data gets changed. If I register two separate ContentResolver, one for .../calendars and one for .../events they still get often called multiple times. What I try to achieve with the following code is to buffer those multiple calls, as the ContentResolver itself calls a service, that would run a lot of code. So the service should only get called once for many ContentObserver calls in a short period of time.
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());
}
}
My idea to solve that problem, was to generate a thread if a saved value ("int first" from SharedPreferences) equals 1. If the observer would get called another time while that thread sleeps, the value would get raised and the thread would sleep again...
Unfortunately the Thread blocks other incoming calls, so that its loop never gets extended. The Logs in my original code, showed me that the SharedPreferences get changed after the Thread is done!
- Does anybody have a solution for me? (I'm new to threading...)
- Should I implement another service for this buffering work?
- General: Is it ok to transfer Context into a ContentObserver?
Thanks in advance! ;)