With ICS, we now have APIs for the Calendar! :)
My question is, how do we determine if an event has been updated. Ideally this could be done with a BroadcastReceiver, but I don't think there is one that is publicly accessible. There is some event broadcasted, but I don't think it's accessible to non-system apps.
02-06 23:05:05.316: I/CalendarProvider2(9201): Sending notification intent: Intent { act=android.intent.action.PROVIDER_CHANGED dat=content://com.android.calendar }
02-06 23:05:05.320: W/ContentResolver(9201): Failed to get type for: content://com.android.calendar (Unknown URL content://com.android.calendar)
This is my work around for now. Is there a better way? Users can get squimish if they see a service running for along time and often will kill it to save battery life.
public class CalendarUpdatedService extends Service {
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
int returnValue = super.onStartCommand(intent, flags, startId);
getContentResolver().registerContentObserver(
CalendarContract.Events.CONTENT_URI, true, observer);
return returnValue;
}
@Override
public IBinder onBind(Intent intent) {
return null;
}
ContentObserver observer = new ContentObserver(new Handler()) {
@Override
public boolean deliverSelfNotifications() {
return true;
}
@Override
public void onChange(boolean selfChange) {
super.onChange(selfChange);
//code goes here to update
}
};
}
Click Import & Export in the settings, and you'll find the Import option. Select the file you just exported from the other calendar, then choose the calendar you'd like to import the dates to. You've now imported all of your events.
When you sync your calendar on your mobile device, the same events will show up when you use Google Calendar on your computer.
I use a static singleton class (you could also extend Application) with methods to register/unregister multiple observers for different providers such as the calendar provider(s). I store this in a HashMap so I can determine which observers are registered at a later time.
It is ugly but there doesn't seem to be a better solution.
EDIT This receiver:
public class CalendarChangedReceiver extends BroadcastReceiver {
private static final String TAG = "CalendarChangedReceiver";
@Override
public void onReceive(Context context, Intent intent) {
Log.d(TAG, "calendar changed! "+intent.toUri(Intent.URI_INTENT_SCHEME));
}
}
With this manifest declaration:
<receiver android:name=".CalendarChangedReceiver">
<intent-filter>
<action android:name="android.intent.action.PROVIDER_CHANGED"/>
<data android:scheme="content"/>
<data android:host="com.android.calendar"/>
</intent-filter>
</receiver>
Will catch changes to Events and Calendars in ICS. If you are using the old undocumented calendar provider the only solution is ContentObserver(s) in a static class or service.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With