Reputation: 119
I've been looking through the various posts on how to delete just one instance of a recurring event from my Android 2.3 Phone's calendar, but I haven't been able to find the perfect answer. So far, the best I've come across is :
Uri eventsUri = Uri.parse("content://com.android.calendar/events");
Uri deleteEventUri = Uri.withAppendedPath(eventsUri, String.valueOf(id2));
DeleteEventActivity.context.getContentResolver().delete(deleteEventUri, null, null);
Where id2 is the id of the event I want to delete. The problem I have is that I only want to delete one instance of a recurring event, but this code deletes all occurrences. Is there a way to delete only one instance? Thanks.
Upvotes: 5
Views: 3349
Reputation: 599
What about updating particular instances of a recurring event? Say I have a daily recurring event Mon-Fri, but I want to update a few fields (begin, end/duration, title, description, all-day, availability, status) for the instance on Wed only. How can this be done?
I tried the approach that @alex-f mentioned:
ContentValues
and put BEGIN as ORIGINAL_INSTANCE_TIME.ContentValues
insert(uri, values)
But this screwed up my event data:
Upvotes: 0
Reputation: 119
If anyone else is still struggling with this, I've finally cracked it!
It turns out that you do not delete or amend any records, what you actually do is insert a new event called an exception. It took me a few months to find this information anywhere, and even having found it, another few months to work out exactly what needed to be put into the exception to make it work, so here is how I did it.
Firstly, query the actual instance of the event that you want to cancel one occurrence of. You need to query the table CalendarContract.Instances to get the values of CalendarContract.Instances.TITLE, CalendarContract.Instances.BEGIN and CalendarContract.Instances.EVENT_ID. The way I do this in my code doesn't really fit in with the context of this answer, so hopefully you will be able to work out how to do that yourself. Store these values as:
final String title = eventCursor.getString(0);
final long beginl=eventCursor.getLong(1);
final int id = eventCursor.getInt(2);
Then we need to set up a new event as follows :
final Context context = getApplicationContext();
final ContentResolver contentResolver = context.getContentResolver();
final Uri.Builder builder = Uri.parse(
"content://com.android.calendar/events").buildUpon();
final Cursor eventCursor = contentResolver.query(builder.build(),
new String[]
{Events.CALENDAR_TIME_ZONE,Events.ALL_DAY,Events.CALENDAR_ID,Events._SYNC_ID, Events.OWNER_ACCOUNT },
"_id=" + id, null, null);
while (eventCursor.moveToNext()) {
final String timezone=eventCursor.getString(0);
final String allday=eventCursor.getString(1);
final long calID=eventCursor.getLong(2);
final String mSyncId=eventCursor.getString(3);
final String account=eventCursor.getString(4);
ContentValues values = new ContentValues();
values.put(Events.TITLE, title);
values.put(Events.EVENT_TIMEZONE, timezone);
values.put(Events.ORIGINAL_SYNC_ID, mSyncId);//not 100% sure about this,may also need a date?
values.put(Events.HAS_ALARM, "0");
values.put(Events.HAS_ATTENDEE_DATA,"0");
values.put(Events.ALL_DAY, allday);
values.put(Events.DTSTART, beginl+3600000);
values.put(Events.ORIGINAL_INSTANCE_TIME, beginl+3600000);
values.put(Events.STATUS, Events.STATUS_CANCELED);
Uri uri = Uri.withAppendedPath(Events.CONTENT_EXCEPTION_URI,
String.valueOf(id));
uri = asSyncAdapter(uri, account, CTS_TEST_TYPE);
Uri resultUri = context.getContentResolver().insert(uri, values);
try {
int eventID = Integer.parseInt(resultUri.getLastPathSegment());
int debug=eventID;
} catch (Exception e) {
int debug=0;
}
}
static Uri asSyncAdapter(Uri uri, String account, String accountType) {
return uri.buildUpon()
.appendQueryParameter
(android.provider.CalendarContract.CALLER_IS_SYNCADAPTER,"true")
.appendQueryParameter(Calendars.ACCOUNT_NAME, account)
.appendQueryParameter(Calendars.ACCOUNT_TYPE, accountType).build();
}
Hope this works, I've tried to cut out the parts of my code which are not relevant. You'll note I am having to add 3600000 to the beginl value (1 hour in milliseconds). I assume that is because we are in BST at the moment and this code will not work once the clocks change, but I'll worry about that at the time!
Finally, I used an app called Content Provider Helper to help me find this out. You can use it query your content provider tables. I would try setting up an exception using my code, then use my phones calendar app to delete the instance, and compare the two records.
Upvotes: 6
Reputation: 6181
Instances.query()
)ContentValues
. Put your instance's BEGIN value as ...Events.ORIGINAL_INSTANCE_TIME. Put STATUS_CANCELED as ...Events.STATUSUpvotes: 6
Reputation: 829
You will have to update the EXDATE column of the original event.
Upvotes: 1