Calendar

The Calendar API lets you add, change, and delete entries (called events) in the calendar database on a device. You can add new events and include related information such as the location, start and end time, and list of attendees. You can also include more detailed information for an event, such as frequency and recurrence information, sensitivity, and if the event is a special type of event (for example, an all-day event or a birthday).

The calendar database is accessible from any application that uses the Calendar API, including the BlackBerry Calendar app that's included in BlackBerry 10. So, if you create an app that adds new events to the database, a user can see these events in the Calendar app. Similarly, if the user creates, updates, or deletes an event in the Calendar app, these changes are reflected when your app accesses the calendar database.

The CalendarEvent class represents an event in the calendar database. This class contains all of the information about a particular event. The Calendar API also includes a few specialized classes that represent specific types of information about an event. For example, the Recurrence class represents the recurrence rules for an event, including whether the event repeats, how often it repeats, what days of the week it occurs on, and so on. The Sensitivity class represents the degree of confidentiality of an event (personal, private, confidential, and so on). Other helpful classes include AttendeeStatus and BusyStatus.

Screen showing the Calendar application.

One class that's important is the Attendee class, which represents a single participant in an event. You can retrieve a list of Attendee objects for an event by calling CalendarEvent::attendees(). Then, you can use the returned Attendee objects to find out more information about a specific attendee (such as email address, and name) and their role (such as meeting chair, required attendee, or optional attendee).

To save an event to the calendar database, several fields are required; if you don't provide values for them, you can't save the event. At a minimum, you must populate the following fields in a CalendarEvent:

  • Account ID
  • Folder ID
  • Start time
  • End time
  • Subject

Prerequisites

To use the Calendar API in your app, you need to link against the correct library by adding the following line to your project's .pro file:

LIBS += -lbbpim

Your app must also have the Calendar permission ( access_pimdomain_calendars), which you specify in the bar-descriptor.xml file for your app.

Identifying calendar events

Each event that you add to the calendar database must have an account ID and folder ID. When they are used together, these values uniquely identify a calendar that's available on the device and let you add, update, and remove events in that calendar.

An account ID represents a specific account that's associated with the device. Users can associate multiple email accounts with their devices, such as Gmail accounts, Windows Live Hotmail accounts, or work accounts. Each account is uniquely identified using an account ID, and you can use this ID to determine which account to add calendar events to.

A folder ID represents a specific calendar in the Calendar app on the device. Each account that a user associates with the device can contain its own calendars. For example, a user's Gmail account might include three separate calendars: a birthday calendar, an appointment calendar, and a mortgage payment calendar. The Calendar app aggregates and displays all of the calendars from all of the accounts on the device, so it's important to have a way to refer to a specific calendar in an account. Each calendar has a folder ID that identifies that calendar in its account.


Diagram showing two accounts, Gmail and Windows Live Hotmail, each with several calendars.

The folder ID uniquely identifies a calendar within a particular account only. It's possible to have two distinct calendars that have the same folder ID but different account IDs. Also, an account ID uniquely identifies an account on a particular device only. For example, if you add the same Gmail account to both a BlackBerry Z10 smartphone and a BlackBerry Q10 smartphone, the account IDs that you retrieve on each device are not related in any way and may or may not be the same. Similarly, if you delete a Gmail account from a device and add it to the same device again, the account ID changes.

When your app accesses the calendar database, you should consider retrieving the default account ID and folder ID so that you know where to add your calendar events. Users can select their default calendar using the Settings app on the device, and this calendar is usually a good place to store new events that your app creates.

You can call CalendarService::defaultCalendarFolder() to retrieve a pair of IDs (an account ID and a folder ID) that specify the default calendar on the device. When you call this function, you receive the IDs as a QPair, and you can access each value by using the first and second public data members.

Not applicable

Here's how to retrieve the IDs for the default calendar and then use them to create and add a new calendar event:

#include <bb/pim/calendar/CalendarService>
#include <bb/pim/calendar/CalendarEvent>

using namespace bb::pim::calendar;
// Create the calendar service object
CalendarService calendarService;

// Retrieve the IDs for the default calendar
QPair<AccountId, FolderId> defaultCalendar =
    calendarService.defaultCalendarFolder();

// Create the calendar event and set its IDs
CalendarEvent newEvent;
newEvent.setAccountId(defaultCalendar.first);
newEvent.setFolderId(defaultCalendar.second);

// Populate any other appropriate fields of the event, such as
// start time, end time, subject, and so on
...

// Save the new event to the calendar database
calendarService.createEvent(newEvent);

The AccountId and FolderId variables are typedefs that refer to integers. These typedefs are available automatically when you import the CalendarService header file in your project. Using these named typedefs, along with others such as AttendeeId and ContactId, makes it easier to read and maintain your code.

Because there could be several different calendars on the device, you might want to retrieve a list of all of them and then decide which one to add your calendar event to. You can call CalendarService::folders() to get a list of every calendar in every account that's associated with the device. This function returns a QList filled with CalendarFolder objects, and you can iterate through the objects in the list to find the calendar that you want.

The list of calendars that your app retrieves depends on the security perimeter that your app is running in. If your app is running in the personal space on the device, the folders() function returns only those calendars that are located in the personal space. Similarly, if your app is running in the work space, the folders() function returns only those calendars that are located in the work space. This separation of personal and work calendars helps keep data secure between the two perimeters and ensures that only authorized apps have access to potentially sensitive work data.

Not applicable

Here's how to retrieve a list of all calendars in the calendar database, find a calendar named "Birthdays" (if it exists), and add a new event to that calendar:

#include <bb/pim/calendar/CalendarService>
#include <bb/pim/calendar/CalendarFolder>
#include <bb/pim/calendar/CalendarEvent>

using namespace bb::pim::calendar;
// Create the calendar service object
CalendarService calendarService;

// Retrieve the list of all calendars
QList<CalendarFolder> allFolders = calendarService.folders();

// Determine whether a calendar named "Birthdays" exists in the
// list of all calendars
bool found = false;
for (int i = 0; i < allFolders.size(); i++) {
    if (allFolders.at(i).name() == "Birthdays")
        found = true;
        break;
}

if (found) {
    // Create a new birthday event that's associated with the
    // "Birthdays" calendar
    CalendarEvent newBirthday;
    newBirthday.setAccountId(allFolders.at(i).accountId());
    newBirthday.setFolderId(allFolders.at(i).id());
    
    // Populate any other appropriate fields of the event, such
    // as subject and birthday flag
    ...

    // Save the new event to the calendar database
    calendarService.createEvent(newBirthday);
} else {
    // The "Birthdays" calendar wasn't found, so handle this case
    // here
    ...
}

Manipulating calendar events

To create a new calendar event and add it to the calendar database, you create a CalendarEvent object and use its functions to specify the properties of the event. For example, you can call setStartTime() to specify the start time, setSubject() to specify the subject, and so on. To save your events to the database, you need to create a CalendarService object and use createEvent() to add the event.

Not applicable

Here's how to create two events and add them to the calendar database. The first event is a personal appointment and doesn't include any attendees. The second event is a meeting and includes a list of attendees. Both events are saved to the default calendar on the device.

#include <bb/pim/calendar/CalendarService>
#include <bb/pim/calendar/CalendarEvent>
#include <bb/pim/calendar/Attendee>

using namespace bb::pim::calendar;
// Create the calendar service object
CalendarService calendarService;

// Create the calendar events
CalendarEvent firstEvent;
CalendarEvent secondEvent;

// Retrieve the IDs of the default calendar on the device
QPair<AccountId, FolderId> defaultCalendar =
    calendarService.defaultCalendarFolder();

// Specify information for the first event
firstEvent.setStartTime(QDateTime(2012, 11, 30, 14, 0, 0));
firstEvent.setEndTime(QDateTime(2012, 11, 30, 15, 0, 0));
firstEvent.setSensitivity(Sensitivity::Personal);
firstEvent.setAccountId(defaultCalendar.first);
firstEvent.setFolderId(defaultCalendar.second);
firstEvent.setSubject("Doctor's appointment");

// Create the attendees for the second event
Attendee firstAttendee;
Attendee secondAttendee;

firstAttendee.setName("Wes Barichak");
firstAttendee.setRole(AttendeeRole::ReqParticipant);

secondAttendee.setName("Karla Tetzel");
secondAttendee.setRole(AttendeeRole::OptParticipant);

// Add the attendees to the second event, and specify other
// information for the event
secondEvent.setStartTime(QDateTime(2012, 11, 30, 10, 0, 0));
secondEvent.setEndTime(QDateTime(2012, 11, 30, 11, 0, 0));
secondEvent.setSensitivity(Sensitivity::Confidential);
secondEvent.setAccountId(defaultCalendar.first);
secondEvent.setFolderId(defaultCalendar.second);
secondEvent.setSubject("Meeting with stakeholders");
secondEvent.setAttendees(QList<Attendee>(firstAttendee,
                                         secondAttendee));

// Add the events to the database
calendarService.createEvent(firstEvent);
calendarService.createEvent(secondEvent);

To update the value of an existing event in the database, you need to retrieve the event that you want to update by calling CalendarService::event(). You can also retrieve multiple events by calling CalendarService::events(). Then, you update the properties of the event and call CalendarService::updateEvent() to save the updated event in the database.

Not applicable

Here's how to update the value of an existing event in the database:

#include <bb/pim/calendar/CalendarService>
#include <bb/pim/calendar/Result>
#include <bb/pim/calendar/CalendarEvent>

using namespace bb::pim::calendar;
// Create the calendar service object
CalendarService calendarService;

// Retrieve the IDs of the default calendar on the device
QPair<AccountId, FolderId> defaultCalendar =
    calendarService.defaultCalendarFolder();

// Retrieve the event that you want to update from the database
Result result;
CalendarEvent eventToUpdate = calendarService.event(
                                  defaultCalendar.first,
                                  123, result);

// If the existing event was retrieved successfully, update the
// event information
if (result == Result::Success) {
    eventToUpdate.setStartTime(QDateTime(2012, 11, 30, 16, 0,
                                         0));
    eventToUpdate.setEndTime(QDateTime(2012, 11, 30, 17, 0, 0));
    calendarService.updateEvent(eventToUpdate);
}

Retrieving event information

You can use the CalendarService class to retrieve events from the calendar database. There are several different ways that you can retrieve events, depending on the type of event information and number of events that you're looking for. Several common ways are listed below. For a full list, see the API reference for the CalendarService class.

Retrieve a single event

To retrieve a single event, you can call CalendarService::event() and specify the account ID and event ID of the event that you want.

Not applicable

#include <bb/pim/calendar/CalendarService>

using namespace bb::pim::calendar;
CalendarService calendarService;
calendarService.event(myAccountId, myEventId);

This approach can be effective if you know the exact account ID and event ID of the event you want to retrieve. For example, your app might display a list of events and let users select and update a specific event by tapping on it. If you store the account ID and event ID of each event in your list's data model, you can use them to retrieve the event from the calendar database when a user taps an event in the list.

Retrieve events using search criteria

You might want to retrieve a list of all events that fit a certain set of criteria (for example, events that start or end within a certain time period). You can use an EventSearchParameters object to specify the event criteria that you want to search for. Then, you can call CalendarService::events() and provide the EventSearchParameters object as a parameter.

Not applicable

Here's how to retrieve a list of events that start or end between 9:00 AM and 5:00 PM on a specific date, and that start with the text "Cascades" in the subject or location fields.

#include <bb/pim/calendar/CalendarService>
#include <bb/pim/calendar/EventSearchParameters>
#include <bb/pim/calendar/CalendarEvent>

using namespace bb::pim::calendar;
CalendarService calendarService;
EventSearchParameters criteria;

criteria.setStart(QDateTime(2012, 11, 30, 9, 0, 0));
criteria.setEnd(QDateTime(2012, 11, 30, 5, 0, 0));
criteria.setPrefix("Cascades");

QList<CalendarEvent> events = calendarService.events(criteria);

Retrieve events that have attendees in common

You can retrieve events that the current user has in common with another person (that is, events that both the current user and the specified person are participating in). This approach can be useful if you want to determine which events the user attends with a specific person, such as a work colleague or personal friend. You can use an AnalyticsParams object to specify the email addresses of attendees that participate in the same events as the current user.

Not applicable

Here's how to retrieve a list of the nearest future events that the current user has in common with another person. An AnalyticsParams object accepts a map of keys and email addresses. In this example, a single email address is associated with the "work" key in the map.

#include <bb/pim/calendar/CalendarService>
#include <bb/pim/calendar/AnalyticsParams>
#include <bb/pim/calendar/CalendarEvent>

using namespace bb::pim::calendar;
CalendarService calendarService;
AnalyticsParams params;
QMap<QString, QVariant> map;

QList<QString> workEmails;
workEmails.insert("marco.cacciacarro@example.com");
map.insert("work", workEmails);

params.setEmails(map);

QMap<QString, QList<CalendarEvent> > resultMap =
    calendarService.nextEvents(params);
QList<CalendarEvent> workEvents = resultMap.value("work");

Using different attendee types

There are three different classes that represent event attendees. Each class represents a different type of attendee and contains information that's applicable to that type.

This class represents a simple attendee. It includes attendee information such as attendee type, name, email address, and so on. You can retrieve Attendee objects by calling CalendarEvent::attendees(). This function returns a list of Attendee objects, each of which corresponds to a participant of the event.

In your apps, when you create an attendee to add to a CalendarEvent, you typically use an Attendee object. Similarly, when you want to update an attendee in a specific event, or delete an attendee from an event, you use an Attendee object.

This class represents an attendee that's associated with a particular event. This class is similar to the Attendee class, but an AttendeeInEvents object contains information that specifies what events that attendee participates in. You can use functions such as AttendeeInEvents::events() and AttendeeInEvents::addEvent() to retrieve and manipulate the events that this attendee participates in.

You don't retrieve AttendeeInEvents objects from CalendarEvent objects, as you do with Attendee objects. Instead, you can call CalendarService::attendees() to retrieve a list of AttendeeInEvent objects. You might use this approach to get a list of people who all participate in events that you specify.

This class represents an attendee that's common between the current user and a specified person or list of people. A CommonAttendee object includes information such as the actual attendee data (represented by an Attendee object), and statistics for the common attendee, such as the number of events in common and the date of the most recent event.

You can call CalendarService::commonAttendees() to retrieve a list of people that have attended events with both the current user and the specified person or list of people.

Parsing iCalendar files

The Calendar API supports the use of iCalendar files to create events. iCalendar is a common format that's used to represent calendar events and tasks. If you want to support iCalendar files in your apps, you can use the CalendarService to parse these types of files and add the data to the calendar database.

You can call CalendarService::parseICalendarData() to parse an iCalendar file, which you specify using a file path. This function returns a CalendarEvent object that includes the data from the iCalendar file, and you can add this object to the database using the CalendarService. Alternatively, you can call CalendarService::parseICalendarFile() to parse multiple calendar events that are present in the same iCalendar file. This function returns an ICalendarObjects object that includes a list of CalendarEvent objects.

Not applicable

Here's how to retrieve calendar events from an iCalendar file called business.ics, which is included in the assets folder of the app's project. The events are retrieved using parseICalendarFile() and a Label is created with the subject of each event. Each Label is then added to a Container, ready to be displayed in an app.

#include <bb/pim/calendar/CalendarService>
#include <bb/pim/calendar/ICalendarObjects>
#include <bb/pim/calendar/CalendarEvent>

using namespace bb::pim::calendar;
// Create Calendar service object
CalendarService calendarService;

// Retrieve default calendar account ID
QPair<AccountId, FolderId> defaultCalendar =
    calendarService.defaultCalendarFolder();

// Copy the iCal file from the assets directory to the shared
// directory
QString filePath = QDir::currentPath() +
                   "/app/native/assets/business.ics";
QString newPath = "/accounts/1000/shared/misc/business.ics";
qDebug() << "Result of copy: " << QFile::copy(filePath,
                                              newPath);

// Parse the iCal file in the shared directory
ICalendarObjects iCalObjects =
    calendarService.parseICalendarFile(defaultCalendar.first,
                                       1, newPath,
                                       "application/ics");

// Get events from the parsed iCal file
QList<CalendarEvent> events = iCalObjects.events();

// Iterate through the events, create a label for each, and
// add the label to a container to display
Container *container = new Container;
Label *labels[events.size()];

QList<CalendarEvent>::iterator i;
int count = 0;
for (i = events.begin(); i != events.end(); i++) {
    labels[count] = Label::create(i->subject());
    container->add(labels[count]);
    count++;
}

The CalendarService, as well as other personal information management APIs such as the ContactService and NotebookService, doesn't have the file system permissions that are required to read a file directly from the assets folder in an app. To work around this limitation, the code sample above copies the business.ics file to the shared directory on the device and then accesses it from there. If you choose to use a similar approach in your own app, remember to add the access_shared permission in your bar-descriptor.xml file. For more information about the file system, see Working with the file system.

Last modified: 2014-09-30



Got questions about leaving a comment? Get answers from our Disqus FAQ.

comments powered by Disqus