Інтеграція Calendar Provider (системний календар) в Android-додаток

TRUETECH займається розробкою, підтримкою та обслуговуванням мобільних додатків iOS, Android, PWA. Маємо великий досвід та експертизу для публікації мобільних додатків до популярних маркетів Google Play, App Store, Amazon, AppGallery та інші.

Розробка та підтримка будь-яких видів мобільних додатків:

Інформаційні та розважальні мобільні програми
Новинки, ігри, довідники, онлайн-каталоги, погодні, фітнес та здоров'я, туристичні, освітні, соціальні мережі та месенджери, квіз, блоги та подкасти, форуми, агрегатори
Мобільні програми електронної комерції
Інтернет-магазини, B2B-додатки, маркетплейси, онлайн-обмінники, кешбек-сервіси, біржі, дропшиппінг-платформи, програми лояльності, доставка їжі та товарів, платіжні системи
Мобільні програми для управління бізнес-процесами
CRM-системи, ERP-системи, управління проектами, інструменти для команди продажів, облік фінансів, управління виробництвом, логістика та доставка, управління персоналом, системи моніторингу даних
Мобільні програми електронних послуг
Дошки оголошень, онлайн-школи, онлайн-кінотеатри, платформи надання електронних послуг, платформи кешбеку, відеохостинги, тематичні портали, платформи онлайн-бронювання та запису, платформи онлайн-торгівлі

Це лише деякі з типів мобільних додатків, з якими ми працюємо, і кожен із них може мати свої специфічні особливості та функціональність, а також бути адаптованим під конкретні потреби та цілі клієнта.

Послуги, які ми пропонуємо
Показано 1 з 1Усі 1735 послуг
Інтеграція Calendar Provider (системний календар) в Android-додаток
Простий
~2-3 дні
Часті запитання

Наші компетенції:

Етапи розробки

Останні роботи

  • image_mobile-applications_feedme_467_0.webp
    Розробка мобільного додатка для компанії FEEDME
    792
  • image_mobile-applications_xoomer_471_0.webp
    Розробка мобільного додатку для компанії XOOMER
    671
  • image_mobile-applications_rhl_428_0.webp
    Розробка мобільного додатку для компанії RHL
    1097
  • image_mobile-applications_zippy_411_0.webp
    Розробка мобільного додатку для компанії ZIPPY
    969
  • image_mobile-applications_affhome_429_0.webp
    Розробка мобільного додатку для компанії Affhome
    914
  • image_mobile-applications_flavors_409_0.webp
    Розробка мобільного додатку для компанії FLAVORS
    495

Інтеграція Calendar Provider (системний календар) в Android-додатки

Системний календар Android доступний через CalendarProvider—стандартний Content Provider, доступний з API 14. Більшість додатків використовують один з двох сценаріїв: читання існуючих подій або створення нових. Обидва вимагають дозволів під час виконання та правильної роботи з URI.

Дозволи

Для читання використовуйте READ_CALENDAR; для запису — WRITE_CALENDAR. Обидва є dangerous permissions, запитуються через ActivityCompat.requestPermissions() або ActivityResultContracts.RequestPermission(). Без явних запитів під час виконання на Android 6+ ви отримуєте SecurityException.

Читання подій

События зберігаються в таблиці CalendarContract.Events. Запит через 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))
        // обробка
    }
}

Важливо: використовуйте getColumnIndexOrThrow() замість getColumnIndex()—якщо колонка відсутня в проекції, це негайно впадає з чіткою винятковою ситуацією замість ArrayIndexOutOfBoundsException десь у бізнес-логіці.

Створення події

val values = ContentValues().apply {
    put(CalendarContract.Events.CALENDAR_ID, calendarId)
    put(CalendarContract.Events.TITLE, "Зустріч із командою")
    put(CalendarContract.Events.DTSTART, startMillis)
    put(CalendarContract.Events.DTEND, endMillis)
    put(CalendarContract.Events.EVENT_TIMEZONE, TimeZone.getDefault().id)
    put(CalendarContract.Events.DESCRIPTION, "Обговорення версії v2.1")
}

val uri = context.contentResolver.insert(CalendarContract.Events.CONTENT_URI, values)
val eventId = uri?.lastPathSegment?.toLong()

EVENT_TIMEZONE — це обов'язкове поле. Без нього подія створюється в UTC, і користувачі бачать неправильний час після зміни часового поясу. Це класична помилка, що потрапляє на виробництво й проявляється у користувачів з інших регіонів.

Додавання нагадування

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)

Відкриття системного UI

Якщо вашому додатку не потрібен прямий доступ до даних, а тільки відкриття стандартного інтерфейсу створення подій, використовуйте Intent без дозволів:

val intent = Intent(Intent.ACTION_INSERT).apply {
    data = CalendarContract.Events.CONTENT_URI
    putExtra(CalendarContract.Events.TITLE, "Назва події")
    putExtra(CalendarContract.EXTRA_EVENT_BEGIN_TIME, startMillis)
    putExtra(CalendarContract.EXTRA_EVENT_END_TIME, endMillis)
}
startActivity(intent)

Це простіше, безпечніше й не вимагає дозволів. Це підходить для більшості випадків, коли додаток не веде свій власний список подій.

Інтеграція CalendarProvider займає 1–3 дні залежно від обсягу функцій: читання подій, їх створення, синхронізація кількох облікових записів. Вартість розраховується індивідуально.