Android日历操作

最近接到一个需求,要为用户增加一些日历提示信息。感觉不是很难的一个需求,也折腾了一天,记录一些关键步骤,以资来者。

申请日历权限

APP想要操作用户的日历,需要有读写日历的权限:android.permission.READ_CALENDAR,android.permission.WRITE_CALENDAR。上述权限读取和写入可以分别申请,即如果需求只是写入日历提醒功能,则不需要申请READ_CALENDAR权限。此外,由于此权限是高危权限,需要进行动态申请,具体申请方式可以参见Android原生动态权限申请方法
.

写入日历提醒

Android的日历系统对外暴露是通过provider机制进行的,即每次操作都要拼装对应的URI。这里比较关键的是三个URL为:

private static String CALENDAR_URL = "content://com.android.calendar/calendars"; // 日历账户
private static String CALENDAR_EVENT_URL = "content://com.android.calendar/events"; // 事件表
private static String CALENDAR_REMINDER_URL = "content://com.android.calendar/reminders"; // 提醒表

首先我们需要获得用户日历的账户id,这个值是我们所有日历操作的基础;然后向events表插入对应的日程,包括起止时间(ms)、标题、事件描述;最后向reminders表插入对应的提醒事件,包括日程填入后的eventId,提醒时间以及提醒方式。

核心代码:

public static boolean insertCalendarEvent(Context context, String title, String description,
											  long beginTimeMillis, long endTimeMillis) {
	if (context == null || TextUtils.isEmpty(title) || TextUtils.isEmpty(description)) {
		return false;
	}

	int calId = checkCalendarAccount(context); // 获取日历账户的id
	if (calId < 0) { // 获取账户id失败直接返回,添加日历事件失败
		return false;
	}

	try {
		/** 插入日程 */
		ContentValues eventValues = new ContentValues();
		eventValues.put(CalendarContract.Events.DTSTART, beginTimeMillis); // 事件起始时间
		eventValues.put(CalendarContract.Events.DTEND, endTimeMillis); // 事件结束时间
		eventValues.put(CalendarContract.Events.TITLE, title); // 事件标题
		eventValues.put(CalendarContract.Events.DESCRIPTION, description); // 事件描述
		eventValues.put(CalendarContract.Events.CALENDAR_ID, 1); // 使用默认日历目录
		eventValues.put(CalendarContract.Events.EVENT_TIMEZONE, TimeZone.getDefault().getID()); // 获取默认时区
		Uri eUri = context.getContentResolver().insert(Uri.parse(CALENDAR_EVENT_URL), eventValues);
		long eventId = ContentUris.parseId(eUri);
		if (eventId == 0) { // 插入失败
			return false;
		}

		/** 插入提醒 - 依赖插入日程成功 */
		ContentValues reminderValues = new ContentValues();
		reminderValues.put(CalendarContract.Reminders.EVENT_ID, eventId);
		reminderValues.put(CalendarContract.Reminders.MINUTES, 10); // 提前10分钟提醒
		reminderValues.put(CalendarContract.Reminders.METHOD, CalendarContract.Reminders.METHOD_ALERT); // 提示方式提醒
		Uri rUri = context.getContentResolver().insert(Uri.parse(CALENDAR_REMINDER_URL),
				reminderValues);
		if (rUri == null || ContentUris.parseId(rUri) == 0) {
			return false;
		}
	} catch (Exception e) {
		e.printStackTrace();
		return false;
	}
	return true;
}
查看日历

查看日历一种方式是通过qurey的方式进行provider查询,这种方式有很大可能会读取到用户其他的日历信息,不是很友好(主要是没需求,都懂得~)。这里推荐另一种查看日历的方式,直接拉起系统日历来查看具体信息。具体代码如下:

private void gotoCalendar() {
	Intent intent = new Intent(Intent.ACTION_MAIN);
	intent.addCategory(Intent.CATEGORY_APP_CALENDAR);
	startActivity(intent);
}
TODO

需求虽然做完且交付了,还有两个问题需要继续学习解决,记录下来,省的忘了。

  1. 日历的账户操作很重要,能有效解决多个应用日程污染问题;
  2. 如何过滤本APP插入日程,如果日程被修改过如何识别出来。

参看代码:CalendarActivity

  • 2
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 3
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

kiba_zwei

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值