Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Cannot read recurring events from android calendar programmatically

Tags:

android

I have followed the tutorial in this link - http://jimblackler.net/blog/?p=151&cpage=2#comment-52767 to access the internal android calendar database (even though it is not officially supported by the SDK). It works for all entries except for recurring events. The cursor does not return any recurring events at all. Can someone help me here. Following is my cursor declaration -

    String[] projection = new String[] { "title", "description", "dtstart", "eventLocation" };
    String selection = "(calendar_id=" + calID + ")AND " + (now - window)
            + "<dtstart AND dtstart< " + (now + (window));
    String sortorder = "dtstart ASC";

    Cursor managedCursor = getCalendarManagedCursor(projection, selection,
            "events", sortorder);

    private Cursor getCalendarManagedCursor(String[] projection,
        String selection, String path, String sort) {
    Uri calendars = Uri.parse("content://calendar/" + path);
    Cursor managedCursor = null;
    try {
        managedCursor = getContentResolver().query(calendars, projection,
                selection, null, sort);
    } catch (IllegalArgumentException e) {
        Log.w(DEBUG_TAG,
                "Failed to get provider at [" + calendars.toString() + "]");
    }

    if (managedCursor == null) {
        // try again
        calendars = Uri.parse("content://com.android.calendar/" + path);
        try {
            managedCursor = getContentResolver().query(calendars,
                    projection, selection, null, sort);
        } catch (IllegalArgumentException e) {
            Log.w(DEBUG_TAG,
                    "Failed to get provider at [" + calendars.toString()
                            + "]");
        }`
like image 249
AnilV Avatar asked Aug 20 '11 06:08

AnilV


2 Answers

Use the Instances table if you need to locate recurring events.

The URIs for querying it are:

  • instances/when/*/* - All instances between two times (milliseconds)
  • instances/whenbyday/*/* - All instances between two times (days)
  • instances/groupbyday/*/* - Same as whenbyday, but grouped by the start day

The list of columns in that table are:

  • _id - The ID of this instance
  • event_id - The event it was created from
  • begin - Begin time (milliseconds)
  • end - End time (milliseconds)
  • startDay - Start day of instance
  • endDay - End day of instance
  • startMinute - Minutes since midnight (0..1440)
  • endMinute - Minutes since midnight

You can also use the columns from the Events and Calendar tables.

You can see an example on the same page that you linked: http://jimblackler.net/blog/?p=151

Example:

String[] projection = new String[] {
        "title", "description", "begin", "eventLocation"
};
String selection = "calendar_id = " + calID;
String path = "instances/when/" + (now - window) + "/" + (now + window);
String sortOrder = "begin DESC";
Cursor managedCursor = getCalendarManagedCursor(
        projection, selection, path, sortorder);

Edit: It seems Google got around to document the Calendar Provider. Browse to Calendar Providier | Google Developers for more information.

like image 178
Markus Jarderot Avatar answered Sep 20 '22 18:09

Markus Jarderot


I finally made this work in the following way. Remember DTSTART, DTEND, _ID don't work for Instances table even if you can access them. Use BEGIN, END and Event_ID instead. Please refer to these 2 links: How to get calendar events with title including recurring events and Android Calendar Recurring Events Have Wrong End Date/Time

        long now = System.currentTimeMillis();

        Uri.Builder eventsUriBuilder = CalendarContract.Instances.CONTENT_URI.buildUpon();
        ContentUris.appendId(eventsUriBuilder, Long.MIN_VALUE);
        ContentUris.appendId(eventsUriBuilder, Long.MAX_VALUE);

        Uri eventsUri = eventsUriBuilder.build();
        Cursor cursor = context.getContentResolver().query(
            eventsUri,
            new String[] {CalendarContract.Instances.CALENDAR_ID, CalendarContract.Instances.TITLE,
                    CalendarContract.Instances.DESCRIPTION, CalendarContract.Instances.BEGIN,
                    CalendarContract.Instances.END, CalendarContract.Instances.EVENT_LOCATION,
                    CalendarContract.Instances.EVENT_ID},
            CalendarContract.Instances.BEGIN + " >= " + now + " and " + CalendarContract.Instances.BEGIN 
                    + " <= " + (now + 2592000000L) + " and " + CalendarContract.Instances.VISIBLE + " = 1",
            null,
            CalendarContract.Instances.BEGIN + " ASC");
like image 30
Sean Avatar answered Sep 22 '22 18:09

Sean