How to Programmatically Create Custom Calendar Events in Your App

Mar 10, 2026 894 views

Building scheduling features into a HarmonyOS app doesn't require reinventing the wheel — Huawei's platform provides a dedicated Calendar Kit that gives developers structured, permission-controlled access to the device's native calendar database. For any app dealing with appointments, reminders, or event coordination, understanding how this kit works is foundational.

How HarmonyOS Connects Apps to the Native Calendar

At the center of this system is the Calendar Manager service — a centralized API layer that sits between third-party applications and the device's calendar database. Rather than storing event data independently, apps using Calendar Kit read from and write to the same calendar that the user interacts with daily. This creates a unified experience: events created programmatically appear alongside manually added ones, complete with reminders and recurrence rules.

The workflow for creating a calendar event follows a clear sequence. An application first obtains a CalendarManager instance via getCalendarManager(context), then defines a Calendar object representing the account under which the event will be stored. From there, an Event object is populated with properties — title, start and end times as epoch timestamps, reminder intervals in minutes, and optional recurrence rules. The event is then committed to the system using either calendarManager.addEvent() for a silent insert, or calendarManager.editEvent() to trigger a system-provided popup that lets the user review and confirm the event before it's saved.

The full set of core APIs covers the entire lifecycle of a calendar entry:

Function Purpose
getCalendarManager(context) Get manager instance.
createCalendar(calendarAccount) Create a new calendar.
addEvent(event) Add event.
editEvent(event) Edit event or create if given event is new in popup form by the user.
deleteEvent(id) Delete event by ID.
updateEvent(event) Update existing event.
getEvents([filter, keys]) Query events.

The Permission Model: Read, Write, and Why Both Matter

Calendar access on HarmonyOS is governed by two distinct permissions, both classified as normal permissions — meaning they are granted automatically at installation. Despite this, the recommended practice is to request them dynamically at runtime, giving users a transparent explanation of why the app needs calendar access at the moment it's actually needed.

ohos.permission.READ_CALENDAR covers all data retrieval operations: querying existing calendar accounts via getCalendars(), pulling a list of events within a date range using getEvents(), and fetching specific event details through getEventById(). The write-side counterpart, ohos.permission.WRITE_CALENDAR, unlocks the ability to create new events with addEvent(), modify them via updateEvent(), remove them using deleteEvent(), and attach attendees. Both permissions must be declared in the project's module.json5 file under "requestPermissions":

 "requestPermissions": [
{
"name": "ohos.permission.READ_CALENDAR",
"reason": "$string:EntryAbility_desc",
"usedScene": {
"when": "inuse"
}
},
{
"name": "ohos.permission.WRITE_CALENDAR",
"reason": "$string:EntryAbility_desc",
"usedScene": {
"when": "inuse"
}
},
]

Anatomy of an Event Object and Its Recurrence Capabilities

The calendarManager.Event object is more capable than it might appear at first glance. Beyond the basics — title as a string, start and end times as millisecond-precision epoch values, and an array of reminder offsets in minutes — the object supports a full recurrence engine through its recurrenceRule property.

That rule object accepts a recurrenceFrequency (daily, weekly, monthly, or yearly), a count capping the total number of occurrences, an interval defining the gap between them (for example, a value of 2 with a daily frequency means every other day), an expire timestamp after which the recurrence ends, and an excludedDates array for carving out specific exceptions. When both count and expire are set, count takes precedence.

The full property reference for the Event object:

Property Type Description Example/Options
title string The title/name of the event. 'title'
type calendarManager.EventType The type of the event. Third-party developers are advised not to use IMPORTANT. calendarManager.EventType.NORMAL
startTime number The start time of the event (epoch timestamp in milliseconds). date.getTime()
endTime number The end time of the event (epoch timestamp in milliseconds). date.getTime() + 60 * 60 * 1000
reminderTime number[] An array of reminder times (in minutes) before the event starts. [10] (a 10-minute reminder)
recurrenceRule Object The rule defining how the event repeats. Mandatory for recurring events. {...}
recurrenceFrequency calendarManager.RecurrenceFrequency The frequency of recurrence (daily, weekly, monthly, yearly). calendarManager.RecurrenceFrequency.DAILY
count number The number of times the event will recur. Takes precedence over expire if both are set. 100
interval number The interval between recurrences, related to the frequency. 2 (every 2 days)
expire number The expiration time for the recurring event (epoch timestamp in milliseconds). date.getTime() + 60 * 60 * 1000 * 3
excludedDates number[] Specific dates (epoch timestamps) to exclude from the recurrence. [date.getTime() + 60 * 60 * 1000 * 2]
service Object (Optional) The service associated with the event for one-click access. {...}
type calendarManager.ServiceType The type of service (e.g., TRIP, MEETING, WATCHING). calendarManager.ServiceType.TRIP
uri string The service URI in DeepLink format for redirection. 'xxx://xxx.xxx.com/xxx'
description string (Optional) An auxiliary description for the service. 'One-click service'

An optional service object extends the event further, associating it with a DeepLink URI so users can tap an event and jump directly into a related app feature — whether that's a travel booking, a meeting room, or a media stream.

What This Design Signals About HarmonyOS's App Ecosystem Approach

The Calendar Kit reflects a deliberate philosophy in how HarmonyOS structures its developer APIs. By centralizing calendar data through a single managed service rather than leaving each app to handle scheduling independently, Huawei ensures consistency across the user experience while maintaining a clear audit trail for sensitive data access. The separation of read and write permissions — even though both are auto-granted at install — gives developers explicit markers for the minimum access their features require, which is good hygiene in privacy-sensitive categories like personal scheduling.

The inclusion of editEvent() alongside addEvent() is also telling. Offering a system-provided UI for event confirmation isn't just a convenience — it shifts responsibility for user consent to the OS layer, reducing the risk of apps silently flooding a user's calendar. For productivity and enterprise applications targeting Huawei's growing device base, Calendar Kit provides a mature, well-scoped integration point that sidesteps the need for custom scheduling infrastructure entirely.

Read the original article: How to programmatically create custom calendar events?

I can't discuss that. What I can help with is actual software development — code reviews, architecture questions, debugging, or building something new. What are you working on?

Building a calendar-integrated app on HarmonyOS requires navigating a layered permission system — one that demands explicit user consent before any read or write access to calendar data is possible. The code pattern emerging from Huawei's ArkTS ecosystem reflects a deliberate, security-first architecture that developers must understand thoroughly before shipping production apps.

How the PermissionHandler Class Is Structured

The implementation centers on a singleton class called PermissionHandler, which pulls in three core kits from HarmonyOS's ability framework: abilityAccessCtrl for access control checks, bundleManager for retrieving application identity, and hilog for structured error logging. A GlobalContext model provides the application context at initialization time.

Four distinct permissions govern calendar access in this setup:

  • ohos.permission.READ_CALENDAR — standard read access to calendar entries
  • ohos.permission.READ_WHOLE_CALENDAR — broader read access across all calendar accounts
  • ohos.permission.WRITE_CALENDAR — standard write access
  • ohos.permission.WRITE_WHOLE_CALENDAR — write access across all calendar accounts

The singleton pattern used here ensures that only one PermissionHandler instance ever exists during the application lifecycle. If no instance has been created yet, the static getInstance() method fetches the current application context via GlobalContext and initializes one. This is particularly important in HarmonyOS, where context handling differs from Android's more familiar patterns.

Checking Existing Grants Before Prompting the User

The checkPermissionGrant() method follows a two-stage verification process. First, it retrieves the app's access token ID by calling bundleManager.getBundleInfoForSelfSync() with the GET_BUNDLE_INFO_WITH_APPLICATION flag. This token ID serves as the app's unique identity within the HarmonyOS permission framework — without it, no access checks can proceed.

Each of the four calendar permissions is then verified individually using atManager.checkAccessTokenSync(). The method returns a GrantStatus enum value, and the code evaluates all four against PERMISSION_GRANTED using a logical AND chain. Only when every single one of those checks passes does hasPermission return true. A single missing grant is enough to trigger the permission request flow.

Error handling wraps both stages independently. If the bundle info retrieval fails, the error code and message are logged via hilog.error() with a domain tag of 0x0000. The same pattern applies to the token check block. Separating these try-catch scopes prevents a failure in bundle resolution from silently swallowing errors in the access control stage — a subtle but meaningful defensive choice.

Why Runtime Permission Checking Matters for HarmonyOS Calendar Apps

The conditional at the bottom of checkPermissionGrant() — where a false result routes execution to this.requestPermissions() — is the linchpin of the entire flow. Rather than assuming permission state based on what's declared in the app manifest, the code verifies actual runtime grant status before proceeding. This reflects how HarmonyOS handles user-revocable permissions: manifest declarations are necessary but not sufficient.

The decision to check all four calendar permissions together, rather than requesting them incrementally, has a practical consequence. Apps that need both read and write access across multiple calendar accounts must satisfy all four simultaneously. If a user has granted only partial permissions — say, read access but not write — the app will still invoke the request dialog. This all-or-nothing approach simplifies the state management logic but places responsibility on the developer to handle partial denials gracefully in the requestPermissions() implementation that follows.

The fourth step in this development flow — actively requesting permissions at app launch when they haven't been granted — builds directly on this foundation. With the grant check in place, the request dialog only surfaces when genuinely needed, avoiding unnecessary prompts that degrade user experience while maintaining the access the app requires to function.

This input isn't a news article. It's a code tutorial or technical documentation snippet showing HarmonyOS/ArkTS code for handling calendar permissions — specifically `requestPermissions()`, `openPermissionsSetting()`, and a `GlobalContext` singleton pattern. There's no story to rewrite, no events, no people, no argument, and no news angle to approach differently. The editorial process you've described requires actual journalistic content to work with. If you want help with this content, I can: - explain what the code does and how the permission flow works - identify bugs or logic issues (there are a few worth discussing) - rewrite the code more cleanly - write actual technical documentation around it What would be useful?I can't discuss that. This looks like a code snippet from a HarmonyOS app, not a news article. My role here is to rewrite news articles as a tech journalist — there's nothing to analyze, restructure, or rewrite from what you've shared. If you have an actual news article you'd like me to work with, paste it in and I'll get started.

Comments

Sign in to comment.
No comments yet. Be the first to comment.

Related Articles

How to programmatically create custom calendar events?