Nanfeng

Notes on software development, code, and curious ideas

Adding Calendar Events and Reminders from an Android App

An Android app can add a calendar event in two ways. The simplest and safest option opens the system calendar editor. Direct insertion through Calendar Provider offers more control but requires calendar permissions and account handling.

Option 1: open the calendar editor

This approach does not require calendar read or write permission because the user reviews and saves the event:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
val start = System.currentTimeMillis() + 60 * 60 * 1000
val end = start + 30 * 60 * 1000

val intent = Intent(Intent.ACTION_INSERT).apply {
data = CalendarContract.Events.CONTENT_URI
putExtra(CalendarContract.EXTRA_EVENT_BEGIN_TIME, start)
putExtra(CalendarContract.EXTRA_EVENT_END_TIME, end)
putExtra(CalendarContract.Events.TITLE, "Project reminder")
putExtra(CalendarContract.Events.DESCRIPTION, "Review the latest build")
}

if (intent.resolveActivity(packageManager) != null) {
startActivity(intent)
}

Use this unless silent, app-managed insertion is a real product requirement.

Option 2: insert directly

Declare permissions in AndroidManifest.xml:

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

On Android 6.0 and later, request both dangerous permissions at runtime. After permission is granted, select a writable calendar from CalendarContract.Calendars, then insert the event:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
val zone = TimeZone.getDefault().id
val values = ContentValues().apply {
put(CalendarContract.Events.CALENDAR_ID, calendarId)
put(CalendarContract.Events.TITLE, "Project reminder")
put(CalendarContract.Events.DTSTART, start)
put(CalendarContract.Events.DTEND, end)
put(CalendarContract.Events.EVENT_TIMEZONE, zone)
}

val eventUri = contentResolver.insert(
CalendarContract.Events.CONTENT_URI,
values
) ?: error("Unable to create event")

val eventId = ContentUris.parseId(eventUri)

Add a reminder for that event:

1
2
3
4
5
6
val reminder = ContentValues().apply {
put(CalendarContract.Reminders.EVENT_ID, eventId)
put(CalendarContract.Reminders.MINUTES, 10)
put(CalendarContract.Reminders.METHOD, CalendarContract.Reminders.METHOD_ALERT)
}
contentResolver.insert(CalendarContract.Reminders.CONTENT_URI, reminder)

Calendar availability is not guaranteed. A device may have no writable account, a provider may reject a reminder method, or the user may revoke permission. Query for CAL_ACCESS_LEVEL >= CAL_ACCESS_CONTRIBUTOR, handle empty results, and show a clear fallback instead of assuming a fixed calendar ID.

+