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向系统日历中添加行程_第1张图片

CalendarContract定义了日历和日程事件相关的数据模型:


Android向系统日历中添加行程_第2张图片
日历提供程序数据模型的图像化表示
  • 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

public  class 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 = 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

你可能感兴趣的:(Android向系统日历中添加行程)