add_2_calendar_plus

A Flutter plugin to add, update, retrieve, and delete events on each platform's default calendar.

Forked from add_2_calendar_new.

Installation

Add to your pubspec.yaml:

dependencies:
  add_2_calendar_plus: ^1.0.0

Android integration

The plugin doesn't need any special permissions to add events via the default calendar app. To add events silently (without launching the calendar app), add these permissions to your AndroidManifest.xml:

<uses-permission android:name="android.permission.WRITE_CALENDAR" />
<uses-permission android:name="android.permission.READ_CALENDAR" />

Starting from API 30, Android requires package visibility configuration. Add a <queries> element as a child of the root element in your AndroidManifest.xml:

<queries>
  <intent>
    <action android:name="android.intent.action.INSERT" />
    <data android:mimeType="vnd.android.cursor.item/event" />
  </intent>
</queries>

iOS integration

Add the following to your Info.plist:

<key>NSCalendarsUsageDescription</key>
<string>INSERT_REASON_HERE</string>

NSContactsUsageDescription is required for location autocomplete once Apple's UI is opened — the app may crash without it:

<key>NSContactsUsageDescription</key>
<string>INSERT_REASON_HERE</string>

Usage

import 'package:add_2_calendar_plus/add_2_calendar_plus.dart';

Add an event

Returns the saved Event with its native calendar id populated, or null on failure.

final Event event = Event(
  title: 'Event title',
  description: 'Event description',
  location: 'Event location',
  startDate: DateTime(2024, 6, 1, 10, 0),
  endDate: DateTime(2024, 6, 1, 11, 0),
  timeZone: 'Asia/Singapore',   // optional
  allDay: false,                // optional, defaults to false
  iosParams: IOSParams(
    reminder: Duration(hours: 1), // alarm before the event (iOS only)
    url: 'https://www.example.com', // URL attached to the event (iOS only)
  ),
  androidParams: AndroidParams(
    emailInvites: ['guest@example.com'], // invite emails (Android only)
  ),
);

final Event? savedEvent = await Add2Calendar.addEvent2Cal(event);
// savedEvent.id holds the native calendar event ID

Update an event

event.id must be set (obtained from a previous addEvent2Cal call). Returns the updated Event or null on failure.

final Event? updatedEvent = await Add2Calendar.updateEvent(
  savedEvent.copyWith(title: 'New title'),
);

Retrieve an event

Returns the Event if found, or null if it no longer exists.

final Event? event = await Add2Calendar.getEvent(savedEvent.id!);

Delete an event

Returns true on success, false otherwise.

final bool deleted = await Add2Calendar.deleteEvent(savedEvent.id!);

Recurring events

Add recurrence to an event by specifying a Recurrence. Use either ocurrences or endDate — not both.

Supported frequencies: daily, weekly, monthly, yearly.

Event(
  // ...
  recurrence: Recurrence(
    frequency: Frequency.weekly,
    interval: 2,       // every 2 weeks
    ocurrences: 10,    // end after 10 occurrences (mutually exclusive with endDate)
    // endDate: DateTime(2025, 1, 1), // or end on a specific date
  ),
);

Android also supports custom RRULE strings (RFC 5545):

Recurrence(
  frequency: Frequency.weekly,
  rRule: 'FREQ=WEEKLY;BYDAY=MO,WE,FR', // Android only
)

iOS language support

By default the iOS calendar screen appears in English. To support additional languages, add them to your Info.plist:

<key>CFBundleLocalizations</key>
<array>
  <string>en</string>
  <string>es</string>
  <string>ja</string>
</array>

Example

See the example/ folder for a runnable demo.