Android Calendar: how to write sync adapter for calendar INSERT

Jason Posit picture Jason Posit · May 3, 2013 · Viewed 8.4k times · Source

I would basically like to reopen the following unanswered post:

I would like to make use of the Android Calendar Provider API to create a calendar and insert events into it. The calendar that is created must not be a local copy. It must synchronize with the Google (online) Calendar. The documentation says in order to do this I must use a sync adapter. But how do I write such a sync adapter?

So far I've found the two following posts but no solution.

I want to use the Android Calendar API for this and not the Google API so that users can work offline.

Answer

tiguchi picture tiguchi · Aug 19, 2013

It looks like Google messed up CalendarContract in this regard. The documentation is not completely clear about it:

...inserting new calendars should be done as a sync adapter.

The way this is phrased appears to me like there is the slim chance it might work. But practically speaking (judging your linked other SO questions) an app using CalendarContract cannot create synchronized calendars.

You really do not want to go through all that trouble of creating your own SyncAdapter. I did it once for one of my apps because I wanted a reliable solution for having synchronized calendar access on pre Ice Cream Sandwich devices (where CalendarContract doesn't exist, yet).

That's a lot of work. It involves interfacing with the Google Calendar web service API (while respecting their access limitations), keeping a local copy of the data and synchronizing just the differences. Ultimately your own SyncAdapter would also duplicate the data of the already existing Google Calendar SyncAdapter.

What you could do as a workaround is just implementing the necessary "create calendar" function directly on the Google Calendar online API. It requires that your app asks the user for authorization via android.permission.USE_CREDENTIALS.

AccountManager can be used for getting the correct authorization token for accessing the Google Calendar API. The method getAuthToken requires an auth token type parameter. The correct one for calendar read / write access is the following string literal: "Manage your calendars".

There are two big problems with that workaround though:

  1. You cannot know for sure if the calendar synchronization backend makes use of Google Calendar. It's unfortunately a black box.

  2. You cannot know for sure when the calendar sync adapter is going to catch up with these changes. I guess it is possible to force a re-sync somehow. But even then, your app will be stalled. You cannot just operate based on that new calendar and use it right away. Your app must wait until the synchronization happened.

You could poll CalendarContract for that. Let your app wait and look for changes in a background thread until the new calendar shows up. Then you have its local id and move on.