How to read and edit Android calendar events using the new Android 4.0 Ice Cream Sandwich API?

We are trying to show user the Ice cream Sandwich calendar view, when they want to add a new event. We can only test this in emulator.

The other problem is that we can't find any examples how to use CalendarProvider. This is the right class when it comes to dealing with Sandwich calendar?

Would this be easier to do with Google Gdata API?

[EDIT] So what we got working was adding an event to calendar but it was not through the API, we open the calendar in the correct view. But now the problem is that it does not work in the emulator because we haven't been able to get the calendar synced.

So the question is: How to read and possibly edit Android calendar events using the new Android 4.0 Ice Cream Sandwich API?


Solution 1:

Here's code that will let you add an event directly:

import android.content.ContentResolver;
import android.content.ContentValues;
import android.net.Uri;
import android.provider.CalendarContract;

import java.util.Calendar;

// Construct event details
long startMillis = 0;
long endMillis = 0;
Calendar beginTime = Calendar.getInstance();
beginTime.set(2012, 9, 14, 7, 30);
startMillis = beginTime.getTimeInMillis();
Calendar endTime = Calendar.getInstance();
endTime.set(2012, 9, 14, 8, 45);
endMillis = endTime.getTimeInMillis();

// Insert Event
ContentResolver cr = getContentResolver();
ContentValues values = new ContentValues();
TimeZone timeZone = TimeZone.getDefault();
values.put(CalendarContract.Events.DTSTART, startMillis);
values.put(CalendarContract.Events.DTEND, endMillis);
values.put(CalendarContract.Events.EVENT_TIMEZONE, timeZone.getID());
values.put(CalendarContract.Events.TITLE, "Walk The Dog");
values.put(CalendarContract.Events.DESCRIPTION, "My dog is bored, so we're going on a really long walk!");
values.put(CalendarContract.Events.CALENDAR_ID, 3);
Uri uri = cr.insert(CalendarContract.Events.CONTENT_URI, values);

// Retrieve ID for new event
String eventID = uri.getLastPathSegment();

You'll need the CALENDAR_ID, so here's how to query the list of calendars:

Uri uri = CalendarContract.Calendars.CONTENT_URI;
String[] projection = new String[] {
       CalendarContract.Calendars._ID,
       CalendarContract.Calendars.ACCOUNT_NAME,
       CalendarContract.Calendars.CALENDAR_DISPLAY_NAME,
       CalendarContract.Calendars.NAME,
       CalendarContract.Calendars.CALENDAR_COLOR
};

Cursor calendarCursor = managedQuery(uri, projection, null, null, null);

You'll need to request the android.permission.READ_CALENDAR permission for all of this to work.

If you want to avoid having to request permissions, you can also ask the Calendar app to create a new event on your behalf by using an Intent:

Intent intent = new Intent(Intent.ACTION_INSERT)
         .setType("vnd.android.cursor.item/event")
         .putExtra(CalendarContract.EXTRA_EVENT_BEGIN_TIME, beginTime.getTimeInMillis())
         .putExtra(CalendarContract.EXTRA_EVENT_END_TIME, endTime.getTimeInMillis())
         .putExtra(CalendarContract.EXTRA_EVENT_ALL_DAY , false) // just included for completeness
         .putExtra(Events.TITLE, "My Awesome Event")
         .putExtra(Events.DESCRIPTION, "Heading out with friends to do something awesome.")
         .putExtra(Events.EVENT_LOCATION, "Earth")
         .putExtra(Events.RRULE, "FREQ=DAILY;COUNT=10") 
         .putExtra(Events.AVAILABILITY, Events.AVAILABILITY_BUSY)
         .putExtra(Events.ACCESS_LEVEL, Events.ACCESS_PRIVATE)
         .putExtra(Intent.EXTRA_EMAIL, "[email protected]");
startActivity(intent);

Solution 2:

You can use the following code to setup the timezone and it works for me

TimeZone timeZone = TimeZone.getDefault();
values.put(CalendarContract.Events.EVENT_TIMEZONE, timeZone.getID());

Solution 3:

Make sure,you are not using 'visibilty' for ICS and JellyBean devices (apiLevel>=14)

Try this -

ContentValues values= new ContentValues();
int apiLevel = android.os.Build.VERSION.SDK_INT;
            if(apiLevel<14)
            values.put("visibility", 0);

Use visibility only if device version is less than 14(ICS)