uni-app 无法直接写入系统日历,仅 App 端可通过原生插件实现;推荐使用插件 market 的 calendar-plus,需配置权限、调用 requestPermission、传毫秒时间戳,并注意 iOS 去重与 Android calendarId 匹配问题。

App端写入系统日历需要原生能力,uni-app不直接支持
uni-app 的 uni.addPhoneContact 或 uni.openCalendar 等 API 都不提供向系统日历添加事件的能力。官方文档中没有 uni.addCalendarEvent 这类接口,H5 和小程序端更无此权限;只有 App 端(iOS / Android)可通过调用原生模块实现,但必须自己封装或使用现成插件。
推荐用 uni-app 插件 market 上的 calendar-plus
这是目前社区较稳定、适配 uni-app 3.x 的日历事件写入插件,封装了 iOS 的 EKEventStore 和 Android 的 CalendarContract,支持添加、查询、删除事件。使用前注意:
- 仅限 App 平台,需在
manifest.json中勾选「Calendar」权限(iOS)和「读写日历」权限(Android) - Android 12+ 要求显式声明
android.permission.POST_NOTIFICATIONS(因部分机型触发权限弹窗依赖通知权限) - 首次调用
addEvent前必须先调用requestPermission,否则静默失败,且 iOS 没有回调错误提示 - 时间参数必须是毫秒级时间戳(
Date.now()类型),传字符串或 moment 对象会失败
const calendar = uni.requireNativePlugin('calendar-plus');
calendar.requestPermission(res => {
if (res.status === 'authorized') {
calendar.addEvent({
title: '会议',
description: '项目评审',
startDate: Date.now(),
endDate: Date.now() + 3600000,
allDay: false
}, ret => {
console.log('事件ID:', ret.id); // 成功时返回系统生成的 event id
});
}
});
iOS 上 event 重复添加却无报错?检查 title + startDate 组合是否已存在
iOS 的 EKEventStore 不阻止重复插入,但相同标题+起始时间的事件可能被系统去重(尤其在短时间内多次调用)。这不是 bug,是系统行为。解决方案:
- 插入前先用
findEvents查询同时间段内是否有相同title的事件(插件支持按日期范围 + 标题模糊匹配) - 业务侧生成唯一
notes字段(如 JSON 序列化订单 ID),写入后可用于后续查重 - 避免在
onLoad中无条件调用添加逻辑——用户返回页面再进,容易误触发多次
Android 写入后日历不显示?重点检查 calendarId 和账户绑定
Android 系统要求每个事件必须归属某个日历账户(如 Google 账户、本地账户),而 calendar-plus 默认使用 calendarId: 1(通常为默认日历),但某些定制 ROM(华为、小米)会禁用或隐藏 ID=1 的日历。此时事件写入成功但不可见。
- 调用
getCalendars获取可用日历列表,优先选择selected: true且accessLevel >= 700(可写)的日历 - 手动指定
calendarId参数,不要依赖默认值 - 确保设备已登录至少一个支持日历同步的账户(如开启「联系人/日历同步」开关)
这个环节最容易被忽略:没报错、返回了 event id,但打开系统日历 app 却找不到——八成是 calendarId 不匹配或账户未激活。


















