Enumerating Android Calendars


AndroidAndroid APIs allow you to query information about calendars in your system. Your application can perform typical read, write, update, and delete (CRUD) operations on calendars using a combination of several classes.

To retrieve calendar data, you’ll use the following classes:

  • Context
  • ContentResolver
  • Cursor

Android security requires that you announce your application’s intentions for calendar access. You indicate this in the application’s manifest file. The following manifest entry tells the Android platform that your application will read calendar information:

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

Make sure that the <uses-permission> is immediately outside the <application> tag. If you do not put this permission indicator in your manifest file, your application will throw security exceptions. More importantly, it won’t be able to access calendar information.

Why do you need three classes (Context, ContentResolver, and Cursor) to retrieve calendar information? First, a cursor is used to iterate through calendar information. Second, the Cursor is provided by a ContentResolver. Finally, you need a Context to retrieve a content resolver.

Within an Activity class, which represents a user-interface view, you can get a content resolver easily with the getContentResolver method. An Activity is a subclass of Context. That’s simple enough. However, if you want to separate concerns, you may want to create a calendar service to isolate calendar details from the rest of your application. As a separate, non-Activity, class, your CalendarService (implementation left to the reader) may not have access to a context. So you may need to provide a resolver or context from your Activity when instantiating a CalendarService instance. 

Here’s how you retrieve the content resolver:

import android.content.ContentResolver;
// if you are calling from within an Activity
ContentResolver resolver = getContentResolver(); // if you are calling from elsewhere with access to a Context ContentResolver resolver = context.getContentResolver();

Once you have the resolver, you can then query it for the exact data items needed. Calendars have a lot of information including name, time zone, and colors. Tell the resolver exactly what you want by declaring a projection. A projection is simply a String array that indicates the fields that you want to extract from a calendar row in Android’s databases.

The following code shows how to perform the query:

import android.provider.CalendarContract;
String[] projection = {CalendarContract.Calendars._ID,
String selection = String.format("%s = 1", CalendarContract.Calendars.VISIBLE);
Cursor c = contentResolver.query(CalendarContract.Calendars.CONTENT_URI,
    null, null);
while(c.moveToNext()) {
    // the cursor, c, contains all the projection data items
    // access the cursor’s contents by array index as declared in
    // your projection 
    long id = cursor.getLong(0);
String name = cursor.getString(1)); ... } c.close();

This particular example simply iterates over the calendar meta-data, not actual events. You’ll need an additional query for that.

Leave a Reply

Your email address will not be published. Required fields are marked *