Android Calendar Intent
Calendar is the most common application that user uses daily. User can add his / her daily plans into it. Calendar can notice user for the upcoming events automatically. It is useful if an application can add an event to the Calendar app and remind user for the future event.
Android provides mainly two approaches to work on calendar event. One is using Calendar Provider
and the another one is handing off it to the system Calendar app.
Calendar Provider
provides us all the functionalities, including inserting, querying, updating and deleting existing calendar events. However, the steps are tedious and must require user’s runtime permissions (android.permission.READ_CALENDAR
and android.permission.WRITE_CALENDAR
) to read and write the sensitive calendar information. It is easy to make a mistake with this approach.
Therefore, Google officially recommends developer to use the second approach, i.e. handing off all the calendar operations to system Calendar app by using Intent
. Calendar app is opened right after requested by our app and user is automatically redirected back to our app after user finishes his / her calendar actions. In system Calendar app, there has already been a well-designed UI for user to fill in necessary calendar information. Good UI and UX can then be guaranteed.
This article will briefly cover:
- Limitation of Intent approach
- Structure of Android Calendar database
- Idea of
Content Provider
- Coding 1) : Inserting new calendar event
- Coding 2): Viewing events on a specific date
- Coding 3): View an event details by event id
- Coding 4): Update an event by event id
- Recurrence Rule (RRule) definition
- Calendar field: Invitees
Limitation of Intent approach
Not all calendar operations are available for Intent approach. See the above table. As stated mentioned at the Calendar Intent official documentation, Calendar Intent can only view, edit and create a calendar event. Deletion is not an option. In order to delete an existing one, Calendar Provider
has to be used and lots of tedious codes have to be added. See here.
Calendar structure
In Android system, there are mainly 5 tables under Calendar structure and can be divided into 3 levels in Android calendar structure. They are:
- Calendar
- Event
- Attendee, Reminder and Instance
There is also a Time
table which will be covered at the later session.
In each device, one or more calendar accounts can be added, e.g. Google, Apple and Microsoft. Under each calendar, there can be a list of event. At the same time, there can be a list of attendees, reminders and instance under each event.
The concept of event
and instance
is likely confusing. Let’s explain with a calendar example:
Event: Every Tuesday from 1st January, 2019 to 31st December, 2019.
Instance:
- (Tuesday) 1st January, 2019
- (Tuesday) 8th January, 2019,
- …
53. (Tuesday) 31st December, 2019
There are totally 53 instances
under a single weekly event
.
Calendar provider
Calendar provider is one of the content providers which store data in a relational database model and expose them to other applications through unique public URIs (Uniform Resource Identifier). As mentioned above, there are mainly 5 tables controlled by Calendar Provider and thus there are 5 public URIs.
- Calendars table URI:
content://com.android.calendar/calendars
- Events table URI:
content://com.android.calendar/events
- Attendees table URI:
content://com.android.calendar/attendees
- Reminders table URI:
content://com.android.calendar/reminders
- Instances table URI:
content://com.android.calendar/instances
Every Content Provider provides URI with a special format. URI must start with content://
and followed by the class of provider. The last parameter is the name of table.
Coding part
Coding part will be split into four parts:
- Inserting new calendar event
- Viewing a list of calendar event by a given time
- Viewing an existing calendar event by event id
- Updating an existing calendar event
Parts of the codes are shared between each category.
Coding 1) : Inserting new calendar event
Step 1: Define an Intent
As mentioned before, app hands off the calendar action to the system Calendar app. Therefore, the only way to pre-fill the information at the system Calendar app is to pass it through Intent
.
The 1st parameter to be set is the action of Intent. There are three possible choices:
- Intent.ACTION_INSERT
(Used for creating a new Calendar event) - Intent.ACTION_VIEW
(Used for viewing an existing Calendar event either by event id or event time) - Intent.ACTION_EDIT
(Used for editing an existing Calendar event)
The 2nd thing to be set is the CONTENT_URI
of the table we are now editing to. As mentioned above, there are mainly 5 different tables under Calendar structure. To view, edit and create a calendar event, it should point to the Events
table which stores the information of all calendar events.
Step 2: Add extra data to Intent
Calendar information can be passed to Calendar app by Intent
through extra
. See the above image for all the available keys.
Most of the parameters are self-explanatory except the RRULE
which stands for “Recurrence Rule”. It is just like SQL statement which defines the query rules for system to filter specific days. It will be explained in details in the coming session.
Step 3: Open system calendar app
Calendar app can be triggered by using the simplest function startActivity(intent: Intent)
.
Coding 2): Viewing events on a specific date
The 2nd calendar feature is viewing events on a specific date. The date cell specified by the the provided timestamp is highlighted on Calendar app. The above sample code is using timestamp 1546300800000
which is 1st January, 2019.
One important thing is that the URI used this time is content://com.android.calendar/time/1546300800000
. It is pointing to a table of Time
instead of the Calendar
, Events
, Attendees
, Reminders
and Instances
. Since Time
does not provide a public URI, the URI has to be constructed with Uri.Builder
.
The second important thing is that Intent action is no longer Intent.ACTION_INSERT
and should be changed to Intent.ACTION_VIEW
. By definition, Intent.ACTION_VIEW
is used for displaying data to the user and Intent.ACTION_INSERT
is used for inserting an empty item into the given container.
Coding 3): View an event details by event id
Android provides an approach to view the event details by event id
which can only be queried from Calendar Provider
. Due to the sensitive user information, read calendar permission (android.permission.READ_CALENDAR
) must be granted at runtime.
Step 1: Request android.permission.READ_CALENDAR permission
RxPermission is recommended to be used for requesting permission at runtime due to its simplicity for requesting permission and checking the status.
Step 2: Get event id from Calendar Content Provider
At the above function, both the event_id
and title
columns are queried for demonstration. Actually all fields in an event can be queried.
Step 3: Construct an URI with event ID
This time we could use the withAppendedId()
function to construct the URI since Events
table provides the public CONTENT_URI
. The final URI format is content://com.android.calendar/events/{event_id}
.
Step 4: Set Intent action to Intent.ACTION_VIEW
Same as the session before, Intent.ACTION_VIEW
has to be used since it is now viewing a record instead of creating a new record. The following page, which has only share and delete functions, of the event is eventually shown:
Coding 4): Update an event by event id
The final available calendar action provided by Android is updating an existing event. Like the one for viewing an event by its event id
, the URI is in format of content://com.android.calendar/events/{event_id}
. However, the Intent action has to be changed to Intent.ACTION_EDIT
which provides explicit editable access to the given data. All event fields added at the “Coding 1)” can be updated here with the same extra keys.
Get the response from user
User can either perform or cancel the calendar functions (insert and update). App can detect this result at the onActivityResult()
callback.
Result code
can be either Activity.RESULT_OK
(value: -1)when user has performed the action successfully or Activity.RESULT_CANCELED
(value: 0) when user canceled the actions.
Moreover, there is only data returned when an event is inserted or updated. There are only three fields stored in the returned
Intent:
Key: timezone; Value: Asia/Hong_Kong
Key: allday; Value: false
Key: go_to_millis; Value: 1573365600000
Recurrence rule
Recurrence rule defines the repeating pattern for recurring events. It is in form of string. For example, FREQ=WEEKLY;BYDAY=MO;COUNT=3
represents a pattern repeating 3 times on every Monday weekly, i.e. Monday, 2019-Nov-05 & 12 & 19.
The rule is written in the format of {rule_name}={rule_value}
and concatenated with others with semicolon ;
.
There are lots of global standard recurrence rules. Here are the four common rules which could be able to handle most cases — FREQ
, UNTIL
, COUNT
and BYDAY
.
1. FREQ (Frequency)
Frequency defines how often the pattern is repeated. It accepts the following parameters:
DAILY
WEEKLY
MONTHLY
YEARLY
Example: FREQ=DAILY
2. UNTIL
UNTIL
defines the end date of the frequency. It accepts a value in date format of yyyyMMdd'T'HHmmss'Z'
, e.g. “20191105T000000Z”
Example: FREQ=DAILY;UNTIL=20191105T000000Z
means repeating the event every day until the 5th November, 2019.
3. COUNT
COUNT
defines the number of occurrence of the frequency. It accepts an integer value.
Example: FREQ=DAILY;COUNT=10
means repeating the event every day for 10 rounds, i.e. 10 days.
4. BYDAY
BYDAY
defines the list of weekday that the repeating pattern should be applied. It accepts the following parameters:
MO
(Monday)TU
(Tuesday)WE
(Wednesday)TH
(Thursday)FR
(Friday)SA
(Saturday)SU
(Sunday)
Example: FREQ=WEEKLY;BYDAY=MO,FR
means the pattern repeats on every Monday and Friday weekly.
Practical examples:
- Repeat yearly on the upcoming 3 years
FREQ=YEARLY;COUNT=3
- Repeat monthly until 1st January, 2020
FREQ=MONTHLY;UNTIL=20200101T000000Z
- Repeat every Monday and Thursday on the upcoming 3 weeks. Count is 6 since total occurrence is 2x3 = 6.
FREQ=WEEKLY;BYDAY=MO,TH;COUNT=6
- Repeat weekly on Monday until 1st January, 2020
FREQ=WEEKLY;BYDAY=MO,TU;UNTIL=20200101T000000Z
Trick on Recurrence Rule
UNTIL
and COUNT
contradict with each other. UNTIL
defines the end date of the frequency. COUNT
defines the number of occurrence of the frequency.
Android would ignore the presence of COUNT
if UNTIL
is presented, i.e. FREQ=DAILY;COUNT=10;UNTIL=20191105T000000Z
equals to FREQ=DAILY;UNTIL=20191105T000000Z
Calendar field: Invitees
Invitee
is a special field in Calendar information. It accepts either an email address or a list of email addresses separated with comma. See below example:
Automatic invitation email
An email will be automatically sent to all invitees right after the calendar is created, updated and deleted. See below for the email templates:
Automatic confirmation email
If invitee accepts or declines the user’s invitation, a confirmation email is sent to the user automatically. See below for the templates:
Add to invitee’s calendar (Both Android & iOS )
Together with the email, there is an invite.ics
attachment which is readable in both Android and iOS. The invitee can click on this attachment and system would automatically pop up the calendar app to insert the calendar events.
Summary
- Android provides two approaches to handle Calendar operation and the recommended approach is handing off the operation to system Calendar app. Using Intent approach can reduce the risk on handling calendar operations since trustable UI and UX are provided by system
- There are mainly 6 tables controlled under calendar structure. They are
Calendars
,Events
,Attendees
,Reminders
,Instances
andTime
. ButTime
does not provide a public URI. - Different operations have to use different Intent action.
Intent.ACTION_INSERT
should be used when event is going to be created.Intent.ACTION_EDIT
should be used when event is going to be updated.Intent.ACTION_VIEW
should be used when event is going to be viewed. android.permission.READ_CALENDAR
has to be requested andevent id
has to be retrieved before editing or viewing an existing record.- Recurrence rule is a SQL like statement. The most usefully codes are
FREQ
(Frequency),UNTIL
(End time of repeat pattern),COUNT
(number of occurrence) andBYDAY
(Specific days). - Automatic invitation emails are sent to all invitees and confirmation emails are sent back to user when invitees make their choices on the invited event. Invitee can add the event to calendar by the email attachment (
Invite.ics
).
Hope this article could give you more understanding on Android Calendar. Have a nice day~ Cheer! 😉
Reference:
1. Calendar Provider official documentation
2. Intent action list official documentation
3. Recurrence rule demo
To know more about me and my learning pattern:
Please follow me at Twitter@myrick_chow for more information. Thank you for reading this article. Have a nice day! 😄