Skip to content

Basis of CalendarManager

1. Create CalendarManager

If you want to create CalendarManager, then you need an instance of CalendarManager.Factory. Calendar SDK provides Dagger's CalendarComponent which needs to be included in DI graph to produce instance of CalendarManager.Factory.

After the CalendarManager.Factory is inserted in the proper place, you can use it to get CalendarManager.

CalendarManager as an argument receives a list of authorized accounts. Passed accounts can be of different types: Google, Microsoft or list of Google and Microsoft accounts.

1
2
3
4
5
6
@Inject
lateinit var factory: CalendarManager.Factory

fun getCalendarManager(accounts: List<Account>): CalendarManager {
    return factory.create(accounts)
}

2. Operation Concept

Execution

Almost all methods of CalendarManager returns type Operation<T>. The Interface Operation<T> is a special wrapper for any long Non-UI operation. The Operation can be fulfilled in synchronous and asynchronous manners.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
    // Synchronous approach
    try {
       val result = calendarManager.getCalendars().execute()
    } catch(e: Exception) {
        // handle exception
    }

    // Asynchronous approach
    calendarManager.getCalendars().enqueue(object : Callback<List<Calendar>> {
        override fun onSuccess(result: List<Calendar>>) {
            // handle result
        }

        override fun onError(t: Throwable) {
            // handle error
        }
    }

Cancellation

Any instance of Operation can be canceled using the cancel() method.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
    val operation = calendarManager.getCalendars()

    operation.enqueue(object : Callback<List<Calendar>> {
        override fun onSuccess(result: List<Calendar>>) {
            // handle result
        }

        override fun onError(t: Throwable) {
            // handle error
        }
    }

    // cancel operation
    operation.cancel()

Important

When Operation is completed or canceled it can't be reused again.

3. Getting calendars and events

Calendars

If you want to get all user's calendars via CalendarManager which is bound to previously passed account, then call the getCalendars() method.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
    val result = kotlin.runCatching { calendarManager.getCalendars().execute() }


    // if a list of accounts contains different providers, we can group calendars by them
    result.onSuccess {
        val groupedCalendars = it.groupBy { it.source }

        val googleCalendars = groupedCalendars[Calendar.CalendarSource.GOOGLE]
        val microsoftCalendars = groupedCalendars[Calendar.CalendarSource.MICROSOFT]

        ...
    }

Events

If you want to get the events of calendars fetched via getCalendars() call getEvents() method. getEvents() accepts timePeriod paremeter which is responsible for start and end date of events. All events which are in this time period will be fetched.

1
2
3
4
5
6
7
8
    calendarManager.getCalendars().execute()

    val startTime = Date()
    val endTime = Date(startTime.time + 3_600_600)

    // it will return a list of events in the range of 1 hour
    val events = kotlin.runCatching { calendarManager.getEvents(TimePeriod(startTime, endTime)).execute() }
    ...

Important

Date is presented in UTC Time Zone.

4. Change event response status

1
2
3
4
5
6
7
8
    // Change response status to accept
    val acceptedEvent = kotlin.runCatching { calendarManager.accept(event).execute() }

    // Change response status to tentative
    val tantativelyAcceptedEvent = kotlin.runCatching { calendarManager.tentative(event).execute() }

    // Change response status to reject
    val rejectedEvent = kotlin.runCatching { calendarManager.reject(event).execute() }

5. Observe calendar changes

Start observing

EventsObserver allows observing changes in a specific calendar. It tracks deleted events, udpated events and new events. If you want to start observing changes, the call the observe() method. It accepts list of calendars, time range in which we want to observe and EventsObserver.

Instance of EventsObserver can be created via instance of CalendarManager via createEventsObserver() method. To start receiving updates method start() should be called before addObserver().

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
    val startTime = Date()
    val endTime = Date(startTime.time + 3_600_600)

    val eventsObserver = calendarManager.createEventsObserver(TimePeriod(startTime, endTime))
    eventsObserver.start()

    eventsObserver.addObserver(object : EventsObserver {
        override fun onNewEvents(events: List<Event>) {
            // handle new events
        }

        override fun onUpdatedEvents(events: List<Event>) {
            // handle updated events
        }

        override fun onDeletedEvents(events: List<Event>) {
            // handle deleted events
        }

        override fun onError(t: Throwable) {
            // handle errors
        }
    })

Important

Date is presented in UTC Time Zone.

Important

Interval for checking changes is 15 seconds.

Stop observing

To fully stop observing changes all callbacks should be removed before calling stop().

Important

If any error occurs while observing changes then the observer for specific calendar will stop. In order to continue observing, you need to call restart() or restartAll().

6. Meeting Details

CalendarManager is able to detect meeting info in the event description field or location field. If the CalendarManager finds meeting info it will parse and create the corresponding meeting structure in Event.

Important

Currently, the CalendarManager supports only Zoom invitation and all Zoom related data contains in ZoomMeetingInfo class.

Read more about error handling in the next section.

Events Reminder

Events Reminder it's a mechanism which send notifications about upcoming events.

EventsReminderManager can be created via EventsReminderManager.Factory. For creating you need EventsObserver and CalendarManager.

Important

EventsReminderManager will be tracking only those events which are in time range passed to EventsObserver.

Callback-based approach

In order to use callback-based would be enough to set listener for EventsReminderManager and call start().

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
    val startTime = Date()
    val endTime = Date(startTime.time + 3_600_600)

    val eventsObserver = calendarManager.createEventsObserver(TimePeriod(startTime, endTime))
    eventsObserver.start()

    val eventsReminderManager = EventsReminderManager.Factory.create(calendarManager, eventsObserver)
    eventsReminderManager.addListener(...)

    eventsReminderManager.start()

BroadcastReceiver-based approach

In order to send system-wide notifications you need to create instance of CalendarNotification. CalendarNotification is located in android-sdk-calendar-notification library. In order to receive notifications, should be registered BroadcastReceiver with action in constant ACTION_UPCOMING_CALENDAR_EVENT. To get extras from Intent you can use such constants:

  • EXTRA_EVENT - via this constant you can get instance of Event class.
  • EXTRA_LEFT_MINUTES_BEFORE_EVENT - via this constant you can get how many minutes left before event.
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
    val startTime = Date()
    val endTime = Date(startTime.time + 3_600_600)

    val eventsObserver = calendarManager.createEventsObserver(TimePeriod(startTime, endTime))
    eventsObserver.start()

    val eventsReminderManager = EventsReminderManager.Factory(calendarManager, eventsObserver)
    val calendarNotification = CalendarNotification.Factory(appContext, eventsReminderManager)

    calendarNotification.start()

    val intentFilter = IntentFilter(ACTION_UPCOMING_CALENDAR_EVENT)

    activity.registerReceiver(object : BroadcastReceiver {
        override fun onReceive(context: Context, intent: Intent) {
            val event = intent.getParcelable<Event>(EXTRA_EVENT)
            val minutesLeft = intent.getInt(EXTRA_LEFT_MINUTES_BEFORE_EVENT)
            ...
        }
    }, intentFitler)