What You Need to Know About the Intents of Android’s Calendar App

When your app needs to access calendar data you have to choose whether to use the CalendarContract content provider or whether to use Intents to start specific Activities of the Calendar app. This post covers the intents offered by the official Calendar app.

While with using Intents your possibilities are limited compared to those of the content provider, using intents has the advantage that the user already knows the Calendar app and that some things get automated for you (e.g. alarm and attendee settings). And if you only use intents, your app doesn’t need the permissions you need for the content provider.

As of now you can do exactly four things:

  • You can open the Calendar app at a specific date
  • You can view events
  • You can create new events
  • You can edit events

Well, actually you can only do three things, since the last intent doesn’t work. More on this later.

From ICS onwards the Calendar is part of Android’s standard apps. So it is very unlikely that the Calendar app is missing. Nevertheless you should always test for the availability of Intents. I omit this in the code samples in the next paragraphs since these are examples only – but you should not! You can read more about this in my post about how to test for Intent availability.

Opening the Calendar app

Maybe you want to give the user the possibility to view her calendar. In this case you can use the ACTION_VIEW and CalendarContract.CONTENT_URI as the Uri to start the app.

You have to add the time at which you want to open the calendar. You can either do this by concatenating Strings or by using Android’s Uri.Builder helper class.

In the following code fragment I show how you would open the calendar with a date two month in the future:

Calendar cal = new GregorianCalendar(); 
cal.setTime(new Date()); 
cal.add(Calendar.MONTH, 2); 
long time = cal.getTime().getTime(); 
Uri.Builder builder = 
      CalendarContract.CONTENT_URI.buildUpon(); 
builder.appendPath("time"); 
builder.appendPath(Long.toString(time)); 
Intent intent = 
      new Intent(Intent.ACTION_VIEW, builder.build()); 
startActivity(intent); 

Creating an event

Probably more interesting is creating an event. In this case the action to use is ACTION_INSERT and the URI to use is Events.CONTENT_URI. What makes this option so compelling is that you do not have to add any Intent extras. You can open the event editor without any data – in which case only some default values of the form are prefilled as you can see in the next screen.

Form for entering events

Form for entering events

If the user has no calendar account added, Android shows a dialog that warns the user that no events can be added as long as no account exists. This is pretty common on the emulator – but should be the exception on a real device. Normally device vendors have a calendar with some sync adapter of their own. But even if this is not the case, your app will not crash. The next screenshot shows the message in this case.

Warning when no calendar account exists

Warning when no calendar account exists

The simplest code to create an event with an intent is this:

Intent intent = 
      new Intent(Intent.ACTION_INSERT, Events.CONTENT_URI);
startActivity(intent); 

But if you want, you can add data so that the form is prefilled with these values. You can basically set all the data, that you can use to create events with the content provider. For attendees and alarms you have to use other constants, since they are not part of the Events class. Strangely Google has decided that for the start- end end-time of the event you also need special constants. Why they didn’t use the constants of the Events class is beyond me. This makes the code kind of ugly and the API harder to understand than necessary. As you can see in the next code fragment these constants from differing classes do not look that good:

Calendar cal = new GregorianCalendar(); 
cal.setTime(new Date()); 
cal.add(Calendar.MONTH, 2); 
Intent intent = new Intent(Intent.ACTION_INSERT); 
intent.setData(Events.CONTENT_URI); 
intent.putExtra(Events.TITLE, "Some Test Event"); 
intent.putExtra(Events.ALL_DAY, true); 
intent.putExtra(
      CalendarContract.EXTRA_EVENT_BEGIN_TIME, 
      cal.getTime().getTime()); 
intent.putExtra(
      CalendarContract.EXTRA_EVENT_END_TIME, 
      cal.getTime().getTime() + 600000); 
intent.putExtra(
      Intent.EXTRA_EMAIL, 
      "attendee1@yourtest.com, attendee2@yourtest.com"); 
startActivity(intent); 

Viewing an event

In addition to creating a new event you sometimes want users to view an event. Once again an intent is useful here because the presentation of the intent is done in a way that the user is accustomed to. But to do so, you need to have the event id – for which you need the content provider.

For the next example I assume that you already have the id for the event. In this case the code is really simple:

Intent intent = new Intent(Intent.ACTION_VIEW);
Uri.Builder uri = Events.CONTENT_URI.buildUpon();
uri.appendPath(Long.toString(yourEventId));
intent.setData(uri.build());
startActivity(intent);

That’s all nice and swell. Alas, the default Calendar app manipulates the back stack and pressing back does not jump back to your app but to the calendar view. That’s the correct behavior when started from the calendar widget but not when the calendar app has been called from another app.

Your users have to press back twice to get back to the point where they came from. And they will blame you for this even though it’s not your fault. Because of this try to avoid the need for viewing events. It might be better to open the calendar at the correct date.

I have filed a bug report for this issue. If you agree, that this is annoying, please star this issue.

And it’s not just me, at least one developer at StackOverflow complains about the same bug.

Editing an Event

The final Intent that the calendar app supports is editing an event. Well at least according to the Android documentation.

Now it would have been nice if it worked. But not so. What you actually see if you use the intent for editing is the read-only version of the editing activity. In this case you can only change minor stuff like the reminders or the timezone. Theoretically you can provide additional data – though this unsurprisingly also doesn’t work.

Add to this that the back button causes trouble again. When you click “Done” the Calendar-View is shown. The more natural behaviour would have been to save the changes and then return to where you came from. At least clicking “Cancel” or the back button works as expected.

This is pretty annoying since this is a very useful intent – or would be if it worked. If your app needs to edit events there is no other way to do so than to create the necessary form yourself. Not what users have come to expect in Android. And not what we developers love on Android.

I have also filed a bug report for this issue. Please vote for this as well.

For this bug I have also found another fellow StackOverflow user complaining about it.

Choosing between Intents and the CalendarContract provider

When to use which approach depends on the needs of your app. The following bullet points list some pros and cons of each approach:

Advantages of using intents

  • You do not need to use permissions
  • The user of your app can decide which backend calendar to use for an event
  • familiar interface of the calendar app
  • common behavior in Android

Disadvantages of intents

  • Only very few use cases are supported; an important one doesn’t work correctly
  • The consistency of the user experience within your app might get lost when opening the Calendar app.

Advantages of the content provider

  • Significant changes of nearly all data possible
  • The only way for sync adapters to sync calendar related data
  • Might happen in the background without the user knowing much about it

Disadvantages of the content provider

  • You have to add permissions to your app
  • If your app is not acting as a sync adapter you might not know which calendar id to use

Lessons learned

You have ssen how to leverage intents to open up the Calendar view at a specific date, how to create new events and how to view existing ones.

You have also learned about the weak spots of the app’s intents: The incorrect back behavior for viewing events and the total mess of the edit event intent.

Thus you have to choose carefully which and if intents are the correct way for your app to deal with events.

Share this article:

You can leave a response, or trackback from your own site.

11 Responses to “What You Need to Know About the Intents of Android’s Calendar App”

  1. Garima Loyma says:

    Sir pls send Andriod application For Calander with Alrm messenger…

  2. Lanny says:

    Hi Wolfram, Thanks for your tutorial and it is really helpful.
    When try to view calendar event by id (got the event id by using Instances), got a problem that it shows the wrong date on Calendar app. I looked and post the question in Stackoverflow, couldn’t find a solution which works. Wonder if you have experienced with the same issue and know the work around?
    Thanks!

    on Android 4.2.2, seems still having the same problem. Is it the correct behavior, or some thing missing here?

    got the event id through
    Instances.query(context.getContentResolver(), proj, begin, end);
    proj== String[]{Instances.EVENT_ID, Instances.BEGIN, Instances.END…};

    use the even id to view the event in calendar app.

    tried with code (from http://developer.android.com/guide/topics/providers/calendar-provider.html), it still shows December 31 1969 on the ‘Detail view’ opened by the ‘intent’; and shows current date (instead of the real date specified in the event) in the ‘Edit event’ form if clicking on the the event on the ‘Detail view’ of the calendar.

    Uri uri = ContentUris.withAppendedId(Events.CONTENT_URI, eventID);

    Intent intent = new Intent(Intent.ACTION_VIEW)
    .setData(uri);
    startActivity(intent);

    and still does not work even with the:

    intent.putExtra(“beginTime”, from);
    intent.putExtra(“endTime”, till); //’from’, ’till’ is the mills got from the Instances.BEGIN/END fields from the query

  3. Subash Poudel says:

    I tried to start the calendar app using startactivityforresult but it doesnot seem to work like with camera and gallery application. Then I started using content observer but the app kept on crashing. Is there a way to add multiple events to calendar and return back to my app?

  4. Francesco Lombardi says:

    Hi this is interesting, tnx you for your tutorial. If i create a calendar with a specific Uri, can i create an event only for that calendar using intents? I don’t want to use API. tnx for your answer

  5. Faris says:

    i want to set a begin time and end time for an event,how can i do that ?
    and if want it to be a recurring event?

  6. Aayushi Jain says:

    i want to know the event_id after creating an event to edit and delete using

    Calendar cal = new GregorianCalendar();
    cal.setTime(new Date());
    cal.add(Calendar.MONTH, 2);
    Intent intent = new Intent(Intent.ACTION_INSERT);
    intent.setData(Events.CONTENT_URI);
    intent.putExtra(Events.TITLE, “Some Test Event”);
    intent.putExtra(Events.ALL_DAY, true);
    intent.putExtra(
    CalendarContract.EXTRA_EVENT_BEGIN_TIME,
    cal.getTime().getTime());
    intent.putExtra(
    CalendarContract.EXTRA_EVENT_END_TIME,
    cal.getTime().getTime() + 600000);
    intent.putExtra(
    Intent.EXTRA_EMAIL,
    “attendee1@yourtest.com, attendee2@yourtest.com“);
    startActivity(intent);
    i am successfully creating event but unable to get the event_id . Can you please help me regarding getting event_id using intent method.

  7. Rekha says:

    Hello sir,
    i want source code of Event screen for my project to create a new
    event screen.
    please help me…

    • You can search for it. The app is part of the AOSP. But why you would want to do so, is beyond me. I recommend to either use intents to reuse the existing app or to create something that fits exactly your app and your app’s needs.

Leave a Reply

You can also subscribe without commenting.

Subscribe to RSS Feed My G+-Profile Follow me on Twitter!