@Override protected String cursorToEntry(SyncContext context, Cursor c, Entry entry, Object info) throws ParseException { EventEntry event = (EventEntry) entry; SyncInfo syncInfo = (SyncInfo) info; String feedUrl = c.getString(c.getColumnIndex(Calendars.URL)); // update the sync info. this will be used later when we update the // provider with the results of sending this entry to the calendar // server. syncInfo.calendarId = c.getLong(c.getColumnIndex(Events.CALENDAR_ID)); syncInfo.calendarTimezone = c.getString(c.getColumnIndex(Events.EVENT_TIMEZONE)); if (TextUtils.isEmpty(syncInfo.calendarTimezone)) { // if the event timezone is not set -- e.g., when we're creating an // event on the device -- we will use the timezone for the calendar. syncInfo.calendarTimezone = c.getString(c.getColumnIndex(Events.TIMEZONE)); } // id event.setId(c.getString(c.getColumnIndex(Events._SYNC_ID))); event.setEditUri(c.getString(c.getColumnIndex(Events._SYNC_VERSION))); // status byte status; int localStatus = c.getInt(c.getColumnIndex(Events.STATUS)); switch (localStatus) { case Events.STATUS_CANCELED: status = EventEntry.STATUS_CANCELED; break; case Events.STATUS_CONFIRMED: status = EventEntry.STATUS_CONFIRMED; break; case Events.STATUS_TENTATIVE: status = EventEntry.STATUS_TENTATIVE; break; default: // should not happen status = EventEntry.STATUS_TENTATIVE; break; } event.setStatus(status); // visibility byte visibility; int localVisibility = c.getInt(c.getColumnIndex(Events.VISIBILITY)); switch (localVisibility) { case Events.VISIBILITY_DEFAULT: visibility = EventEntry.VISIBILITY_DEFAULT; break; case Events.VISIBILITY_CONFIDENTIAL: visibility = EventEntry.VISIBILITY_CONFIDENTIAL; break; case Events.VISIBILITY_PRIVATE: visibility = EventEntry.VISIBILITY_PRIVATE; break; case Events.VISIBILITY_PUBLIC: visibility = EventEntry.VISIBILITY_PUBLIC; break; default: // should not happen Log.e( TAG, "Unexpected value for visibility: " + localVisibility + "; using default visibility."); visibility = EventEntry.VISIBILITY_DEFAULT; break; } event.setVisibility(visibility); byte transparency; int localTransparency = c.getInt(c.getColumnIndex(Events.TRANSPARENCY)); switch (localTransparency) { case Events.TRANSPARENCY_OPAQUE: transparency = EventEntry.TRANSPARENCY_OPAQUE; break; case Events.TRANSPARENCY_TRANSPARENT: transparency = EventEntry.TRANSPARENCY_TRANSPARENT; break; default: // should not happen Log.e( TAG, "Unexpected value for transparency: " + localTransparency + "; using opaque transparency."); transparency = EventEntry.TRANSPARENCY_OPAQUE; break; } event.setTransparency(transparency); // could set the html uri, but there's no need to, since it should not be edited. // title event.setTitle(c.getString(c.getColumnIndex(Events.TITLE))); // description event.setContent(c.getString(c.getColumnIndex(Events.DESCRIPTION))); // where event.setWhere(c.getString(c.getColumnIndex(Events.EVENT_LOCATION))); // attendees long eventId = c.getInt(c.getColumnIndex(Events._SYNC_LOCAL_ID)); addAttendeesToEntry(eventId, event); // comment uri event.setCommentsUri(c.getString(c.getColumnIndexOrThrow(Events.COMMENTS_URI))); Time utc = new Time(Time.TIMEZONE_UTC); boolean allDay = c.getInt(c.getColumnIndex(Events.ALL_DAY)) != 0; String startTime = null; String endTime = null; // start time int dtstartColumn = c.getColumnIndex(Events.DTSTART); if (!c.isNull(dtstartColumn)) { long dtstart = c.getLong(dtstartColumn); utc.set(dtstart); startTime = utc.format3339(allDay); } // end time int dtendColumn = c.getColumnIndex(Events.DTEND); if (!c.isNull(dtendColumn)) { long dtend = c.getLong(dtendColumn); utc.set(dtend); endTime = utc.format3339(allDay); } When when = new When(startTime, endTime); event.addWhen(when); // reminders Integer hasReminder = c.getInt(c.getColumnIndex(Events.HAS_ALARM)); if (hasReminder != null && hasReminder.intValue() != 0) { addRemindersToEntry(eventId, event); } // extendedProperties Integer hasExtendedProperties = c.getInt(c.getColumnIndex(Events.HAS_EXTENDED_PROPERTIES)); if (hasExtendedProperties != null && hasExtendedProperties.intValue() != 0) { addExtendedPropertiesToEntry(eventId, event); } long originalStartTime = -1; String originalId = c.getString(c.getColumnIndex(Events.ORIGINAL_EVENT)); int originalStartTimeIndex = c.getColumnIndex(Events.ORIGINAL_INSTANCE_TIME); if (!c.isNull(originalStartTimeIndex)) { originalStartTime = c.getLong(originalStartTimeIndex); } if ((originalStartTime != -1) && !TextUtils.isEmpty(originalId)) { // We need to use the "originalAllDay" field for the original event // in order to format the "originalStartTime" correctly. boolean originalAllDay = c.getInt(c.getColumnIndex(Events.ORIGINAL_ALL_DAY)) != 0; Time originalTime = new Time(c.getString(c.getColumnIndex(Events.EVENT_TIMEZONE))); originalTime.set(originalStartTime); utc.set(originalStartTime); event.setOriginalEventStartTime(utc.format3339(originalAllDay)); event.setOriginalEventId(originalId); } // recurrences. ICalendar.Component component = new ICalendar.Component("DUMMY", null /* parent */); if (RecurrenceSet.populateComponent(c, component)) { addRecurrenceToEntry(component, event); } // if this is a new entry, return the feed url. otherwise, return null; the edit url is // already in the entry. if (event.getEditUri() == null) { return feedUrl; } else { return null; } }
private void getServerDiffsForFeed( SyncContext context, SyncData baseSyncData, SyncableContentProvider tempProvider, String feed, Object baseSyncInfo, SyncResult syncResult) { final SyncInfo syncInfo = (SyncInfo) baseSyncInfo; final GDataSyncData syncData = (GDataSyncData) baseSyncData; Cursor cursor = getContext() .getContentResolver() .query( Calendar.Calendars.CONTENT_URI, CALENDARS_PROJECTION, SELECT_BY_ACCOUNT_AND_FEED, new String[] {getAccount(), feed}, null /* sort order */); ContentValues map = new ContentValues(); int maxResults = getMaxEntriesPerSync(); try { if (!cursor.moveToFirst()) { return; } // TODO: refactor all of this, so we don't have to rely on // member variables getting updated here in order for the // base class hooks to work. syncInfo.calendarId = cursor.getLong(0); boolean syncEvents = (cursor.getInt(6) == 1); long syncTime = cursor.getLong(2); String feedUrl = cursor.getString(3); String name = cursor.getString(4); String origCalendarTimezone = syncInfo.calendarTimezone = cursor.getString(5); if (!syncEvents) { // should not happen. non-syncable feeds should not be scheduled for syncs nor // should they get tickled. if (Log.isLoggable(TAG, Log.VERBOSE)) { Log.v(TAG, "Ignoring sync request for non-syncable feed."); } return; } context.setStatusText("Syncing " + name); // call the superclass implementation to sync the current // calendar from the server. getServerDiffsImpl( context, tempProvider, getFeedEntryClass(), feedUrl, syncInfo, maxResults, syncData, syncResult); if (mSyncCanceled || syncResult.hasError()) { return; } // update the timezone for this calendar if it changed if (!TextUtils.equals(syncInfo.calendarTimezone, origCalendarTimezone)) { map.clear(); map.put(Calendars.TIMEZONE, syncInfo.calendarTimezone); mContentResolver.update( ContentUris.withAppendedId(Calendars.CONTENT_URI, syncInfo.calendarId), map, null, null); } } finally { cursor.close(); } }