@Override protected void removeDataRows(Resource resource) { Event event = (Event) resource; pendingOperations.add( ContentProviderOperation.newDelete(syncAdapterURI(Attendees.CONTENT_URI)) .withSelection( Attendees.EVENT_ID + "=?", new String[] {String.valueOf(event.getLocalID())}) .build()); pendingOperations.add( ContentProviderOperation.newDelete(syncAdapterURI(Reminders.CONTENT_URI)) .withSelection( Reminders.EVENT_ID + "=?", new String[] {String.valueOf(event.getLocalID())}) .build()); }
void populateReminders(Event e) throws RemoteException { // reminders Uri remindersUri = Reminders.CONTENT_URI .buildUpon() .appendQueryParameter(ContactsContract.CALLER_IS_SYNCADAPTER, "true") .build(); @Cleanup Cursor c = providerClient.query( remindersUri, new String[] { /* 0 */ Reminders.MINUTES, Reminders.METHOD }, Reminders.EVENT_ID + "=?", new String[] {String.valueOf(e.getLocalID())}, null); while (c != null && c.moveToNext()) { VAlarm alarm = new VAlarm(new Dur(0, 0, -c.getInt(0), 0)); PropertyList props = alarm.getProperties(); switch (c.getInt(1)) { /*case Reminders.METHOD_EMAIL: props.add(Action.EMAIL); break;*/ default: props.add(Action.DISPLAY); props.add(new Description(e.getSummary())); } e.addAlarm(alarm); } }
void populateAttendees(Event e) throws RemoteException { Uri attendeesUri = Attendees.CONTENT_URI .buildUpon() .appendQueryParameter(ContactsContract.CALLER_IS_SYNCADAPTER, "true") .build(); @Cleanup Cursor c = providerClient.query( attendeesUri, new String[] { /* 0 */ Attendees.ATTENDEE_EMAIL, Attendees.ATTENDEE_NAME, Attendees.ATTENDEE_TYPE, /* 3 */ Attendees.ATTENDEE_RELATIONSHIP, Attendees.STATUS }, Attendees.EVENT_ID + "=?", new String[] {String.valueOf(e.getLocalID())}, null); while (c != null && c.moveToNext()) { try { Attendee attendee = new Attendee(new URI("mailto", c.getString(0), null)); ParameterList params = attendee.getParameters(); String cn = c.getString(1); if (cn != null) params.add(new Cn(cn)); // type int type = c.getInt(2); params.add((type == Attendees.TYPE_RESOURCE) ? CuType.RESOURCE : CuType.INDIVIDUAL); // role int relationship = c.getInt(3); switch (relationship) { case Attendees.RELATIONSHIP_ORGANIZER: params.add(Role.CHAIR); break; case Attendees.RELATIONSHIP_ATTENDEE: case Attendees.RELATIONSHIP_PERFORMER: case Attendees.RELATIONSHIP_SPEAKER: params.add( (type == Attendees.TYPE_REQUIRED) ? Role.REQ_PARTICIPANT : Role.OPT_PARTICIPANT); break; case Attendees.RELATIONSHIP_NONE: params.add(Role.NON_PARTICIPANT); } // status switch (c.getInt(4)) { case Attendees.ATTENDEE_STATUS_INVITED: params.add(PartStat.NEEDS_ACTION); break; case Attendees.ATTENDEE_STATUS_ACCEPTED: params.add(PartStat.ACCEPTED); break; case Attendees.ATTENDEE_STATUS_DECLINED: params.add(PartStat.DECLINED); break; case Attendees.ATTENDEE_STATUS_TENTATIVE: params.add(PartStat.TENTATIVE); break; } e.addAttendee(attendee); } catch (URISyntaxException ex) { Log.e(TAG, "Couldn't parse attendee information, ignoring", ex); } } }
@Override public void populate(Resource resource) throws LocalStorageException { Event e = (Event) resource; try { @Cleanup Cursor cursor = providerClient.query( ContentUris.withAppendedId(entriesURI(), e.getLocalID()), new String[] { /* 0 */ Events.TITLE, Events.EVENT_LOCATION, Events.DESCRIPTION, /* 3 */ Events.DTSTART, Events.DTEND, Events.EVENT_TIMEZONE, Events.EVENT_END_TIMEZONE, Events.ALL_DAY, /* 8 */ Events.STATUS, Events.ACCESS_LEVEL, /* 10 */ Events.RRULE, Events.RDATE, Events.EXRULE, Events.EXDATE, /* 14 */ Events.HAS_ATTENDEE_DATA, Events.ORGANIZER, Events.SELF_ATTENDEE_STATUS, /* 17 */ entryColumnUID(), Events.DURATION, Events.AVAILABILITY }, null, null, null); if (cursor != null && cursor.moveToNext()) { e.setUid(cursor.getString(17)); e.setSummary(cursor.getString(0)); e.setLocation(cursor.getString(1)); e.setDescription(cursor.getString(2)); boolean allDay = cursor.getInt(7) != 0; long tsStart = cursor.getLong(3), tsEnd = cursor.getLong(4); String duration = cursor.getString(18); String tzId = null; if (allDay) { e.setDtStart(tsStart, null); // provide only DTEND and not DURATION for all-day events if (tsEnd == 0) { Dur dur = new Dur(duration); java.util.Date dEnd = dur.getTime(new java.util.Date(tsStart)); tsEnd = dEnd.getTime(); } e.setDtEnd(tsEnd, null); } else { // use the start time zone for the end time, too // because apps like Samsung Planner allow the user to change "the" time zone but change // the start time zone only tzId = cursor.getString(5); e.setDtStart(tsStart, tzId); if (tsEnd != 0) e.setDtEnd(tsEnd, tzId); else if (!StringUtils.isEmpty(duration)) e.setDuration(new Duration(new Dur(duration))); } // recurrence try { String strRRule = cursor.getString(10); if (!StringUtils.isEmpty(strRRule)) e.setRrule(new RRule(strRRule)); String strRDate = cursor.getString(11); if (!StringUtils.isEmpty(strRDate)) { RDate rDate = new RDate(); rDate.setValue(strRDate); e.setRdate(rDate); } String strExRule = cursor.getString(12); if (!StringUtils.isEmpty(strExRule)) { ExRule exRule = new ExRule(); exRule.setValue(strExRule); e.setExrule(exRule); } String strExDate = cursor.getString(13); if (!StringUtils.isEmpty(strExDate)) { // ignored, see https://code.google.com/p/android/issues/detail?id=21426 ExDate exDate = new ExDate(); exDate.setValue(strExDate); e.setExdate(exDate); } } catch (ParseException ex) { Log.w(TAG, "Couldn't parse recurrence rules, ignoring", ex); } catch (IllegalArgumentException ex) { Log.w(TAG, "Invalid recurrence rules, ignoring", ex); } // status switch (cursor.getInt(8)) { case Events.STATUS_CONFIRMED: e.setStatus(Status.VEVENT_CONFIRMED); break; case Events.STATUS_TENTATIVE: e.setStatus(Status.VEVENT_TENTATIVE); break; case Events.STATUS_CANCELED: e.setStatus(Status.VEVENT_CANCELLED); } // availability e.setOpaque(cursor.getInt(19) != Events.AVAILABILITY_FREE); // attendees if (cursor.getInt(14) != 0) { // has attendees try { e.setOrganizer(new Organizer(new URI("mailto", cursor.getString(15), null))); } catch (URISyntaxException ex) { Log.e(TAG, "Error when creating ORGANIZER URI, ignoring", ex); } populateAttendees(e); } // classification switch (cursor.getInt(9)) { case Events.ACCESS_CONFIDENTIAL: case Events.ACCESS_PRIVATE: e.setForPublic(false); break; case Events.ACCESS_PUBLIC: e.setForPublic(true); } populateReminders(e); } else throw new RecordNotFoundException(); } catch (RemoteException ex) { throw new LocalStorageException(ex); } }