更新记录
1.1.0(2026-02-03)
- 新增 Android 平台支持
- 使用 Android CalendarContract API 实现日历提醒功能
- 自动请求日历读写权限
- 统一 iOS 和 Android 返回数据格式
平台兼容性
uni-app(4.84)
| Vue2 | Vue3 | Chrome | Safari | app-vue | app-nvue | Android | iOS | 鸿蒙 |
|---|---|---|---|---|---|---|---|---|
| × | × | × | × | × | × | 5.0 | 12 | × |
| 微信小程序 | 支付宝小程序 | 抖音小程序 | 百度小程序 | 快手小程序 | 京东小程序 | 鸿蒙元服务 | QQ小程序 | 飞书小程序 | 小红书小程序 | 快应用-华为 | 快应用-联盟 |
|---|---|---|---|---|---|---|---|---|---|---|---|
| × | × | × | × | × | × | × | × | × | - | × | × |
uni-app x(4.84)
| Chrome | Safari | Android | iOS | 鸿蒙 | 微信小程序 |
|---|---|---|---|---|---|
| × | × | 5.0 | 12 | × | × |
jun-calendar-event
uni-app 系统日历提醒插件 - 支持 iOS & Android 双平台
一个功能完善的 UTS 插件,用于在 uni-app 应用中调用系统原生日历功能,支持创建、查询、删除日历提醒事件。
✨ 功能特性
- ✅ 双平台支持: iOS 和 Android 原生实现
- ✅ 完整功能: 创建、查询、删除日历事件
- ✅ 重复提醒: 支持每周重复规则
- ✅ 多时间提醒: 可设置多个提醒时间点
- ✅ 全天事件: 支持全天事件类型
- ✅ 权限管理: 自动请求和处理日历权限
- ✅ 时区适配: 自动使用设备当前时区
📱 平台实现
| 平台 | 实现方式 | 最低版本 | 状态 |
|---|---|---|---|
| iOS | EventKit Framework | iOS 9.0+ | ✅ 已支持 |
| Android | CalendarContract API | Android 5.0+ (API 21) | ✅ 已支持 |
🚀 快速开始
1. 安装插件
将插件导入到项目的 uni_modules 目录下,或通过 HBuilderX 插件市场导入。
2. 导入使用
import {
createEventCalendar,
removeEventCalendar,
getEventCalendar,
removeAllEventCalendar,
} from "@/uni_modules/jun-calendar-event";
3. 创建日历提醒
createEventCalendar({
title: "团队会议",
notes: "讨论项目进度",
startDate: "2024-12-25 10:00:00",
endDate: "2024-12-25 12:00:00",
alarmOffset: [-60 * 15], // 提前15分钟提醒
isAllDay: false,
weeks: [], // 不重复
success: (res) => {
console.log("创建成功,事件ID:", res.eventId);
uni.showToast({ title: "提醒已创建", icon: "success" });
},
fail: (err) => {
console.log("创建失败:", err.message);
uni.showToast({ title: "创建失败", icon: "none" });
},
});
4. 查询日历提醒
getEventCalendar((eventsJson) => {
const events = JSON.parse(eventsJson);
console.log("查询到的事件:", events);
// events 是一个数组,包含所有日历事件
});
5. 删除日历提醒
removeEventCalendar({
idfer: "event_id_here", // 从查询结果中获取的事件ID
success: (res) => {
console.log("删除成功");
uni.showToast({ title: "已删除", icon: "success" });
},
fail: (err) => {
console.log("删除失败:", err.message);
},
});
📖 API 文档
createEventCalendar(options)
创建日历提醒事件
参数说明
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
| title | String | 是 | 日历事件标题 |
| notes | String | 是 | 日历事件备注/描述 |
| startDate | String | 是 | 开始时间,格式:yyyy-MM-dd HH:mm:ss |
| endDate | String | 是 | 结束时间,格式:yyyy-MM-dd HH:mm:ss |
| alarmOffset | Array\<Number> | 是 | 提醒时间数组,单位:秒,负数表示提前。例如:[-60*15] 表示提前 15 分钟 |
| isAllDay | Boolean | 是 | 是否为全天事件 |
| weeks | Array\<Number> | 是 | 重复规则,[0,1,2,3,4,5,6] 分别代表周日到周六,空数组表示不重复 |
| success | Function | 否 | 成功回调,参数:{ eventId: string } |
| fail | Function | 否 | 失败回调,参数:{ message: string } |
示例
// 创建每周一、三、五的健身提醒
createEventCalendar({
title: "健身训练",
notes: "记得带运动装备",
startDate: "2024-12-23 18:00:00",
endDate: "2024-12-23 20:00:00",
alarmOffset: [-60 * 30, -60 * 10], // 提前30分钟和10分钟提醒
isAllDay: false,
weeks: [1, 3, 5], // 周一、周三、周五
success: (res) => console.log("创建成功", res.eventId),
fail: (err) => console.log("创建失败", err.message),
});
// 创建全天生日提醒
createEventCalendar({
title: "小明生日",
notes: "记得准备礼物",
startDate: "2024-12-25 00:00:00",
endDate: "2024-12-25 23:59:59",
alarmOffset: [-60 * 60 * 24 * 7, -60 * 60 * 24], // 提前7天和1天
isAllDay: true,
weeks: [],
success: (res) => console.log("创建成功"),
fail: (err) => console.log("创建失败"),
});
getEventCalendar(callback)
查询日历提醒列表(查询当前时间到未来一年内的事件)
参数说明
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
| callback | Function | 是 | 回调函数,参数为 JSON 字符串 |
返回数据格式
[
{
eventId: "事件唯一标识",
title: "事件标题",
notes: "事件备注",
startDate: "2024-12-25 10:00:00",
endDate: "2024-12-25 12:00:00",
rules: [1, 3, 5], // 重复规则,空数组表示不重复
},
];
示例
getEventCalendar((eventsJson) => {
const events = JSON.parse(eventsJson);
console.log("查询到 " + events.length + " 个事件");
events.forEach((event) => {
console.log("标题:", event.title);
console.log("开始时间:", event.startDate);
console.log("重复规则:", event.rules);
});
});
removeEventCalendar(options)
删除指定的日历提醒
参数说明
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
| idfer | String | 是 | 事件 ID(从查询结果中获取) |
| success | Function | 否 | 成功回调,参数:{ message: string } |
| fail | Function | 否 | 失败回调,参数:{ message: string } |
示例
removeEventCalendar({
idfer: "BDAF720F-E341-46F8-851F-FE7F5A5DFD10",
success: (res) => {
console.log("删除成功");
uni.showToast({ title: "已删除", icon: "success" });
},
fail: (err) => {
console.log("删除失败:", err.message);
uni.showToast({ title: "删除失败", icon: "none" });
},
});
removeAllEventCalendar(options)
删除指定时间段内的所有日历提醒
参数说明
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
| startDate | String | 是 | 开始时间,格式:yyyy-MM-dd HH:mm:ss |
| endDate | String | 是 | 结束时间,格式:yyyy-MM-dd HH:mm:ss |
| success | Function | 否 | 成功回调 |
| fail | Function | 否 | 失败回调 |
示例
// 删除2024年12月的所有提醒
removeAllEventCalendar({
startDate: "2024-12-01 00:00:00",
endDate: "2024-12-31 23:59:59",
success: (res) => console.log("批量删除成功"),
fail: (err) => console.log("删除失败"),
});
💡 完整示例
<template>
<view class="container">
<view class="header">
<text class="title">日历提醒管理</text>
</view>
<view class="actions">
<button @click="createReminder" type="primary">创建提醒</button>
<button @click="loadReminders" type="default">刷新列表</button>
</view>
<view class="list">
<view v-for="item in reminderList" :key="item.eventId" class="list-item">
<view class="item-title">{{ item.title }}</view>
<view class="item-time">{{ item.startDate }}</view>
<view class="item-notes">{{ item.notes }}</view>
<button @click="deleteReminder(item.eventId)" size="mini" type="warn">
删除
</button>
</view>
</view>
<view v-if="reminderList.length === 0" class="empty">
<text>暂无日历提醒</text>
</view>
</view>
</template>
<script>
import {
createEventCalendar,
removeEventCalendar,
getEventCalendar,
} from "@/uni_modules/jun-calendar-event";
export default {
data() {
return {
reminderList: [],
};
},
onLoad() {
this.loadReminders();
},
methods: {
// 创建提醒
createReminder() {
const tomorrow = new Date();
tomorrow.setDate(tomorrow.getDate() + 1);
tomorrow.setHours(10, 0, 0, 0);
const start = this.formatDate(tomorrow);
tomorrow.setHours(12, 0, 0, 0);
const end = this.formatDate(tomorrow);
createEventCalendar({
title: `会议提醒_${Math.floor(Math.random() * 100)}`,
notes: "这是一个测试提醒",
startDate: start,
endDate: end,
alarmOffset: [-60 * 15], // 提前15分钟
isAllDay: false,
weeks: [],
success: (res) => {
uni.showToast({ title: "创建成功", icon: "success" });
this.loadReminders();
},
fail: (err) => {
uni.showToast({
title: "创建失败: " + err.message,
icon: "none",
});
},
});
},
// 加载提醒列表
loadReminders() {
getEventCalendar((data) => {
this.reminderList = JSON.parse(data);
});
},
// 删除提醒
deleteReminder(eventId) {
removeEventCalendar({
idfer: eventId,
success: () => {
uni.showToast({ title: "删除成功", icon: "success" });
this.loadReminders();
},
fail: (err) => {
uni.showToast({
title: "删除失败: " + err.message,
icon: "none",
});
},
});
},
// 格式化日期
formatDate(date) {
const pad = (n) => String(n).padStart(2, "0");
return `${date.getFullYear()}-${pad(date.getMonth() + 1)}-${pad(
date.getDate()
)} ${pad(date.getHours())}:${pad(date.getMinutes())}:${pad(
date.getSeconds()
)}`;
},
},
};
</script>
<style scoped>
.container {
padding: 20rpx;
background-color: #f5f5f5;
min-height: 100vh;
}
.header {
text-align: center;
padding: 20rpx;
}
.title {
font-size: 36rpx;
font-weight: bold;
}
.actions {
padding: 20rpx 0;
}
.actions button {
margin: 10rpx 0;
}
.list {
margin-top: 20rpx;
}
.list-item {
background-color: white;
padding: 20rpx;
margin-bottom: 20rpx;
border-radius: 10rpx;
}
.item-title {
font-size: 32rpx;
font-weight: bold;
margin-bottom: 10rpx;
}
.item-time {
font-size: 28rpx;
color: #666;
margin-bottom: 10rpx;
}
.item-notes {
font-size: 26rpx;
color: #999;
margin-bottom: 10rpx;
}
.empty {
text-align: center;
color: #999;
margin-top: 100rpx;
}
</style>
⚠️ 注意事项
1. 自定义基座
UTS 插件必须使用自定义基座进行测试和运行
在 HBuilderX 中:
- 点击
运行->运行到手机或模拟器->制作自定义调试基座 - 等待云端打包完成
- 使用自定义基座运行项目
2. 日期格式
日期时间必须严格遵守格式:yyyy-MM-dd HH:mm:ss
✅ 正确:2024-12-25 10:00:00
❌ 错误:2024/12/25 10:00:00
❌ 错误:2024-12-25
3. 提醒时间
alarmOffset 参数说明:
- 单位:秒
- 负数表示提前,正数表示延后
- 示例:
-60 * 15= 提前 15 分钟-60 * 60= 提前 1 小时-60 * 60 * 24= 提前 1 天
4. 重复规则
weeks 参数说明:
[]- 不重复[0]- 每周日[1]- 每周一[1, 3, 5]- 每周一、三、五[0, 1, 2, 3, 4, 5, 6]- 每天
5. 权限处理
- iOS: 首次使用会弹出系统权限请求对话框
- Android: 自动请求日历读写权限,用户拒绝后可引导到设置页面
将额外权限加入到 manifest.json 》app-plus 》 distribute 》 android 》 permissions
<uses-permission android:name="android.permission.WRITE_SETTINGS"/>
<uses-permission android:name="android.permission.RECEIVE_USER_PRESENT"/>
6. 错误处理
常见错误及解决方案:
| 错误信息 | 原因 | 解决方案 |
|---|---|---|
repeat |
相同时间已存在事件 | 修改时间或删除旧事件 |
需要日历权限 |
用户未授权 | 引导用户到设置中开启权限 |
创建事件失败 |
系统错误 | 检查日期格式和参数 |
🔍 常见问题
Q: 为什么创建失败?
A: 请检查:
- 是否使用了自定义基座
- 日期格式是否正确
- 是否授予了日历权限
Q: 查询不到刚创建的事件?
A: 查询范围是当前时间到未来一年,如果事件时间已过,则不会显示。
Q: 如何在系统日历中查看?
A:
- iOS: 打开系统"日历"应用
- Android: 打开"日历"或"Google 日历"应用
Q: 删除后系统日历还能看到?
A: 可能是缓存问题,重启日历应用或等待几秒刷新。
📚 相关文档
📝 更新日志
v1.1.0 (2024-12-20)
- ✨ 新增 Android 平台完整支持
- 🔧 统一 iOS 和 Android 数据格式
- 📝 完善文档和示例
- 🐛 修复已知问题
v1.0.0 (2024-07-04)
- 🎉 首次发布
- ✅ iOS 平台支持
📄 许可证
MIT License
💬 技术支持
如有问题或建议,欢迎反馈。
开发愉快! 🎉

收藏人数:
购买源码授权版(
试用
赞赏(0)
下载 0
赞赏 0
下载 11210899
赞赏 1855
赞赏
京公网安备:11010802035340号