One of the popular apps on Android device is the Calendar application. As one of the android app development philosophy is to make use of functionalities of other apps, it is expected by many developers that we can access the calendar data easily. However, the truth is NO!

Android doesn’t provide an official API for read/write Calendar data, probably because Android is going to change the calendar data format in future release.

The good news is there’re workarounds, more than one. This tutorial will list out those methods and provide an example at the end of the tutorial.

1. Google Calendar APIs

Google doesn’t provide Calendar API specifically for Android, but it does provide an Calendar API for more general use. The API supports .NET, Java and Python, so it is expected that it can be used in Android.

However, this method requires the app to establish a network connection through Internet (probably requires some kind of authentication), and then access the calendar data. As android already has Calendar app built in, it sounds dumb that we’ll need to connect to Internet, create a connection and access the data.

This approach is not explored in detail here. Interested readers could refer reference 2 for more details.

2. Android Calendar Private APIs

Android is open source, so it’s not difficult to find out that android actually has undocumented APIs for calendar (it’s just not public APIs).

This part will cover how to get list of calendars, how to read event, and how to add event.

2.0 Permission Declaration

In order to read calendar data, one needs to declare the “READ_CALENDAR” permission in AndroidManifest.xml file.

<uses-permission android:name="android.permission.READ_CALENDAR"></uses-permission>

 

For write to Calendar, there’s a another “WRITE_CALENDAR” permission.

<uses-permission android:name="android.permission.WRITE_CALENDAR"></uses-permission>

 

You can refer to the complete code at the end of the tutorial for exact position of the declaration.

2.1 List Calendars

One may have multiple calendars created in Calendar application. For me, I have the default calendar, a Singapore Holiday Calendar, and a third calendar from my other Gmail account.

The code to get a list of all calendars are as below,

class MyCalendar {
    public String name;
    public String id;
    public MyCalendar(String _name, String _id) {
        name = _name;
        id = _id;
    }
    @Override
    public String toString() {
        return name;
    }
}
private MyCalendar m_calendars[];
private void getCalendars() {
    String[] l_projection = new String[]{"_id", "displayName"};
    Uri l_calendars;
    if (Build.VERSION.SDK_INT >= 8 ) {
        l_calendars = Uri.parse("content://com.android.calendar/calendars");
    } else {
        l_calendars = Uri.parse("content://calendar/calendars");
    }
    Cursor l_managedCursor = this.managedQuery(l_calendars, l_projection, null, null, null);    //all calendars
    //Cursor l_managedCursor = this.managedQuery(l_calendars, l_projection, "selected=1", null, null);   //active calendars
    if (l_managedCursor.moveToFirst()) {
        m_calendars = new MyCalendar[l_managedCursor.getCount()];
        String l_calName;
        String l_calId;
        int l_cnt = 0;
        int l_nameCol = l_managedCursor.getColumnIndex(l_projection[1]);
        int l_idCol = l_managedCursor.getColumnIndex(l_projection[0]);
        do {
            l_calName = l_managedCursor.getString(l_nameCol);
            l_calId = l_managedCursor.getString(l_idCol);
            m_calendars[l_cnt] = new MyCalendar(l_calName, l_calId);
            ++l_cnt;
        } while (l_managedCursor.moveToNext());
    }
}

The code essentially queries the android calendar content provider and goes through the calendar list returned. The name and calendar id are stored in m_calendars[].

For android version less than 8, the uri for query calendars is content://calendar/*, while content://com.android.calendar/* is used for android version 8 and above.

2.2 Read Events

To read a list of Calendar events, one can create another query as illustrated below,

private void getLastThreeEvents() {
    Uri l_eventUri;
    if (Build.VERSION.SDK_INT >= 8 ) {
        l_eventUri = Uri.parse("content://com.android.calendar/events");
    } else {
        l_eventUri = Uri.parse("content://calendar/events");
    }
    String[] l_projection = new String[]{"title", "dtstart", "dtend"};
    Cursor l_managedCursor = this.managedQuery(l_eventUri, l_projection, "calendar_id=" + m_selectedCalendarId, null, "dtstart DESC, dtend DESC");
    //Cursor l_managedCursor = this.managedQuery(l_eventUri, l_projection, null, null, null);
    if (l_managedCursor.moveToFirst()) {
        int l_cnt = 0;
        String l_title;
        String l_begin;
        String l_end;
        StringBuilder l_displayText = new StringBuilder();
        int l_colTitle = l_managedCursor.getColumnIndex(l_projection[0]);
        int l_colBegin = l_managedCursor.getColumnIndex(l_projection[1]);
        int l_colEnd = l_managedCursor.getColumnIndex(l_projection[1]);
        do {
            l_title = l_managedCursor.getString(l_colTitle);
            l_begin = getDateTimeStr(l_managedCursor.getString(l_colBegin));
            l_end = getDateTimeStr(l_managedCursor.getString(l_colEnd));
            l_displayText.append(l_title + "\n" + l_begin + "\n" + l_end + "\n----------------\n");
            ++l_cnt;
        } while (l_managedCursor.moveToNext() && l_cnt < 3);
        m_text_event.setText(l_displayText.toString());
    }
}

The method above get the last three events from the selected calendar. Note that m-selectedCalendarId variable and getDateTimeStr() method are defined by us. You can refer to code at the end of the tutorial for a complete picture.

2.3 Create an Event

Similarly, one can insert a new event into Calendar database.

/*add an event to calendar*/
private void addEvent() {
    ContentValues l_event = new ContentValues();
    l_event.put("calendar_id", m_selectedCalendarId);
    l_event.put("title", "roman10 calendar tutorial test");
    l_event.put("description", "This is a simple test for calendar api");
    l_event.put("eventLocation", "@home");
    l_event.put("dtstart", System.currentTimeMillis());
    l_event.put("dtend", System.currentTimeMillis() + 1800*1000);
    l_event.put("allDay", 0);
    //status: 0~ tentative; 1~ confirmed; 2~ canceled
    l_event.put("eventStatus", 1);
    //0~ default; 1~ confidential; 2~ private; 3~ public
    l_event.put("visibility", 0);
    //0~ opaque, no timing conflict is allowed; 1~ transparency, allow overlap of scheduling
    l_event.put("transparency", 0);
    //0~ false; 1~ true
    l_event.put("hasAlarm", 1);
    Uri l_eventUri;
    if (Build.VERSION.SDK_INT >= 8 ) {
        l_eventUri = Uri.parse("content://com.android.calendar/events");
    } else {
        l_eventUri = Uri.parse("content://calendar/events");
    }
    Uri l_uri = this.getContentResolver().insert(l_eventUri, l_event);
    Log.v("++++++test", l_uri.toString());
}

The code above simply create a ContentValues and insert it into the database URI.

3. Sending Intent to Calendar

This method doesn’t require the READ/WRITE_CALENDAR permission. It sends out an intent to calendar, and users will be redirected to Calendar app to create the event. Note that this is not a documented method either.

Below is a method that adds an event to Android Calendar.

/*add an event through intent, this doesn't require any permission
* just send intent to android calendar
*/
private void addEvent2() {
   Intent l_intent = new Intent(Intent.ACTION_EDIT);
   l_intent.setType("vnd.android.cursor.item/event");
   //l_intent.putExtra("calendar_id", m_selectedCalendarId);  //this doesn't work
   l_intent.putExtra("title", "roman10 calendar tutorial test");
   l_intent.putExtra("description", "This is a simple test for calendar api");
   l_intent.putExtra("eventLocation", "@home");
   l_intent.putExtra("beginTime", System.currentTimeMillis());
   l_intent.putExtra("endTime", System.currentTimeMillis() + 1800*1000);
   l_intent.putExtra("allDay", 0);
   //status: 0~ tentative; 1~ confirmed; 2~ canceled
   l_intent.putExtra("eventStatus", 1);
   //0~ default; 1~ confidential; 2~ private; 3~ public
   l_intent.putExtra("visibility", 0);
   //0~ opaque, no timing conflict is allowed; 1~ transparency, allow overlap of scheduling
   l_intent.putExtra("transparency", 0);
   //0~ false; 1~ true
   l_intent.putExtra("hasAlarm", 1);
   try {
       startActivity(l_intent);
   } catch (Exception e) {
       Toast.makeText(this.getApplicationContext(), "Sorry, no compatible calendar is found!", Toast.LENGTH_LONG).show();
   }
}

This method is used in my android app, Advanced Phone Log.

4. A Complete and Runnable Example

The code snippet shown above are retrieved from an example. You can download the source code here, or find it at github.

Below are screenshots of the app.

234

Figure 1. Screenshots of Calendar Sample App

Reference:

1. Working with the Android Calendar: http://www.developer.com/ws/article.php/3850276/Working-with-the-Android-Calendar.htm

2. Google Calendar APIs and Tools: http://code.google.com/apis/calendar/data/2.0/developers_guide.html

 

40 comments on “Android Tutorial–Programming with Calendar

  1. It doesn’t work. At all..

    • @coi,

      Well, it does work. Just not all of it. I was able to successfully get a list of calendars, I just can’t seem to get a list of the user’s events.

      And Coi, if your program is crashing, make sure you’ve setup the calendar on your emulator with an account. Otherwise, run it on a phone.

  2. thanks for the great tutorial. But i would like to ask you is there a way to detect if an event is added to the calendar from the calendar app on the mobile device. to explain more to you for example if the user open the calendar app on his mobile device (Usually the google calendar app) then he add the detail of the event and add the calendar event. i want to detect the newly added event and use this event. hope you could know
    thanks

  3. Dawood on said:

    nice
    i want to use the google calendar api in my android application. how can i do this???

  4. Hi I have downloaded your sample and trying to run but I am getting following error.

    04-28 15:19:17.013: E/ActivityThread(469): Failed to find provider info for com.android.calendar

    So far I have made sure, I have correct API level (8) in project properties selected. Also I have Google Account added on my emulator. Am I missing anything?
    Seems to me that com.android.calendar provider is no more supported in Google API Level 8? I have also tried running on most recent API Level 15. But error remains same.
    Any suggestions?
    Running Environment
    Win-7, Eclipse IDE
    - Can run most of the Google Samples on my current setup.

    Thanks

  5. Ameya Thakur on said:

    ContentValues event = new ContentValues();
    event.put(“calendar_id”, 2);
    event.put(“title”, strTitle);
    event.put(“dtstart”, convertDateStringtoLong(startDateTime));
    event.put(“dtend”, convertDateStringtoLong(endDateTime));
    event.put(“allDay”,0);

    Uri l_eventUri;
    if (Build.VERSION.SDK_INT >= 8 ) {
    l_eventUri = Uri.parse(“content://com.android.calendar/events”);
    } else {
    l_eventUri = Uri.parse(“content://calendar/events”);
    }

    Uri l_uri = _activity.getContentResolver().insert(l_eventUri, event);

    Log.v(“++++++test”, l_uri.toString());//05-03 13:27:36.868: V/++++++test(7615): content://com.android.calendar/events/7934

    I am able to see the Event been posted to “content://com.android.calendar/events/7934″

    when I go to the Calendar I don’t see any Event added to the Calendar… the _activity is the one which I am passing it from the WebContainerActivity

  6. Ameya Thakur on said:

    Thanks for the wonderful tutorial……
    Is there any way we can remove the Guest field which is there in the Add Event 2 … I tried with the removeExtra it did not worked either…

  7. Rick on said:

    Can you modify this to show a specific calendar that is not owned by the end-user? Say myBusiness puts out there app and wants myBusiness’s google calendar to do the lastThreeFields method in their app.

  8. Dejan on said:

    Hey, really great application. Can you tell me how to get ListView of the events..Please help me…

Leave a Reply

Your email address will not be published.

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>

Set your Twitter account name in your settings to use the TwitterBar Section.