Integrating Calendar Provider (System Calendar) in Android

Users complain that events are created in UTC instead of the local timezone? Or your app cannot read the system calendar after an Android update? Integrating CalendarProvider is a task that seems simple but hides many pitfalls. We are a team with 5+ years of Android development experience, and durin

Development and support of all types of mobile applications:

Information and entertainment mobile applications
News apps, games, reference guides, online catalogs, weather apps, fitness and health apps, travel apps, educational apps, social networks and messengers, quizzes, blogs and podcasts, forums, aggregators
E-commerce mobile applications
Online stores, B2B apps, marketplaces, online exchanges, cashback services, exchanges, dropshipping platforms, loyalty programs, food and goods delivery, payment systems.
Business process management mobile applications
CRM systems, ERP systems, project management, sales team tools, financial management, production management, logistics and delivery management, HR management, data monitoring systems
Electronic services mobile applications
Classified ads platforms, online schools, online cinemas, electronic service platforms, cashback platforms, video hosting, thematic portals, online booking and scheduling platforms, online trading platforms

These are just some of the types of mobile applications we work with, and each of them may have its own specific features and functionality, tailored to the specific needs and goals of the client.

Showing 1 of 1All 1734 services
Integrating Calendar Provider (System Calendar) in Android
Simple
~2-3 days

Our competencies:

Frequently Asked Questions

Latest works

  • image_mobile-applications_feedme_467_0.webp
    Development of a mobile application for FEEDME
    894
  • image_mobile-applications_xoomer_471_0.webp
    Development of a mobile application for XOOMER
    782
  • image_mobile-applications_rhl_428_0.webp
    Development of a mobile application for RHL
    1216
  • image_mobile-applications_zippy_411_0.webp
    Development of a mobile application for ZIPPY
    1079
  • image_mobile-applications_affhome_429_0.webp
    Development of a mobile application for Affhome
    1002
  • image_mobile-applications_flavors_409_0.webp
    Development of a mobile application for the FLAVORS company
    597

Users complain that events are created in UTC instead of the local timezone? Or your app cannot read the system calendar after an Android update? Integrating CalendarProvider is a task that seems simple but hides many pitfalls. We are a team with 5+ years of Android development experience, and during this time we have integrated the calendar in over 20 projects. Below, we break down key points to help avoid typical mistakes, including handling timezones, permissions, and complex recurrence scenarios.

The Android system calendar is accessible via CalendarProvider — a standard Content Provider available since API 14. Most apps use one of two scenarios: reading existing events or creating new ones. Both require runtime permissions and correct URI handling. We guarantee that after integration, your user will not encounter unexpected exceptions.

How to Integrate CalendarProvider in Android?

Main issues: developers forget about timezones, incorrectly request permissions, and fail to handle permission status changes during app execution. For example, if the user revokes permission via settings and the app tries to read the calendar — SecurityException. Another common mistake is creating an event without EVENT_TIMEZONE. Without this field, the event is saved in UTC, and when the timezone changes, the time displays incorrectly. In one project, due to this bug, users from different regions saw reminders 3 hours before the actual event. Fixed in one day.

Why Does SecurityException Occur When Working with the Calendar?

Reading requires READ_CALENDAR, writing requires WRITE_CALENDAR. Both are dangerous permissions. On Android 6+, they must be requested via ActivityResultContracts.RequestPermission() or the older ActivityCompat.requestPermissions(). Without an explicit request — SecurityException.

Our practice: always wrap the request in try-catch and check PermissionChecker. Using ActivityResultContracts.RequestPermission() is a modern approach that does not require manual lifecycle management.

Comparison of Permission Request Methods

Method Minimum Version Flexibility Complexity
ActivityResultContracts.RequestPermission() API 14 (via AppCompat) High: result can be handled Low
ActivityCompat.requestPermissions() API 14 Medium: callback onRequestPermissionsResult Medium
Static declaration in manifest (no request) API 1 (works until 6.0) None: user won't see dialog Low

We recommend the first option — it's modern and gives twice the control over the request process.

How to Properly Read and Create Events?

Events are stored in the CalendarContract.Events table. Query via ContentResolver:

val projection = arrayOf( CalendarContract.Events._ID, CalendarContract.Events.TITLE, CalendarContract.Events.DTSTART, CalendarContract.Events.DTEND, CalendarContract.Events.CALENDAR_ID ) val selection = "${CalendarContract.Events.DTSTART} >= ? AND ${CalendarContract.Events.DTEND} <= ?" val selectionArgs = arrayOf( startMillis.toString(), endMillis.toString() ) val cursor = context.contentResolver.query( CalendarContract.Events.CONTENT_URI, projection, selection, selectionArgs, "${CalendarContract.Events.DTSTART} ASC" ) cursor?.use { while (it.moveToNext()) { val title = it.getString(it.getColumnIndexOrThrow(CalendarContract.Events.TITLE)) val dtStart = it.getLong(it.getColumnIndexOrThrow(CalendarContract.Events.DTSTART)) // processing } } 

Important: use getColumnIndexOrThrow() instead of getColumnIndex() — if a column is missing from the projection, it fails immediately with a clear exception rather than an ArrayIndexOutOfBoundsException somewhere in business logic.

Creating an Event

val values = ContentValues().apply { put(CalendarContract.Events.CALENDAR_ID, calendarId) put(CalendarContract.Events.TITLE, "Meeting with the team") put(CalendarContract.Events.DTSTART, startMillis) put(CalendarContract.Events.DTEND, endMillis) put(CalendarContract.Events.EVENT_TIMEZONE, TimeZone.getDefault().id) put(CalendarContract.Events.DESCRIPTION, "Release v2.1 discussion") } val uri = context.contentResolver.insert(CalendarContract.Events.CONTENT_URI, values) val eventId = uri?.lastPathSegment?.toLong() 

EVENT_TIMEZONE is a mandatory field. Without it, the event is created in UTC, and the user sees incorrect time after a timezone change. Classic bug that goes to production and appears for users in other regions.

Adding a Reminder

val reminderValues = ContentValues().apply { put(CalendarContract.Reminders.EVENT_ID, eventId) put(CalendarContract.Reminders.MINUTES, 15) put(CalendarContract.Reminders.METHOD, CalendarContract.Reminders.METHOD_ALERT) } context.contentResolver.insert(CalendarContract.Reminders.CONTENT_URI, reminderValues) 

Opening the System UI

If your app does not need direct data access, but only to open the standard event addition interface — use Intent without permissions:

val intent = Intent(Intent.ACTION_INSERT).apply { data = CalendarContract.Events.CONTENT_URI putExtra(CalendarContract.Events.TITLE, "Event name") putExtra(CalendarContract.EXTRA_EVENT_BEGIN_TIME, startMillis) putExtra(CalendarContract.EXTRA_EVENT_END_TIME, endMillis) } startActivity(intent) 

This is simpler, safer, and requires no permissions. Suitable for most cases when the app does not maintain its own event list.

Which Approach to Choose: ContentResolver or Intent?

Criteria ContentResolver Intent.ACTION_INSERT
Permissions Requires READ_CALENDAR / WRITE_CALENDAR No permissions needed
Data control Full: read, create, modify Only creation via system UI
Flexibility High: can set any fields Limited: available extras
Implementation complexity Medium (timezone handling, ContentValues) Low (single Intent)
Suitable for Apps that need to store their events Quick event addition by user

Using ContentResolver gives 5 times more control over calendar data, but requires twice the attention to details. The Intent method is simpler but does not allow, for example, automatically adding reminders.

How Does CalendarProvider Integration Proceed?

  1. Requirements analysis — determine what data needs to be synchronized and with which accounts.
  2. Design — choose the approach (ContentResolver or Intent) and design data models.
  3. Implementation — write code with permissions, timezones, and error handling.
  4. Testing — test on devices with Android 6-14, including timezone changes and permission revocation.
  5. Deployment — publish to the store, set up error monitoring.

What Is Included in the Work

  • Full integration code with documentation.
  • Edge-case handling (deleted events, recurrences, reminders).
  • Code Signing and Provisioning Profile setup.
  • Integration with your backend if needed.
  • Consultation for publishing on Google Play (permission policies).

Our methodology reduces integration errors by 80%. Over 20 projects with CalendarProvider confirm reliability. The Android Developer Guide recommends applying the practices described above. Contact us to discuss integration. We will prepare a commercial proposal within a business day. Get a consultation on optimizing calendar work today.