Android向系统日历中添加行程

申请动态权限


日历的content Provider的uri
private static String CALENDER_URL = "content://com.android.calendar/calendars"; private static String CALENDER_EVENT_URL = "content://com.android.calendar/events"; private static String CALENDER_REMINDER_URL = "content://com.android.calendar/reminders";

添加日历行程
解题思路:通过ContentProvider向系统日历中添加数据
日历提供程序是用户日历事件的存储区。您可以利用 Calendar Provider API 对日历、事件、参加者、提醒等执行查询、插入、更新和删除操作。
我们先来看一下Android jar包有关于日历提供的Provider Android向系统日历中添加行程
文章图片

【Android向系统日历中添加行程】CalendarContract定义了日历和日程事件相关的数据模型:

Android向系统日历中添加行程
文章图片
日历提供程序数据模型的图像化表示
  • CalendarContract.Calendars :此表储存日历特定信息。 此表中的每一行都包含一个日历的详细信息,例如名称、颜色、同步信息等。
  • CalendarContract.Events :此表储存事件特定信息。 此表中的每一行都包含一个事件的信息 — 例如事件标题、地点、开始时间、结束时间等。 事件可一次性发生,也可多次重复发生。参加者、提醒和扩展属性存储在单独的表内。它们各自具有一个 EVENT_ID,用于引用 Events 表中的 _ID。
  • CalendarContract.Instances : 此表储存每个事件实例的开始时间和结束时间。 此表中的每一行都表示一个事件实例。 对于一次性事件,实例与事件为 1:1 映射。对于重复事件,会自动生成多个行,分别对应多个事件实例。
  • CalendarContract.Attendees : 此表储存事件参加者(来宾)信息。 每一行都表示事件的一位来宾。 它指定来宾的类型以及事件的来宾出席响应。
  • CalendarContract.Reminders :此表储存提醒/通知数据。 每一行都表示事件的一个提醒。一个事件可以有多个提醒。 每个事件的最大提醒数量在 MAX_REMINDERS 中指定,后者由拥有给定日历的同步适配器设置。 提醒以事件发生前的分钟数形式指定,其具有一个可决定用户提醒方式的方法。
Claendar常量:(日历表) Calendar的必须添加常量:
  • ACCOUNT_NAME :The account that was used to sync the entry to the device.
  • ACCOUNT_TYPE :The type of the account that was used to sync the entry to the device.
  • NAME:The name of the calendar. Column name.
  • CALENDAR_DISPLAY_NAME :The display name of the calendar. Column name.
  • CALENDAR_COLOR :The color of the calendar. This should only be updated by the sync adapter, not other apps, as changing a calendar's color can adversely affect its display.
  • CALENDAR_ACCESS_LEVEL :The level of access that the user has for the calendar
  • OWNER_ACCOUNT:The owner account for this calendar, based on the calendar feed. This will be different from the _SYNC_ACCOUNT for delegated calendars. Column name.
对于给定账户,只有在同时指定account_name和account_type时才能将其视为唯一账户,account_type字符串对应于AccountManager出注册账户时的账户验证器。
Calendar的建议添加常量:
  • SYNC_EVENTS :Is this calendar synced and are its events stored on the device? 0 - Do not sync this calendar or store events for this calendar. 1 - Sync down events for this calendar.
  • CALENDAR_TIME_ZONE:The time zone the calendar is associated with.
  • ALLOWED_REMINDERS :A comma separated list of reminder methods supported for this calendar in the format "#,#,#".
  • ALLOWED_AVAILABILITY :A comma separated list of availability types supported for this calendar in the format "#,#,#".
  • ALLOWED_ATTENDEE_TYPES :A comma separated list of attendee types supported for this calendar in the format "#,#,#".
Event常量:(事件表,所属日历表)
  • CALENDAR_ID:事件所属日历的id
  • ORGANIZER:事件组织者(所有者)的电子邮件。
  • TITLE:事件的标题。
  • EVENT_LOCATION:事件的发生地点。
  • DESCRIPTION:事件的描述
  • DTSTART:事件开始时间,以从公元纪年开始计算的协调世界时毫秒数表示。
  • DTEND:事件结束时间,以从公元纪年开始计算的协调世界时毫秒数表示。
  • EVENT_TIMEZONE:事件的时区。
  • EVENT_END_TIMEZONE:事件结束时间的时区。
  • DURATION:RFC5545式的事件持续时间。例如,值为 "PT1H" 表示事件应持续一小时,值为 "P2W" 表示持续 2 周。
  • ALL_DAY:值为 1 表示此事件占用一整天(按照本地时区的定义)。 值为 0 表示它是常规事件,可在一天内的任何时间开始和结束。
  • RRULE: 事件的重复发生规则格式。例如,"FREQ=WEEKLY; COUNT=10; WKST=SU"。
  • RDATE:事件的重复发生日期,RRULE和RDATE通常联合用于定义一组聚合重复实例,具体参考RFC5545规范
  • AVAILABILITY:将此事件视为忙碌时间还是可调度的空闲时间。
  • GUESTS_CAN_MODIFY :来宾是否可修改事件。
  • GUESTS_CAN_INVITE_OTHERS :来宾是否可邀请其他来宾。
  • GUESTS_CAN_SEE_GUESTS:来宾是否可查看参加者列表。
Reminder常量 :(提醒表,所属事件表)
  • EVENT_ID: 事件id
  • MINUTES: 事件发生前的分钟数,应在达到该时间时发出提醒
  • METHOD: 提醒方式,有:
    METHOD_ALERT, METHOD_DEFAULT,
    METHOD_EMAIL, METHOD_SMS
Instances常量:(实例表,所属事件表,与事件一对一映射关系,详细解析见上文)
  • BEGIN: 实例的开始时间,以协调世界时毫秒数表示。
  • END: 实例的结束时间,以协调世界时毫秒数表示。
  • START_DAY: 与日历时区相应的实例儒略历开始日。
  • END_DAY: 与日历时区相应的实例儒略历结束日。
  • START_MINUTE: 从日历时区午夜开始计算的实例开始时间(分钟)。
  • END_MINUTE: 从日历时区午夜开始计算的实例结束时间(分钟)。
  • EVENT_ID: 该实例对应事件的 _ID。
向系统Calendar中添加Event
publicclass CalendarProviderUtil {// ContentProvider的uri private static Uri calendarUri = CalendarContract.Calendars.CONTENT_URI; private static Uri eventUri = CalendarContract.Events.CONTENT_URI; private static Uri reminderUri = CalendarContract.Reminders.CONTENT_URI; private static ContentResolver contentResolver; /** * 检查是否有日历表,有返回日历id,没有-1 * */ private static int isHaveCalender(){ // 查询日历表的cursor Cursor cursor = contentResolver.query(calendarUri,null,null,null,null); if (cursor == null || cursor.getCount() == 0){ return -1; }else { // 如果有日历表 try { cursor.moveToFirst(); // 通过cursor返回日历表的第一行的属性值 第一个日历的id return cursor.getInt(cursor.getColumnIndex(CalendarContract.Calendars._ID)); }finally { cursor.close(); } } }/** * 添加日历表 * */ private static long addCalendar(){ // 时区 TimeZone timeZone = TimeZone.getDefault(); // 配置Calendar ContentValues value = https://www.it610.com/article/new ContentValues(); value.put(CalendarContract.Calendars.NAME,"我的日历表"); value.put(CalendarContract.Calendars.ACCOUNT_NAME, "myAccount"); value.put(CalendarContract.Calendars.ACCOUNT_TYPE, "myType"); value.put(CalendarContract.Calendars.CALENDAR_DISPLAY_NAME, "myDisplayName"); value.put(CalendarContract.Calendars.VISIBLE, 1); value.put(CalendarContract.Calendars.CALENDAR_COLOR, Color.BLUE); value.put(CalendarContract.Calendars.CALENDAR_ACCESS_LEVEL, CalendarContract.Calendars.CAL_ACCESS_OWNER); value.put(CalendarContract.Calendars.SYNC_EVENTS, 1); value.put(CalendarContract.Calendars.CALENDAR_TIME_ZONE, timeZone.getID()); value.put(CalendarContract.Calendars.OWNER_ACCOUNT, "myAccount"); value.put(CalendarContract.Calendars.CAN_ORGANIZER_RESPOND, 0); value.put(CalendarContract.CALLER_IS_SYNCADAPTER,true); // 插入calendar Uri insertCalendarUri = contentResolver.insert(calendarUri,value); if (insertCalendarUri == null){ return -1; }else { // return Integer.parseInt(insertCalendarUri.toString()); return ContentUris.parseId(insertCalendarUri); }}/** *添加日历事件 * */ public static void addEvent(Context context){// 创建contentResolver contentResolver = context.getContentResolver(); // 日历表id int calendarId = isHaveCalender(); if (calendarId == -1){ addCalendar(); calendarId = isHaveCalender(); }// startMillis Calendar beginTime = Calendar.getInstance(); beginTime.set(2019,8,15); long startMillis = beginTime.getTimeInMillis(); // endMillis Calendar endTime = Calendar.getInstance(); endTime.set(2019,8,15); long endMillis = endTime.getTimeInMillis(); // 准备event ContentValues valueEvent = new ContentValues(); valueEvent.put(CalendarContract.Events.DTSTART,startMillis); valueEvent.put(CalendarContract.Events.DTEND,endMillis); valueEvent.put(CalendarContract.Events.TITLE,"事件标题"); valueEvent.put(CalendarContract.Events.DESCRIPTION,"事件描述"); valueEvent.put(CalendarContract.Events.CALENDAR_ID,calendarId); valueEvent.put(CalendarContract.Events.EVENT_TIMEZONE,"Asia/Shanghai"); // 添加event Uri insertEventUri = contentResolver.insert(eventUri,valueEvent); if (insertEventUri == null){ Toast.makeText(context,"添加event失败",Toast.LENGTH_SHORT).show(); }// 添加提醒 long eventId = ContentUris.parseId(insertEventUri); ContentValues valueReminder = new ContentValues(); valueReminder.put(CalendarContract.Reminders.EVENT_ID,eventId); valueReminder.put(CalendarContract.Reminders.MINUTES,15); valueReminder.put(CalendarContract.Reminders.METHOD, CalendarContract.Reminders.METHOD_ALARM); Uri insertReminderUri = contentResolver.insert(reminderUri,valueReminder); if (insertReminderUri == null){ Toast.makeText(context,"添加reminder失败",Toast.LENGTH_SHORT).show(); } } }

只测试了一下,有用,可能有bug

    推荐阅读