PhoneGap Calendar plugin
for iOS and Android, by Eddy Verbruggen
Every now and then kind folks ask me how they can give me all their money.
Of course I'm happy to receive any amount but I'm just as happy if you simply 'star' this project.
| For a quick demo app and easy code samples, check out the plugin page at the Verified Plugins Marketplace: http://plugins.telerik.com/plugin/calendar |
- Description
- Installation
2. Automatically
2. Manually
2. PhoneGap Build
- Usage
- Promises
- Credits
- License
1. Description
This plugin allows you to add events to the Calendar of the mobile device.
iOS specifics
- Supported methods:
find
, create
, modify
, delete
, .. - All methods work without showing the native calendar. Your app never loses control.
- Tested on iOS 6+.
- On iOS 10+ you need to provide a reason to the user for Calendar access. This plugin adds an empty
NSCalendarsUsageDescription
key to the /platforms/ios/*-Info.plist file which you can override with your custom string. To do so, pass the following variable when installing the plugin:
cordova plugin add cordova-plugin-calendar --variable CALENDAR_USAGE_DESCRIPTION="This app uses your calendar"
Android specifics
- Supported methods on Android 4:
find
, create
(silent and interactive), delete
, .. - Supported methods on Android 2 and 3:
create
interactive only: the user is presented a prefilled Calendar event. Pressing the hardware back button will give control back to your app.
Windows 10 Mobile
- Supported methods:
createEvent
, createEventWithOptions
, createEventInteractively
, createEventInteractivelyWithOptions
only interactively
2. Installation
Automatically
Latest release on npm:
$ cordova plugin add cordova-plugin-calendar
Bleeding edge, from github:
$ cordova plugin add https://github.com/EddyVerbruggen/Calendar-PhoneGap-Plugin.git
Manually
iOS
1. Add the following xml to your config.xml
:
<feature name="Calendar">
<param name="ios-package" value="Calendar" />
</feature>
2. Grab a copy of Calendar.js, add it to your project and reference it in index.html
:
<script type="text/javascript" src="js/Calendar.js"></script>
3. Download the source files for iOS and copy them to your project.
Copy Calendar.h
and Calendar.m
to platforms/ios/<ProjectName>/Plugins
4. Click your project in XCode, Build Phases, Link Binary With Libraries, search for and add EventKit.framework
and EventKitUI.framework
.
Android
1. Add the following xml to your config.xml
:
<feature name="Calendar">
<param name="android-package" value="nl.xservices.plugins.Calendar" />
</feature>
2. Grab a copy of Calendar.js, add it to your project and reference it in index.html
:
<script type="text/javascript" src="js/Calendar.js"></script>
3. Download the source files for Android and copy them to your project.
Android: Copy Calendar.java
to platforms/android/src/nl/xservices/plugins
(create the folders/packages).
Then create a package called accessor
and copy other 3 java Classes into it.
4. Add these permissions to your AndroidManifest.xml:
<uses-permission android:name="android.permission.READ_CALENDAR"/>
<uses-permission android:name="android.permission.WRITE_CALENDAR"/>
Note that if you don't want your app to ask for these permissions, you can leave them out, but you'll only be able to
use one function of this plugin: createEventInteractively
.
PhoneGap Build
Add the following xml to your config.xml
to always use the latest npm version of this plugin:
<plugin name="cordova-plugin-calendar" />
Also, make sure you're building with Gradle by adding this to your config.xml
file:
<preference name="android-build-tool" value="gradle" />
3. Usage
The table gives an overview of basic operation compatibility:
Operation | Comment | iOS | Android | Windows |
---|
createCalendar | | yes | yes | |
deleteCalendar | | yes | yes | |
createEvent | silent | yes | yes * | yes ** |
createEventWithOptions | silent | yes | yes * | yes ** |
createEventInteractively | interactive | yes | yes | yes ** |
createEventInteractivelyWithOptions | interactive | yes | yes | yes ** |
findEvent | | yes | yes | |
findEventWithOptions | | yes | yes | |
listEventsInRange | | | yes | |
listCalendars | | yes | yes | |
findAllEventsInNamedCalendars | | yes | | |
modifyEvent | | yes | | |
modifyEventWithOptions | | yes | | |
deleteEvent | | yes | yes | |
deleteEventFromNamedCalendar | | yes | | |
openCalendar | | yes | yes | |
- * on Android < 4 dialog is shown
- ** only interactively on windows mobile
Basic operations, you'll want to copy-paste this for testing purposes:
var startDate = new Date(2015,2,15,18,30,0,0,0);
var endDate = new Date(2015,2,15,19,30,0,0,0);
var title = "My nice event";
var eventLocation = "Home";
var notes = "Some notes about this event.";
var success = function(message) { alert("Success: " + JSON.stringify(message)); };
var error = function(message) { alert("Error: " + message); };
window.plugins.calendar.createCalendar(calendarName,success,error);
var createCalOptions = window.plugins.calendar.getCreateCalendarOptions();
createCalOptions.calendarName = "My Cal Name";
createCalOptions.calendarColor = "#FF0000";
window.plugins.calendar.createCalendar(createCalOptions,success,error);
window.plugins.calendar.deleteCalendar(calendarName,success,error);
window.plugins.calendar.createEvent(title,eventLocation,notes,startDate,endDate,success,error);
var calOptions = window.plugins.calendar.getCalendarOptions();
calOptions.firstReminderMinutes = 120;
calOptions.secondReminderMinutes = 5;
calOptions.recurrence = "monthly";
calOptions.recurrenceEndDate = new Date(2016,10,1,0,0,0,0,0);
calOptions.calendarName = "MyCreatedCalendar";
calOptions.calendarId = 1;
calOptions.recurrenceInterval = 2;
calOptions.url = "https://www.google.com";
window.plugins.calendar.createEventWithOptions(title,eventLocation,notes,startDate,endDate,calOptions,success,error);
window.plugins.calendar.createEventInteractively(title,eventLocation,notes,startDate,endDate,success,error);
window.plugins.calendar.createEventInteractivelyWithOptions(title,eventLocation,notes,startDate,endDate,calOptions,success,error);
window.plugins.calendar.createEventInNamedCalendar(title,eventLocation,notes,startDate,endDate,calendarName,success,error);
window.plugins.calendar.findEvent(title,eventLocation,notes,startDate,endDate,success,error);
var calOptions = window.plugins.calendar.getCalendarOptions();
calOptions.calendarName = "MyCreatedCalendar";
calOptions.id = "D9B1D85E-1182-458D-B110-4425F17819F1";
window.plugins.calendar.findEventWithOptions(title,eventLocation,notes,startDate,endDate,calOptions,success,error);
window.plugins.calendar.listEventsInRange(startDate,endDate,success,error);
window.plugins.calendar.listCalendars(success,error);
window.plugins.calendar.findAllEventsInNamedCalendar(calendarName,success,error);
var newTitle = "New title!";
window.plugins.calendar.modifyEvent(title,eventLocation,notes,startDate,endDate,newTitle,eventLocation,notes,startDate,endDate,success,error);
var filterOptions = window.plugins.calendar.getCalendarOptions();
filterOptions.calendarName = "Bla";
filterOptions.id = "D9B1D85E-1182-458D-B110-4425F17819F1";
var newOptions = window.plugins.calendar.getCalendarOptions();
newOptions.calendaName = "New Bla";
newOptions.firstReminderMinutes = 120;
window.plugins.calendar.modifyEventWithOptions(title,eventLocation,notes,startDate,endDate,newTitle,eventLocation,notes,startDate,endDate,filterOptions,newOptions,success,error);
window.plugins.calendar.deleteEvent(newTitle,eventLocation,notes,startDate,endDate,success,error);
window.plugins.calendar.deleteEventFromNamedCalendar(newTitle,eventLocation,notes,startDate,endDate,calendarName,success,error);
window.plugins.calendar.openCalendar();
var d = new Date(new Date().getTime() + 3*24*60*60*1000);
window.plugins.calendar.openCalendar(d, success, error);
Creating an all day event:
var startDate = new Date(2014,2,15,0,0,0,0,0);
var endDate = new Date(2014,2,16,0,0,0,0,0);
Creating an event for 3 full days
var startDate = new Date(2014,2,24,0,0,0,0,0);
var endDate = new Date(2014,2,27,0,0,0,0,0);
Example Response IOS getCalendarOptions
{
calendarId: null,
calendarName: "calendar",
firstReminderMinutes: 60,
recurrence: null,
recurrenceEndDate: null,
recurrenceInterval: 1,
secondReminderMinutes: null,
url: null
}
Exmaple Response IOS Calendars
{
id: "258B0D99-394C-4189-9250-9488F75B399D",
name: "standard calendar",
type: "Local"
}
Exmaple Response IOS Event
{
calendar: "Kalender",
endDate: "2016-06-10 23:59:59",
id: "0F9990EB-05A7-40DB-B082-424A85B59F90",
lastModifiedDate: "2016-06-13 09:14:02",
location: "",
message: "my description",
startDate: "2016-06-10 00:00:00",
title: "myEvent"
}
Android 6 (M) Permissions
On Android 6 you need to request permission to use the Calendar at runtime when targeting API level 23+.
Even if the uses-permission
tags for the Calendar are present in AndroidManifest.xml
.
Since plugin version 4.5.0 we transparently handle this for you in a just-in-time manner.
So if you call createEvent
we will pop up the permission dialog. After the user granted access
to his calendar the event will be created.
You can also manually manage and check permissions if that's your thing.
Note that the hasPermission functions will return true when:
- You're running this on iOS, or
- You're targeting an API level lower than 23, or
- You're using Android < 6, or
- You've already granted permission.
function hasReadWritePermission() {
window.plugins.calendar.hasReadWritePermission(
function(result) {
alert(result);
}
)
}
function requestReadWritePermission() {
window.plugins.calendar.requestReadWritePermission();
}
There are similar methods for Read and Write access only (hasReadPermission
, etc),
although it looks like that if you request read permission you can write as well,
so you might as well stick with the example above.
Note that backward compatibility was added by checking for read or write permission in the relevant plugins functions.
If permission is needed the plugin will now show the permission request popup.
The user will then need to allow access and invoke the same method again after doing so.
4. Promises
If you like to use promises instead of callbacks, or struggle to create a lot of
events asynchronously with this plugin then I encourage you to take a look at
this awesome wrapper for
this plugin. Kudos to John Rodney for this piece of art!
5. Credits
This plugin was enhanced for Plugman / PhoneGap Build by Eddy Verbruggen. I fixed some issues in the native code (mainly for iOS) and changed the JS-Native functions a little in order to make a universal JS API for both platforms.
6. License
The MIT License (MIT)
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.