1

When I create a Google Calendar event and attach extended property to it, all is working as expected - both event and its extended property get synced so they can be accessed from different devices. Here is the code:

// create event with extended property
ContentValues values = new ContentValues();
...
values.put(CalendarContract.Events.HAS_EXTENDED_PROPERTIES, 1);
Uri eventURI = contentResolver.insert(CalendarContract.Events.CONTENT_URI, values);
long eventID = Long.parseLong(eventURI.getLastPathSegment());

Uri extendedPropertyURI = CalendarContract.ExtendedProperties.CONTENT_URI;
extendedPropertyURI = extendedPropertyURI.buildUpon()
    .appendQueryParameter(CalendarContract.CALLER_IS_SYNCADAPTER, "true")
    .appendQueryParameter(CalendarContract.Events.ACCOUNT_NAME, "...")
    .appendQueryParameter(CalendarContract.Events.ACCOUNT_TYPE, "com.google").build();

ContentValues extendedValues = new ContentValues();
extendedValues.put(CalendarContract.ExtendedProperties.EVENT_ID, eventID);
extendedValues.put(CalendarContract.ExtendedProperties.NAME, "name");
extendedValues.put(CalendarContract.ExtendedProperties.VALUE, "valueA");

contentResolver.insert(extendedPropertyURI, extendedValues);

Now I want to update my extended property, let's say replace "valueA" with "valueB", here is what I do:

// update extended property
int propertyID = 123; // got this ID from CalendarContract.ExtendedProperties._ID, let me omit the code
ContentValues updatedValues = new ContentValues();
updatedValues.put(CalendarContract.ExtendedProperties.VALUE, "valueB");
Uri updateUri = ContentUris.withAppendedId(extendedPropertyURI, propertyID);
contentResolver.update(updateUri, updatedValues, null, null);

The extended property value gets updated successfully, I can see "valueB" on the device where the update has been executed. But it never syncs with Google Calendar server so other devices always show "valueA". I can observe the same behavior when I am trying to add another extended property to the same event - I can see both extended properties on current device only. New extended property never gets synced.

Can anyone please help to understand what I am doing wrong? I need to be able to add multiple extended properties to an event as well as edit these properties later.

P.S. Instead of attaching one single initial extended property, I could attach multiple extended properties to a new event in a loop, they all will be synced across devices successfully:

for (int i = 0; i < 10; i ++) {
    ContentValues extendedValues = new ContentValues();
    extendedValues.put(CalendarContract.ExtendedProperties.EVENT_ID, eventID);
    extendedValues.put(CalendarContract.ExtendedProperties.NAME, "name");
    extendedValues.put(CalendarContract.ExtendedProperties.VALUE, "value" + i);

    contentResolver.insert(extendedPropertyURI, extendedValues);
}

So the syncing issue only occurs when I am trying to update an existing property or add (not at same time in a loop!) a new property to an event which already has "initial" extended properties.

Zmiter
  • 298
  • 4
  • 15
  • Does this help? http://stackoverflow.com/questions/27293675/why-calendarprovider-doesnt-allow-writting-extendedproperties – luc Mar 03 '16 at 19:03
  • No. Same behavior when I use "real" sync adapter: only the initial extended property syncs, all further actions (add, update, delete) happen on the current device only. – Zmiter Mar 03 '16 at 23:34

2 Answers2

1

The explanation is simple. All changes made by a sync adapter (including inserting/updating the extended properties) are not being synced with Google servers automatically by standard Android syncing mechanism. So if you need to sync the extended property local change, you need to make the related local event dirty (not by setting CalendarContract.Events.DIRTY=1 as it also requires using a sync adapter; running ContentResolver.insert/update without any actual changes is enough). As the event is dirty now and the event change does not come from a sync adapter, Android will automatically sync both the event and its extended properties soon.

It is important to update the local event before updating its extended properties. If you update the extended properties first, the change will be lost after Android completes syncing.

Zmiter
  • 298
  • 4
  • 15
0

You may use 'Incremental sync' to perform repeatedly and updates the client with all the changes that happened ever since the previous sync. To do this, you need to perform a list request with your most recent sync token specified in the syncToken field.

Original query

GET /calendars/primary/events?maxResults=10&singleEvents=true&syncToken=CPDAlvWDx70CEPDAlvWDx

// Result contains the following

"nextPageToken":"CiAKGjBpNDd2Nmp2Zml2cXRwYjBpOXA",

Retrieving next page

GET /calendars/primary/events?maxResults=10&singleEvents=true&syncToken=CPDAlvWDx70CEPDAlvWDx&pageT

For more details regarding Incremental sync, follow this link: https://developers.google.com/google-apps/calendar/v3/sync#incremental_sync

Android Enthusiast
  • 4,826
  • 2
  • 15
  • 30
  • Thanks but 1) I am using CalendarProvider rather than GC API and 2) I don't believe incremental sync can help - I can easily sync any event changes except for the cases with extended properties described above. – Zmiter Mar 03 '16 at 10:35