CalendarContract Events : bad id inserted, Calendar corrupted in Android - android

I made a mistake on testing insert Events using CalendarContract.
I set my own _ID in a Events insert.
values.put(Events._ID, "156498713465");
Now, all my new events are created with a bad id (for exemple -535191590).
When I click to the event in the Google Calendar Application, it crash.
I have the same error as this thread :
Calendar corrupted in Android
I tried to delete all bad events :
activity.getContentResolver().delete(Events.CONTENT_URI, Events._ID + " > ? ",
new String[] { "10000" });
But when a new events are inserted, a bad id is generated.
My question is :
Where can I reset the Events Id sequence ?
Thanks,
Regards

Don't set the id; the following will do what you want:
ContentResolver cr = getContentResolver();
ContentValues values = new ContentValues();
values.put (Events.CALENDAR_ID, Long.toString(newCalendarId));
values.put (Events.DTSTART, dtStart);
values.put (Events.DTEND, dtEnd);
values.put (Events.EVENT_TIMEZONE, TimeZone.getDefault().getID());
values.put (Events.TITLE, title);
Uri uri = cr.insert (Events.CONTENT_URI, values);
// The returned uri will contain the eventId assigned by Events.

Related

Adding an event in google calendar from my android application

Hello I am a beginner in android.
I want to add an event in google calendar from my android application.
Please help me with complete source code. I have looked, but haven't found a solution with complete source code.
You can use ContentValues like local db,
String eventUriString = "content://com.android.calendar/events";
ContentResolver cr = this.getContentResolver();
ContentValues values = new ContentValues();
values.put(CalendarContract.Reminders.CALENDAR_ID, 1);
values.put(CalendarContract.Reminders.TITLE, "YOUR_TITLE");
values.put(CalendarContract.Reminders.DTSTART, TIMES IN MILLISECOND);
values.put(CalendarContract.Reminders.DESCRIPTION,YOUR_TEXT);
values.put(CalendarContract.Reminders.DTEND, TIMES IN MILLISECOND);
values.put(CalendarContract.Reminders.HAS_ALARM, true);
values.put(CalendarContract.Reminders.EVENT_TIMEZONE, TimeZone.getDefault().getID());
Uri uriEvents = cr.insert(CalendarContract.Events.CONTENT_URI, values);
eventID = Long.parseLong(uriEvents.getLastPathSegment());

Update Android calendar events

I'm trying to update calendar events programmatically but I have some issues.
I'm using updating code from Google Android Documentation: https://developer.android.com/guide/topics/providers/calendar-provider.html#update-event
So here's my code :
ContentValues values = new ContentValues();
Uri updateUri = null;
// New end for event
values.put(CalendarContract.Events.DTEND, endMillis);
updateUri = ContentUris.withAppendedId(CalendarContract.Events.CONTENT_URI, eventID);
int rows = c.getContentResolver().update(updateUri, values, null, null);
Log.i("DEBUG_TAG", "Rows updated: " + rows);
But rows variable always returns 0 except when I go into apps settings, remove calendar storage, add a new calendar and a new event and then when I try to update it, it works only once. If I try to add another event and update it afterward, rows return 0 again.
Any idea?
Thanks
Please note that my app is min API level 17 (on which it doesn't work) but I tried on API level 25 and it works, so do you have any idea how to add support to my code for previous Android versions? I've also found that after some tests, it works from API level 21. Under, it doesn't.
EDIT :
I've found a solution, check my answer below.
Here's the solution that worked for me :
The eventID that I used was the result of the query with column CalendarContract.Events._ID but I had to used the ID provided by CalendarContract.Instances.EVENT_ID.
Indeed if I create a new event (the first one) it has _id = 1 and event_id = 1, and if I delete it from Android Calendar App and I create a new one with my app, it has also _id = 1 but event_id = 2.
So the update query failed if I use _id instead of event_id with withAppendedID().
Here's the code that worked for me. startMillis and endMillis are respectively your meeting start time and end time in milliseconds.
Uri.Builder eventsUriBuilder = CalendarContract.Instances.CONTENT_URI
.buildUpon();
ContentUris.appendId(eventsUriBuilder, startMillis);
ContentUris.appendId(eventsUriBuilder, endMillis);
Uri eventsUri = eventsUriBuilder.build();
String[] column = {CalendarContract.Instances.EVENT_ID, CalendarContract.Events.DTSTART, CalendarContract.Events.DTEND, CalendarContract.Events.TITLE};
Cursor cursor;
cursor = c.getContentResolver().query(eventsUri, column, CalendarContract.Events.CALENDAR_ID+"="+Constant.ID_CALENDAR, null, CalendarContract.Instances.DTSTART + " ASC");
if (cursor.moveToFirst()) {
do {
uri = ContentUris.withAppendedId(CalendarContract.Events.CONTENT_URI,cursor.getLong(0));
} while (cursor.moveToNext());
}
cursor.close();
c.getContentResolver().delete(uri, null, null);

Android: How to correctly use "CalendarAlerts" to display unique message in Alarms

I have created some events and stored the data in sqlite table but not the system calendar. However, i would like to have an alert/reminder for these events, which is similar to other events that stored in the system.
With reference to the code below, the details of the event are put in the "CalendarAlerts" table and in the broadcast receiver, the alertCursor is used to find the event data with start time close to the current time.
The code worked well if the event is stored in the system with a "long" eventID. But when i try to put data of my sqlite event in "CalendarAlerts" with a "string" eventID. It shows that the data is inserted into the table successfully but i would not query back the result in the "Alert Receiver" class.
Searched google for a while and it seems that not many people are talking on the topic of "CalendarAlerts". Great if anyone would share the experience on this issue.
Setting the AlarmManager
Uri alertUri = CalendarAlerts.CONTENT_URI;
long alarmMillis = (long) mStart - (long)(min*60*1000);
ContentValues alertValues =AlertUtils.makeContentValues(eventIdentifier,mStart, mEnd,alarmMillis, 0);
context.getContentResolver().insert(alertUri, alertValues);
public static ContentValues makeContentValues(String eventId, long begin, long end,
long alarmTime, int minutes) {
ContentValues values = new ContentValues();
values.put(CalendarAlerts.EVENT_ID, eventId);
values.put(CalendarAlerts.BEGIN, begin);
values.put(CalendarAlerts.END, end);
values.put(CalendarAlerts.ALARM_TIME, alarmTime);
long currentTime = System.currentTimeMillis();
values.put(CalendarAlerts.CREATION_TIME, currentTime);
values.put(CalendarAlerts.RECEIVED_TIME, 0);
values.put(CalendarAlerts.NOTIFY_TIME, 0);
values.put(CalendarAlerts.STATE, CalendarAlerts.STATE_SCHEDULED);
values.put(CalendarAlerts.MINUTES, minutes);
return values;
}
AlertReceiver.java
Cursor alertCursor = cr.query(CalendarAlerts.CONTENT_URI, ALERT_PROJECTION,
(ACTIVE_ALERTS_SELECTION + currentMillis), ACTIVE_ALERTS_SELECTION_ARGS,
ACTIVE_ALERTS_SORT);
You can use this code which works for me :
ContentResolver cr = getActivity().getContentResolver();
ContentValues values = new ContentValues();
values.put(CalendarContract.Events.DTSTART, startMillis);
values.put(CalendarContract.Events.TITLE, title);
values.put(CalendarContract.Events.DESCRIPTION, "description");
TimeZone timeZone = TimeZone.getDefault();
values.put(CalendarContract.Events.EVENT_TIMEZONE, timeZone.getID());
// default calendar
values.put(CalendarContract.Events.CALENDAR_ID, 1);
//for one hour
values.put(CalendarContract.Events.DURATION, "+P1H");
values.put(CalendarContract.Events.HAS_ALARM, 1);
// cr.delete(CalendarContract.Events.CONTENT_URI, null,null);
// insert event to calendar
Uri uri = cr.insert(CalendarContract.Events.CONTENT_URI, values);

Update calendar instances.end via events.dtend

When I update the CalendarContract.Events DTEND column, why doesn't the change show up in the CalendarContract.Instances END column?
My app allows the user to view and change calendar events using the CalendarContract.Events APIs. The code performs an update to the Events table and then reads it back (later) using the Instances table. Changes to TITLE, for example, work fine (that is, I update Events and can read back the change in Instances). Changes to Events.DTEND do show up in Instances.DTEND, but how can I get that update to also show up in Instances.END?
This is important since, evidently, the Android calendar app (and my app, too) uses Instances.BEGIN and Instances.END to determine what to display in the calendar.
Here is my update code:
ContentResolver cr = getContentResolver();
ContentValues values = new ContentValues();
values.put (Events.CALENDAR_ID, calendarId);
values.put (Events.TITLE, title);
values.put (Events.DTEND, eventEnd.getTimeInMillis());
String where = "_id =" + eventId +
" and " + CALENDAR_ID + "=" + calendarId;
int count = cr.update (Events.CONTENT_URI, values, where, null);
if (count != 1)
throw new IllegalStateException ("more than one row updated");
Thanks.
The solution turns out to be adding the start date:
ContentResolver cr = getContentResolver();
ContentValues values = new ContentValues();
values.put (Events.CALENDAR_ID, calendarId);
values.put (Events.TITLE, title);
values.put (Events.DTSTART, eventStart.getTimeInMillis());
values.put (Events.DTEND, eventEnd.getTimeInMillis());
String where = "_id =" + eventId +
" and " + CALENDAR_ID + "=" + calendarId;
int count = cr.update (Events.CONTENT_URI, values, where, null);
if (count != 1)
throw new IllegalStateException ("more than one row updated");
A word of caution: this case only shows how to update nonrecurring events. Nonrecurring events have a null RRULE.
I suspect what the provider code is doing is using only the values you provide instead of refetching the start date itself (obviously if the user changes the start date you would have to provide it anyway). This makes sense from the perspective of reducing db accesses. Too bad Google didn't document any of this.

How to delete a calendar entry?

I'm trying to implement my first android Program. It should write calendar entries (I know, not the best task to begin programming Andorid).
I've tried:
Uri CALENDAR_URI = Uri.parse("content://calendar/events");
ContentResolver cr = getContentResolver();
cr.delete(CALENDAR_URI, null, null); // Delete all
cr.delete(CALENDAR_URI, "calendar_id=1", null); // Delete all in default calendar
cr.delete(CALENDAR_URI, "_id=1", null); // Delete specific entry
Nothing worked. I allays get a "cannot delete that URL".
Inserting an Calendar Entry was simple:
ContentValues values = new ContentValues();
values.put("calendar_id", 1);
values.put("title", this.title);
values.put("allDay", this.allDay);
values.put("dtstart", this.dtstart.toMillis(false));
values.put("dtend", this.dtend.toMillis(false));
values.put("description", this.description);
values.put("eventLocation", this.eventLocation);
values.put("visibility", this.visibility);
values.put("hasAlarm", this.hasAlarm);
cr.insert(CALENDAR_URI, values);
According to my insert method accessing the calendar worked.
Thanks, Arthur!
OK, one thing I didn't try:
Uri CALENDAR_URI = Uri.parse("content://calendar/events");
int id = 1; // calendar entry ID
Uri uri = ContentUris.withAppendedId(CALENDAR_URI, id);
cr.delete(uri, null, null);
This is what I was missing:
Uri uri = ContentUris.withAppendedId(CALENDAR_URI, id);
should lead to content://calendar/events/1
Now my Calendar is empty :-)
The right way to delete things out of a user's calendar is to use the appropriate GData APIs and delete it from their Google Calendar. Manipulating the Calendar application's content provider -- as you are trying to do -- is not part of the public API.

Categories

Resources