search
分发文档
分发文档/应用分发/生态政策/控件适配指南/日历写入控件
日历写入控件更新时间:2025-12-26 15:34:00

一、背景

传统上,应用往日历读取或写入日程,需通过权限弹窗,向用户申请日历读取、修改权限android.permission.READ_CALENDAR、android.permission.WRITE_CALENDAR,由用户主动授权后,应用才可往日历中读取或写入日程信息。该方案存在诸多痛点,举例如下:

  • 应用仅需实现写入预约日程、读取自己写入的日程,却可通过权限读取、修改用户日历中的所有日程信息,对用户隐私带来极大困扰。
  • 应用获取权限后,可在用户不知情情况下写入频繁的日程提醒,造成用户打扰。

为解决以上问题,系统将谨慎开放日历读写权限,为有写入预约日程需求的应用提供日历写入服务,写入日程时需用户手动确认。后期将支持:应用可查询、删除自己成功写入的日程。

二、功能介绍

1. 应用场景介绍

应用需往日历写入日程时,拉起系统级的日历写入服务,并传入标题、提醒时间等参数(如图一)。在用户手动确认后,可成功往日历中写入日程,用户可在日历APP中查看(如图二),并由日历APP做后续日程提醒。

图一:

图二:

2. 日历写入服务功能介绍

利用ACTION_INSERT,您的应用可将事件插入任务转由日历应用执行。借助此方法时,您的应用甚至无需在其清单文件中加入WRITE_CALENDAR权限。

当用户运行使用此方法的应用时,该应用会跳转至日历,以便用户完成事件添加操作。

ACTION_INSERT 利用 extra 字段为表单预填充日历中事件的详细信息。然后,用户可以取消活动、根据需要修改表单或将活动保存到日历中。

三、 适用范围

适用于Andriod16及以上版本。此时若系统日历APP被卸载,将引导安装。安装完成后,用户需重新回到应用页拉起日历写入服务页面。

在Andriod16以下版本,可能存在系统日历APP被卸载且系统中无其他相关action,写入服务启动将会失败,这个时候可考虑使用权限进行兼容。

四、使用说明

以下详细说明适配日历写入服务的接口。

1. 获取Intent,并判断是否支持

val intent = Intent(Intent.ACTION_INSERT)
intent.setData(CalendarContract.Events.CONTENT_URI)
val support = intent.resolveActivity(packageManager)

2. Intent携带参数

如果不传入或传入格式异常,系统会使用自身定义的默认值。

功能Intent Extravalue类型value说明/举例是否支持开发者控制
事件名称CalendarContract.Events.TITLEString限制1000字支持
事件开始时间,以从公元纪年开始计算的毫秒数表示CalendarContract.EXTRA_EVENT_BEGIN_TIMElong举例:System.currentTimeMillis(),开始为当前时间支持
事件结束时间,以从公元纪年开始计算的毫秒数表示CalendarContract.EXTRA_EVENT_END_TIMElongSystem.currentTimeMillis()支持
事件是否属于全天事件CalendarContract.EXTRA_EVENT_ALL_DAYboolean举例:true或false支持
事件描述CalendarContract.Events.DESCRIPTIONString限制1000字支持
事件的重复规则CalendarContract.Events.RRULEString举例:FREQ=DAILY;COUNT=10;表示每天发生一次,重复10次; 详细内容参考下发重复规则详情。支持
事件颜色CalendarContract.Events.EVENT_COLOR--暂不支持
事件的地点CalendarContract.Events.EVENT_LOCATION--暂不支持
日历账户---暂不支持
提醒时间---暂不支持
是否闹钟提醒---暂不支持
  • 重复规则详情
参数释义
FREQ重复规则的类型, 是重复规则中必须定义的一条属性。FREQ=DAILY 表示以天为间隔单位进行重复;FREQ=WEEKLY 表示以周为间隔单位进行重复;FREQ=MONTHLY 表示以月为间隔单位进行重复;FREQ=YEARLY 表示以年为间隔单位进行重复。
INTERVAL表示重复规则的间隔, 必须为正整数。 默认值为1。对应不同的FREQ就是如每一天, 每一周。
UNTIL定义了一个日期-时间值,用以限制重复规则。这个日期-时间值表示这个重复规则的最后一次事件的发生时间。
COUNT定义重复事件的发生次数来限制重复规则
BYSECOND取值范围 0 - 59
BYMINUTE取值范围 0 - 59
BYHOUR取值范围 0 - 23
BYWEEKNO取值范围 1 - 53 或者 -53 - -1, 表示一年的第几周。
BYMONTY取值范围 1 - 12, 表示一年的第几个月。
WKST取值范围 MO, TU, WE, TH, FR, SA, SU。 默认值为 MO。
BYSETPOS取值范围 1 - 366 或者 -366 - -1, 表示规则指定的事件集合中的第n个事件。
更多详细参数https://datatracker.ietf.org/doc/html/rfc5545

常见重复规则举例:

  • 每天重复:FREQ=DAILY;INTERVAL=1;
  • 每周当天重复:FREQ=WEEKLY;INTERVAL=1;
  • 每月当天重复:FREQ=MONTHLY;INTERVAL=1;
  • 每年12 月当天重复 :FREQ=YEARLY;INTERVAL=1;BYMONTH=12。

3. 启动

if (support) {
startActivity(intent)}

五、调用示例

kotlin:

val intent = Intent(Intent.ACTION_INSERT).apply {
data = CalendarContract.Events.CONTENT_URI
putExtra(CalendarContract.Events.TITLE, "我的标题")
putExtra(CalendarContract.EXTRA_EVENT_ALL_DAY, true)
putExtra(CalendarContract.Events.DESCRIPTION, "我的描述")
putExtra(CalendarContract.Events.RRULE, "FREQ=DAILY;COUNT=10")
putExtra(CalendarContract.EXTRA_EVENT_BEGIN_TIME, System.currentTimeMillis())
putExtra(CalendarContract.EXTRA_EVENT_END_TIME,System.currentTimeMillis() + AlarmManager.INTERVAL_DAY)}if (intent.resolveActivity(packageManager) != null) {
startActivity(intent)}

java:

Intent intent = new Intent(Intent.ACTION_INSERT);
intent.setData(CalendarContract.Events.CONTENT_URI);
intent.putExtra(CalendarContract.Events.TITLE, "我的标题");
intent.putExtra(CalendarContract.EXTRA_EVENT_ALL_DAY, true);
intent.putExtra(CalendarContract.Events.DESCRIPTION, "我的描述");
intent.putExtra(CalendarContract.Events.RRULE, "FREQ=DAILY;COUNT=10");
intent.putExtra(CalendarContract.EXTRA_EVENT_BEGIN_TIME, System.currentTimeMillis());
intent.putExtra(CalendarContract.EXTRA_EVENT_END_TIME,System.currentTimeMillis() + AlarmManager.INTERVAL_DAY);if (intent.resolveActivity(packageManager) != null) {
startActivity(intent);}

六、 Android开发者适配文档参考

https://developer.android.google.cn/identity/providers/calendar-provider?hl=zh-cn#intent-insert

该适配指南与金标联盟官网适配指南一致,您也可查阅金标联盟官网中公示适配指南。

金标联盟官方文档地址:https://www.itgsa.com/doc/6631953378231296

上一篇:照片视频选择控件
下一篇:粘贴控件
文档内容是否有帮助?
有帮助
无帮助