本文实例为大家分享了Android实现系统日历同步日程的具体代码,供大家参考,具体内容如下

1、权限

<uses-permission android:name="android.permission.WRITE_CALENDAR" />
<uses-permission android:name="android.permission.READ_CALENDAR" />

2、动态权限Activity中

if (ContextCompat.checkSelfPermission(this,
                Manifest.permission.WRITE_CALENDAR) != PackageManager.PERMISSION_GRANTED) {
            ActivityCompat.requestPermissions(this,
                    new String[]{Manifest.permission.WRITE_CALENDAR,
                            Manifest.permission.READ_CALENDAR}, 1);
  }

3、使用

String tipTime = "2021-04-25 12:00";
long start = TimeUtils.stringToLong(tipTime ,"yyyy-MM-dd HH:mm");
        long end = start + 60 * 60 * 1000L;
        LogUtil.d("start:" + start);
        LogUtil.d("end:" + end);
 
        String[] split = tipTime.split(" ");
        String[] dateStr = split[0].split("-");
        int month = Integer.parseInt(dateStr[1]);
        int day = Integer.parseInt(dateStr[2]);
 
        String until = "20221231T235959Z";//截止时间:2022年12月31日23点59分59秒
        String mRule = "";
 
        switch (mRepeatType) {
            case 1://不重复
                mRule = null;
                break;
            case 2://按年重复(每年的某月某日)
                mRule = "FREQ=YEARLY;UNTIL=" + until + ";WKST=SU;BYMONTH=" + month + ";BYMONTHDAY=" + day;
                break;
            case 3://按月重复(每月的某天)
                mRule = "FREQ=MONTHLY;UNTIL=" + until + ";WKST=SU;BYMONTHDAY=" + day;
                break;
            case 4://按周重复
                String date = split[0];
                String week = TimeUtils.getWeek(date);
                switch (week) {
                    case "周日":
                        mRule = "FREQ=WEEKLY;UNTIL=" + until + ";WKST=SU;BYDAY=SU";
                        break;
                    case "周一":
                        mRule = "FREQ=WEEKLY;UNTIL=" + until + ";WKST=SU;BYDAY=MO";
                        break;
                    case "周二":
                        mRule = "FREQ=WEEKLY;UNTIL=" + until + ";WKST=SU;BYDAY=TU";
                        break;
                    case "周三":
                        mRule = "FREQ=WEEKLY;UNTIL=" + until + ";WKST=SU;BYDAY=WE";
                        break;
                    case "周四":
                        mRule = "FREQ=WEEKLY;UNTIL=" + until + ";WKST=SU;BYDAY=TH";
                        break;
                    case "周五":
                        mRule = "FREQ=WEEKLY;UNTIL=" + until + ";WKST=SU;BYDAY=FR";
                        break;
                    case "周六":
                        mRule = "FREQ=WEEKLY;UNTIL=" + until + ";WKST=SU;BYDAY=SA";
                        break;
                }
                break;
            case 5://按天(每天)
                mRule = "FREQ=DAILY;UNTIL=" + until;
                break;
            case 6://自定义周几重复,可多选
                mRule = "FREQ=WEEKLY;UNTIL=" + until + ";WKST=SU;BYDAY=";
                String[] weeks = mSelectedWeekStr.split(",");
                for (int i = 0; i < weeks.length; i++) {
                    if (weeks[i].equals("周日")) {
                        mRule += "SU,";
                    } else if (weeks[i].equals("周一")) {
                        mRule += "MO,";
                    } else if (weeks[i].equals("周二")) {
                        mRule += "TU,";
                    } else if (weeks[i].equals("周三")) {
                        mRule += "WE,";
                    } else if (weeks[i].equals("周四")) {
                        mRule += "TH,";
                    } else if (weeks[i].equals("周五")) {
                        mRule += "FR,";
                    } else if (weeks[i].equals("周六")) {
                        mRule += "SA,";
                    }
                }
                if (mRule.endsWith(",")) {
                    mRule.substring(0, mRule.length() - 1);
                }
                break;
        }
        LogUtil.d("mRule:" + mRule);
 
        CalendarEvent calendarEvent = new CalendarEvent(
                mContent, mContent,
                "",
                start,
                end,
                0, mRule
        );
 
// 添加事件
int addResult = CalendarProviderManager.addCalendarEvent(AddScheduleActivity.this, calendarEvent);
if (addResult == 0) {
        ToastUtil.showShortToast("插入成功");
 } else if (addResult == -1) {
         ToastUtil.showShortToast("插入失败");
 } else if (addResult == -2) {
         ToastUtil.showShortToast("没有权限");
 }

3、时间转换方法

public static long stringToLong(String strTime, String formatType) {
        Date date = null; // String类型转成date类型
        try {
            date = stringToDate(strTime, formatType);
        } catch (Exception e) {
            e.printStackTrace();
        }
        if (date == null) {
            return 0;
        } else {
            long currentTime = dateToLong(date); // date类型转成long类型
            return currentTime;
        }
    }
 
 
 
    public static Date stringToDate(String strTime, String formatType) {
        SimpleDateFormat formatter = new SimpleDateFormat(formatType);
        Date date = null;
        try {
            date = formatter.parse(strTime);
        } catch (ParseException e) {
            e.printStackTrace();
        }
        return date;
    }
 
 
 
// date要转换的date类型的时间
    public static long dateToLong(Date date) {
        return date.getTime();
    }

4、CalendarProviderManager 类

import android.content.ContentUris;
import android.content.ContentValues;
import android.content.Context;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.database.Cursor;
import android.graphics.Color;
import android.net.Uri;
import android.os.Build;
import android.provider.CalendarContract;
 
import calendarprovider.Util;
 
import java.util.ArrayList;
import java.util.List;
import java.util.TimeZone;
 
import static com.kyle.calendarprovider.Util.checkContextNull;
 
/**
 * 系统日历工具
 */
public class CalendarProviderManager {
 
    private static StringBuilder builder = new StringBuilder();
 
 
    /**
     * TIP: 要向系统日历插入事件,前提系统中必须存在至少1个日历账户
     ** /
 
 
    // ----------------------- 创建日历账户时账户名使用 ---------------------------
    private static String CALENDAR_NAME = "TestC";
    private static String CALENDAR_ACCOUNT_NAME = "Test";
    private static String CALENDAR_DISPLAY_NAME = "Test的账户";
 
 
    // ------------------------------- 日历账户 -----------------------------------
 
    /**
     * 获取日历账户ID(若没有则会自动创建一个)
     *
     * @return success: 日历账户ID  failed : -1  permission deny : -2
     */
    @SuppressWarnings("WeakerAccess")
    public static long obtainCalendarAccountID(Context context) {
        long calID = checkCalendarAccount(context);
        if (calID >= 0) {
            return calID;
        } else {
            return createCalendarAccount(context);
        }
    }
 
    /**
     * 检查是否存在日历账户
     *
     * @return 存在:日历账户ID  不存在:-1
     */
    private static long checkCalendarAccount(Context context) {
        try (Cursor cursor = context.getContentResolver().query(CalendarContract.Calendars.CONTENT_URI,
                null, null, null, null)) {
            // 不存在日历账户
            if (null == cursor) {
                return -1;
            }
            int count = cursor.getCount();
            // 存在日历账户,获取第一个账户的ID
            if (count > 0) {
                cursor.moveToFirst();
                return cursor.getInt(cursor.getColumnIndex(CalendarContract.Calendars._ID));
            } else {
                return -1;
            }
        }
    }
 
    /**
     * 创建一个新的日历账户
     *
     * @return success:ACCOUNT ID , create failed:-1 , permission deny:-2
     */
    private static long createCalendarAccount(Context context) {
        // 系统日历表
        Uri uri = CalendarContract.Calendars.CONTENT_URI;
 
        // 要创建的账户
        Uri accountUri;
 
        // 开始组装账户数据
        ContentValues account = new ContentValues();
        // 账户类型:本地
        // 在添加账户时,如果账户类型不存在系统中,则可能该新增记录会被标记为脏数据而被删除
        // 设置为ACCOUNT_TYPE_LOCAL可以保证在不存在账户类型时,该新增数据不会被删除
        account.put(CalendarContract.Calendars.ACCOUNT_TYPE, CalendarContract.ACCOUNT_TYPE_LOCAL);
        // 日历在表中的名称
        account.put(CalendarContract.Calendars.NAME, CALENDAR_NAME);
        // 日历账户的名称
        account.put(CalendarContract.Calendars.ACCOUNT_NAME, CALENDAR_ACCOUNT_NAME);
        // 账户显示的名称
        account.put(CalendarContract.Calendars.CALENDAR_DISPLAY_NAME, CALENDAR_DISPLAY_NAME);
        // 日历的颜色
        account.put(CalendarContract.Calendars.CALENDAR_COLOR, Color.parseColor("#515bd4"));
        // 用户对此日历的获取使用权限等级
        account.put(CalendarContract.Calendars.CALENDAR_ACCESS_LEVEL, CalendarContract.Calendars.CAL_ACCESS_OWNER);
        // 设置此日历可见
        account.put(CalendarContract.Calendars.VISIBLE, 1);
        // 日历时区
        account.put(CalendarContract.Calendars.CALENDAR_TIME_ZONE, TimeZone.getDefault().getID());
        // 可以修改日历时区
        account.put(CalendarContract.Calendars.CAN_MODIFY_TIME_ZONE, 1);
        // 同步此日历到设备上
        account.put(CalendarContract.Calendars.SYNC_EVENTS, 1);
        // 拥有者的账户
        account.put(CalendarContract.Calendars.OWNER_ACCOUNT, CALENDAR_ACCOUNT_NAME);
        // 可以响应事件
        account.put(CalendarContract.Calendars.CAN_ORGANIZER_RESPOND, 1);
        // 单个事件设置的最大的提醒数
        account.put(CalendarContract.Calendars.MAX_REMINDERS, 8);
        // 设置允许提醒的方式
        account.put(CalendarContract.Calendars.ALLOWED_REMINDERS, "0,1,2,3,4");
        // 设置日历支持的可用性类型
        account.put(CalendarContract.Calendars.ALLOWED_AVAILABILITY, "0,1,2");
        // 设置日历允许的出席者类型
        account.put(CalendarContract.Calendars.ALLOWED_ATTENDEE_TYPES, "0,1,2");
 
        /**
         *   TIP: 修改或添加ACCOUNT_NAME只能由SYNC_ADAPTER调用
         *  对uri设置CalendarContract.CALLER_IS_SYNCADAPTER为true,即标记当前操作为SYNC_ADAPTER操作
         *   在设置CalendarContract.CALLER_IS_SYNCADAPTER为true时,必须带上参数ACCOUNT_NAME和ACCOUNT_TYPE(任意)
         **/
        uri = uri.buildUpon()
                .appendQueryParameter(CalendarContract.CALLER_IS_SYNCADAPTER, "true")
                .appendQueryParameter(CalendarContract.Calendars.ACCOUNT_NAME, CALENDAR_ACCOUNT_NAME)
                .appendQueryParameter(CalendarContract.Calendars.ACCOUNT_TYPE,
                        CalendarContract.Calendars.CALENDAR_LOCATION)
                .build();
 
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
            // 检查日历权限
            if (PackageManager.PERMISSION_GRANTED == context.checkSelfPermission(
                    "android.permission.WRITE_CALENDAR")) {
                accountUri = context.getContentResolver().insert(uri, account);
            } else {
                return -2;
            }
        } else {
            accountUri = context.getContentResolver().insert(uri, account);
        }
 
        return accountUri == null ? -1 : ContentUris.parseId(accountUri);
    }
 
    /**
     * 删除创建的日历账户
     *
     * @return -2: permission deny  0: No designated account  1: delete success
     */
    public static int deleteCalendarAccountByName(Context context) {
        checkContextNull(context);
 
        int deleteCount;
        Uri uri = CalendarContract.Calendars.CONTENT_URI;
 
        String selection = "((" + CalendarContract.Calendars.ACCOUNT_NAME + " = ?) AND ("
                + CalendarContract.Calendars.ACCOUNT_TYPE + " = ?))";
        String[] selectionArgs = new String[]{CALENDAR_ACCOUNT_NAME, CalendarContract.ACCOUNT_TYPE_LOCAL};
 
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
            if (PackageManager.PERMISSION_GRANTED == context.checkSelfPermission(
                    "android.permission.WRITE_CALENDAR")) {
                deleteCount = context.getContentResolver().delete(uri, selection, selectionArgs);
            } else {
                return -2;
            }
        } else {
            deleteCount = context.getContentResolver().delete(uri, selection, selectionArgs);
        }
 
        return deleteCount;
    }
 
 
    // ------------------------------- 添加日历事件 -----------------------------------
 
    /**
     * 添加日历事件
     *
     * @param calendarEvent 日历事件(详细参数说明请参看{@link CalendarEvent}构造方法)
     * @return 0: success  -1: failed  -2: permission deny
     */
    public static int addCalendarEvent(Context context, CalendarEvent calendarEvent) {
          /**
           * TIP: 插入一个新事件的规则:
           *  1.  必须包含CALENDAR_ID和DTSTART字段
           *  2.  必须包含EVENT_TIMEZONE字段,使用TimeZone.getDefault().getID()方法获取默认时区
           *  3.  对于非重复发生的事件,必须包含DTEND字段
           *  4.  对重复发生的事件,必须包含一个附加了RRULE或RDATE字段的DURATION字段
           */
 
        checkContextNull(context);
 
        // 获取日历账户ID,也就是要将事件插入到的账户
        long calID = obtainCalendarAccountID(context);
 
        // 系统日历事件表
        Uri uri1 = CalendarContract.Events.CONTENT_URI;
        // 创建的日历事件
        Uri eventUri;
 
        // 系统日历事件提醒表
        Uri uri2 = CalendarContract.Reminders.CONTENT_URI;
        // 创建的日历事件提醒
        Uri reminderUri;
 
        // 开始组装事件数据
        ContentValues event = new ContentValues();
        // 事件要插入到的日历账户
        event.put(CalendarContract.Events.CALENDAR_ID, calID);
        setupEvent(calendarEvent, event);
 
 
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
            // 判断权限
            if (PackageManager.PERMISSION_GRANTED == context.checkSelfPermission(
                    "android.permission.WRITE_CALENDAR")) {
                eventUri = context.getContentResolver().insert(uri1, event);
            } else {
                return -2;
            }
        } else {
            eventUri = context.getContentResolver().insert(uri1, event);
        }
 
        if (null == eventUri) {
            return -1;
        }
 
 
        if (-2 != calendarEvent.getAdvanceTime()) {
            // 获取事件ID
            long eventID = ContentUris.parseId(eventUri);
 
            // 开始组装事件提醒数据
            ContentValues reminders = new ContentValues();
            // 此提醒所对应的事件ID
            reminders.put(CalendarContract.Reminders.EVENT_ID, eventID);
            // 设置提醒提前的时间(0:准时  -1:使用系统默认)
            reminders.put(CalendarContract.Reminders.MINUTES, calendarEvent.getAdvanceTime());
            // 设置事件提醒方式为通知警报
            reminders.put(CalendarContract.Reminders.METHOD, CalendarContract.Reminders.METHOD_ALERT);
            reminderUri = context.getContentResolver().insert(uri2, reminders);
 
            if (null == reminderUri) {
                return -1;
            }
        }
 
        return 0;
    }
 
 
    // ------------------------------- 更新日历事件 -----------------------------------
 
    /**
     * 更新指定ID的日历事件
     *
     * @param newCalendarEvent 更新的日历事件
     * @return -2: permission deny  else success
     */
    public static int updateCalendarEvent(Context context, long eventID, CalendarEvent newCalendarEvent) {
        checkContextNull(context);
 
        int updatedCount1;
 
        Uri uri1 = CalendarContract.Events.CONTENT_URI;
        Uri uri2 = CalendarContract.Reminders.CONTENT_URI;
 
        ContentValues event = new ContentValues();
        setupEvent(newCalendarEvent, event);
 
        // 更新匹配条件
        String selection1 = "(" + CalendarContract.Events._ID + " = ?)";
        String[] selectionArgs1 = new String[]{String.valueOf(eventID)};
 
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
            if (PackageManager.PERMISSION_GRANTED == context.checkSelfPermission(
                    "android.permission.WRITE_CALENDAR")) {
                updatedCount1 = context.getContentResolver().update(uri1, event, selection1, selectionArgs1);
            } else {
                return -2;
            }
        } else {
            updatedCount1 = context.getContentResolver().update(uri1, event, selection1, selectionArgs1);
        }
 
 
        ContentValues reminders = new ContentValues();
        reminders.put(CalendarContract.Reminders.MINUTES, newCalendarEvent.getAdvanceTime());
        reminders.put(CalendarContract.Reminders.METHOD, CalendarContract.Reminders.METHOD_ALERT);
 
        // 更新匹配条件
        String selection2 = "(" + CalendarContract.Reminders.EVENT_ID + " = ?)";
        String[] selectionArgs2 = new String[]{String.valueOf(eventID)};
 
        int updatedCount2 = context.getContentResolver().update(uri2, reminders, selection2, selectionArgs2);
 
        return (updatedCount1 + updatedCount2) / 2;
    }
 
    /**
     * 更新指定ID事件的开始时间
     *
     * @return If successfully returns 1
     */
    public static int updateCalendarEventbeginTime(Context context, long eventID, long newBeginTime) {
        checkContextNull(context);
 
        Uri uri = CalendarContract.Events.CONTENT_URI;
 
        // 新的数据
        ContentValues event = new ContentValues();
        event.put(CalendarContract.Events.DTSTART, newBeginTime);
 
        // 匹配条件
        String selection = "(" + CalendarContract.Events._ID + " = ?)";
        String[] selectionArgs = new String[]{String.valueOf(eventID)};
 
        return context.getContentResolver().update(uri, event, selection, selectionArgs);
    }
 
    /**
     * 更新指定ID事件的结束时间
     *
     * @return If successfully returns 1
     */
    public static int updateCalendarEventEndTime(Context context, long eventID, long newEndTime) {
        checkContextNull(context);
 
        Uri uri = CalendarContract.Events.CONTENT_URI;
 
        // 新的数据
        ContentValues event = new ContentValues();
        event.put(CalendarContract.Events.DTEND, newEndTime);
 
 
        // 匹配条件
        String selection = "(" + CalendarContract.Events._ID + " = ?)";
        String[] selectionArgs = new String[]{String.valueOf(eventID)};
 
        return context.getContentResolver().update(uri, event, selection, selectionArgs);
    }
 
    /**
     * 更新指定ID事件的起始时间
     *
     * @return If successfully returns 1
     */
    public static int updateCalendarEventTime(Context context, long eventID, long newBeginTime,
                                              long newEndTime) {
        checkContextNull(context);
 
        Uri uri = CalendarContract.Events.CONTENT_URI;
 
        // 新的数据
        ContentValues event = new ContentValues();
        event.put(CalendarContract.Events.DTSTART, newBeginTime);
        event.put(CalendarContract.Events.DTEND, newEndTime);
 
 
        // 匹配条件
        String selection = "(" + CalendarContract.Events._ID + " = ?)";
        String[] selectionArgs = new String[]{String.valueOf(eventID)};
 
        return context.getContentResolver().update(uri, event, selection, selectionArgs);
    }
 
    /**
     * 更新指定ID事件的标题
     *
     * @return If successfully returns 1
     */
    public static int updateCalendarEventTitle(Context context, long eventID, String newTitle) {
        checkContextNull(context);
 
        Uri uri = CalendarContract.Events.CONTENT_URI;
 
        // 新的数据
        ContentValues event = new ContentValues();
        event.put(CalendarContract.Events.TITLE, newTitle);
 
 
        // 匹配条件
        String selection = "(" + CalendarContract.Events._ID + " = ?)";
        String[] selectionArgs = new String[]{String.valueOf(eventID)};
 
        return context.getContentResolver().update(uri, event, selection, selectionArgs);
    }
 
    /**
     * 更新指定ID事件的描述
     *
     * @return If successfully returns 1
     */
    public static int updateCalendarEventDes(Context context, long eventID, String newEventDes) {
        checkContextNull(context);
 
        Uri uri = CalendarContract.Events.CONTENT_URI;
 
        // 新的数据
        ContentValues event = new ContentValues();
        event.put(CalendarContract.Events.DESCRIPTION, newEventDes);
 
 
        // 匹配条件
        String selection = "(" + CalendarContract.Events._ID + " = ?)";
        String[] selectionArgs = new String[]{String.valueOf(eventID)};
 
        return context.getContentResolver().update(uri, event, selection, selectionArgs);
    }
 
    /**
     * 更新指定ID事件的地点
     *
     * @return If successfully returns 1
     */
    public static int updateCalendarEventLocation(Context context, long eventID, String newEventLocation) {
        checkContextNull(context);
 
        Uri uri = CalendarContract.Events.CONTENT_URI;
 
        // 新的数据
        ContentValues event = new ContentValues();
        event.put(CalendarContract.Events.EVENT_LOCATION, newEventLocation);
 
 
        // 匹配条件
        String selection = "(" + CalendarContract.Events._ID + " = ?)";
        String[] selectionArgs = new String[]{String.valueOf(eventID)};
 
        return context.getContentResolver().update(uri, event, selection, selectionArgs);
    }
 
    /**
     * 更新指定ID事件的标题和描述
     *
     * @return If successfully returns 1
     */
    public static int updateCalendarEventTitAndDes(Context context, long eventID, String newEventTitle,
                                                   String newEventDes) {
        checkContextNull(context);
 
        Uri uri = CalendarContract.Events.CONTENT_URI;
 
        // 新的数据
        ContentValues event = new ContentValues();
        event.put(CalendarContract.Events.TITLE, newEventTitle);
        event.put(CalendarContract.Events.DESCRIPTION, newEventDes);
 
 
        // 匹配条件
        String selection = "(" + CalendarContract.Events._ID + " = ?)";
        String[] selectionArgs = new String[]{String.valueOf(eventID)};
 
        return context.getContentResolver().update(uri, event, selection, selectionArgs);
    }
 
    /**
     * 更新指定ID事件的常用信息(标题、描述、地点)
     *
     * @return If successfully returns 1
     */
    public static int updateCalendarEventCommonInfo(Context context, long eventID, String newEventTitle,
                                                    String newEventDes, String newEventLocation) {
        checkContextNull(context);
 
        Uri uri = CalendarContract.Events.CONTENT_URI;
 
        // 新的数据
        ContentValues event = new ContentValues();
        event.put(CalendarContract.Events.TITLE, newEventTitle);
        event.put(CalendarContract.Events.DESCRIPTION, newEventDes);
        event.put(CalendarContract.Events.EVENT_LOCATION, newEventLocation);
 
 
        // 匹配条件
        String selection = "(" + CalendarContract.Events._ID + " = ?)";
        String[] selectionArgs = new String[]{String.valueOf(eventID)};
 
        return context.getContentResolver().update(uri, event, selection, selectionArgs);
    }
 
    /**
     * 更新指定ID事件的提醒方式
     *
     * @return If successfully returns 1
     */
    private static int updateCalendarEventReminder(Context context, long eventID, long newAdvanceTime) {
        checkContextNull(context);
 
        Uri uri = CalendarContract.Reminders.CONTENT_URI;
 
        ContentValues reminders = new ContentValues();
        reminders.put(CalendarContract.Reminders.MINUTES, newAdvanceTime);
 
        // 更新匹配条件
        String selection2 = "(" + CalendarContract.Reminders.EVENT_ID + " = ?)";
        String[] selectionArgs2 = new String[]{String.valueOf(eventID)};
 
        return context.getContentResolver().update(uri, reminders, selection2, selectionArgs2);
    }
 
    /**
     * 更新指定ID事件的提醒重复规则
     *
     * @return If successfully returns 1
     */
    private static int updateCalendarEventRRule(Context context, long eventID, String newRRule) {
        checkContextNull(context);
 
        Uri uri = CalendarContract.Events.CONTENT_URI;
 
        // 新的数据
        ContentValues event = new ContentValues();
        event.put(CalendarContract.Events.RRULE, newRRule);
 
        // 匹配条件
        String selection = "(" + CalendarContract.Events._ID + " = ?)";
        String[] selectionArgs = new String[]{String.valueOf(eventID)};
 
        return context.getContentResolver().update(uri, event, selection, selectionArgs);
    }
 
 
    // ------------------------------- 删除日历事件 -----------------------------------
 
    /**
     * 删除日历事件
     *
     * @param eventID 事件ID
     * @return -2: permission deny  else success
     */
    public static int deleteCalendarEvent(Context context, long eventID) {
        checkContextNull(context);
 
        int deletedCount1;
        Uri uri1 = CalendarContract.Events.CONTENT_URI;
        Uri uri2 = CalendarContract.Reminders.CONTENT_URI;
 
        // 删除匹配条件
        String selection = "(" + CalendarContract.Events._ID + " = ?)";
        String[] selectionArgs = new String[]{String.valueOf(eventID)};
 
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
            if (PackageManager.PERMISSION_GRANTED == context.checkSelfPermission(
                    "android.permission.WRITE_CALENDAR")) {
                deletedCount1 = context.getContentResolver().delete(uri1, selection, selectionArgs);
            } else {
                return -2;
            }
        } else {
            deletedCount1 = context.getContentResolver().delete(uri1, selection, selectionArgs);
        }
 
        // 删除匹配条件
        String selection2 = "(" + CalendarContract.Reminders.EVENT_ID + " = ?)";
        String[] selectionArgs2 = new String[]{String.valueOf(eventID)};
 
        int deletedCount2 = context.getContentResolver().delete(uri2, selection2, selectionArgs2);
 
        return (deletedCount1 + deletedCount2) / 2;
    }
 
 
    // ------------------------------- 查询日历事件 -----------------------------------
 
    /**
     * 查询指定日历账户下的所有事件
     *
     * @return If failed return null else return List<CalendarEvent>
     */
    public static List<CalendarEvent> queryAccountEvent(Context context, long calID) {
        checkContextNull(context);
 
        final String[] EVENT_PROJECTION = new String[]{
                CalendarContract.Events.CALENDAR_ID,             // 在表中的列索引0
                CalendarContract.Events.TITLE,                   // 在表中的列索引1
                CalendarContract.Events.DESCRIPTION,             // 在表中的列索引2
                CalendarContract.Events.EVENT_LOCATION,          // 在表中的列索引3
                CalendarContract.Events.DISPLAY_COLOR,           // 在表中的列索引4
                CalendarContract.Events.STATUS,                  // 在表中的列索引5
                CalendarContract.Events.DTSTART,                 // 在表中的列索引6
                CalendarContract.Events.DTEND,                   // 在表中的列索引7
                CalendarContract.Events.DURATION,                // 在表中的列索引8
                CalendarContract.Events.EVENT_TIMEZONE,          // 在表中的列索引9
                CalendarContract.Events.EVENT_END_TIMEZONE,      // 在表中的列索引10
                CalendarContract.Events.ALL_DAY,                 // 在表中的列索引11
                CalendarContract.Events.ACCESS_LEVEL,            // 在表中的列索引12
                CalendarContract.Events.AVAILABILITY,            // 在表中的列索引13
                CalendarContract.Events.HAS_ALARM,               // 在表中的列索引14
                CalendarContract.Events.RRULE,                   // 在表中的列索引15
                CalendarContract.Events.RDATE,                   // 在表中的列索引16
                CalendarContract.Events.HAS_ATTENDEE_DATA,       // 在表中的列索引17
                CalendarContract.Events.LAST_DATE,               // 在表中的列索引18
                CalendarContract.Events.ORGANIZER,               // 在表中的列索引19
                CalendarContract.Events.IS_ORGANIZER,            // 在表中的列索引20
                CalendarContract.Events._ID                      // 在表中的列索引21
        };
 
        // 事件匹配
        Uri uri = CalendarContract.Events.CONTENT_URI;
        Uri uri2 = CalendarContract.Reminders.CONTENT_URI;
 
        String selection = "(" + CalendarContract.Events.CALENDAR_ID + " = ?)";
        String[] selectionArgs = new String[]{String.valueOf(calID)};
 
        Cursor cursor;
 
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
            if (PackageManager.PERMISSION_GRANTED == context.checkSelfPermission(
                    "android.permission.READ_CALENDAR")) {
                cursor = context.getContentResolver().query(uri, EVENT_PROJECTION, selection,
                        selectionArgs, null);
            } else {
                return null;
            }
        } else {
            cursor = context.getContentResolver().query(uri, EVENT_PROJECTION, selection,
                    selectionArgs, null);
        }
 
        if (null == cursor) {
            return null;
        }
 
        // 查询结果
        List<CalendarEvent> result = new ArrayList<>();
 
        // 开始查询数据
        if (cursor.moveToFirst()) {
            do {
                CalendarEvent calendarEvent = new CalendarEvent();
                result.add(calendarEvent);
                calendarEvent.setId(cursor.getLong(cursor.getColumnIndex(
                        CalendarContract.Events._ID)));
                calendarEvent.setCalID(cursor.getLong(cursor.getColumnIndex(
                        CalendarContract.Events.CALENDAR_ID)));
                calendarEvent.setTitle(cursor.getString(cursor.getColumnIndex(
                        CalendarContract.Events.TITLE)));
                calendarEvent.setDescription(cursor.getString(cursor.getColumnIndex(
                        CalendarContract.Events.DESCRIPTION)));
                calendarEvent.setEventLocation(cursor.getString(cursor.getColumnIndex(
                        CalendarContract.Events.EVENT_LOCATION)));
                calendarEvent.setDisplayColor(cursor.getInt(cursor.getColumnIndex(
                        CalendarContract.Events.DISPLAY_COLOR)));
                calendarEvent.setStatus(cursor.getInt(cursor.getColumnIndex(
                        CalendarContract.Events.STATUS)));
                calendarEvent.setStart(cursor.getLong(cursor.getColumnIndex(
                        CalendarContract.Events.DTSTART)));
                calendarEvent.setEnd(cursor.getLong(cursor.getColumnIndex(
                        CalendarContract.Events.DTEND)));
                calendarEvent.setDuration(cursor.getString(cursor.getColumnIndex(
                        CalendarContract.Events.DURATION)));
                calendarEvent.setEventTimeZone(cursor.getString(cursor.getColumnIndex(
                        CalendarContract.Events.EVENT_TIMEZONE)));
                calendarEvent.setEventEndTimeZone(cursor.getString(cursor.getColumnIndex(
                        CalendarContract.Events.EVENT_END_TIMEZONE)));
                calendarEvent.setAllDay(cursor.getInt(cursor.getColumnIndex(
                        CalendarContract.Events.ALL_DAY)));
                calendarEvent.setAccessLevel(cursor.getInt(cursor.getColumnIndex(
                        CalendarContract.Events.ACCESS_LEVEL)));
                calendarEvent.setAvailability(cursor.getInt(cursor.getColumnIndex(
                        CalendarContract.Events.AVAILABILITY)));
                calendarEvent.setHasAlarm(cursor.getInt(cursor.getColumnIndex(
                        CalendarContract.Events.HAS_ALARM)));
                calendarEvent.setRRule(cursor.getString(cursor.getColumnIndex(
                        CalendarContract.Events.RRULE)));
                calendarEvent.setRDate(cursor.getString(cursor.getColumnIndex(
                        CalendarContract.Events.RDATE)));
                calendarEvent.setHasAttendeeData(cursor.getInt(cursor.getColumnIndex(
                        CalendarContract.Events.HAS_ATTENDEE_DATA)));
                calendarEvent.setLastDate(cursor.getInt(cursor.getColumnIndex(
                        CalendarContract.Events.LAST_DATE)));
                calendarEvent.setOrganizer(cursor.getString(cursor.getColumnIndex(
                        CalendarContract.Events.ORGANIZER)));
                calendarEvent.setIsOrganizer(cursor.getString(cursor.getColumnIndex(
                        CalendarContract.Events.IS_ORGANIZER)));
 
 
                // ----------------------- 开始查询事件提醒 ------------------------------
                String[] REMINDER_PROJECTION = new String[]{
                        CalendarContract.Reminders._ID,                     // 在表中的列索引0
                        CalendarContract.Reminders.EVENT_ID,                // 在表中的列索引1
                        CalendarContract.Reminders.MINUTES,                 // 在表中的列索引2
                        CalendarContract.Reminders.METHOD,                  // 在表中的列索引3
                };
                String selection2 = "(" + CalendarContract.Reminders.EVENT_ID + " = ?)";
                String[] selectionArgs2 = new String[]{String.valueOf(calendarEvent.getId())};
 
                try (Cursor reminderCursor = context.getContentResolver().query(uri2, REMINDER_PROJECTION,
                        selection2, selectionArgs2, null)) {
                    if (null != reminderCursor) {
                        if (reminderCursor.moveToFirst()) {
                            List<CalendarEvent.EventReminders> reminders = new ArrayList<>();
                            do {
                                CalendarEvent.EventReminders reminders1 = new CalendarEvent.EventReminders();
                                reminders.add(reminders1);
                                reminders1.setReminderId(reminderCursor.getLong(
                                        reminderCursor.getColumnIndex(CalendarContract.Reminders._ID)));
                                reminders1.setReminderEventID(reminderCursor.getLong(
                                        reminderCursor.getColumnIndex(CalendarContract.Reminders.EVENT_ID)));
                                reminders1.setReminderMinute(reminderCursor.getInt(
                                        reminderCursor.getColumnIndex(CalendarContract.Reminders.MINUTES)));
                                reminders1.setReminderMethod(reminderCursor.getInt(
                                        reminderCursor.getColumnIndex(CalendarContract.Reminders.METHOD)));
                            } while (reminderCursor.moveToNext());
                            calendarEvent.setReminders(reminders);
                        }
                    }
                }
            } while (cursor.moveToNext());
            cursor.close();
        }
 
        return result;
    }
 
    /**
     * 判断日历账户中是否已经存在此事件
     *
     * @param begin 事件开始时间
     * @param end   事件结束时间
     * @param title 事件标题
     */
    public static boolean isEventAlreadyExist(Context context, long begin, long end, String title) {
        String[] projection = new String[]{
                CalendarContract.Instances.BEGIN,
                CalendarContract.Instances.END,
                CalendarContract.Instances.TITLE
        };
 
        Cursor cursor = CalendarContract.Instances.query(
                context.getContentResolver(), projection, begin, end, title);
 
        return null != cursor && cursor.moveToFirst()
                && cursor.getString(
                cursor.getColumnIndex(CalendarContract.Instances.TITLE)).equals(title);
    }
 
 
    // ------------------------------- 日历事件相关 -----------------------------------
 
    /**
     * 组装日历事件
     */
    private static void setupEvent(CalendarEvent calendarEvent, ContentValues event) {
        // 事件开始时间
        event.put(CalendarContract.Events.DTSTART, calendarEvent.getStart());
        // 事件结束时间
        event.put(CalendarContract.Events.DTEND, calendarEvent.getEnd());
        // 事件标题
        event.put(CalendarContract.Events.TITLE, calendarEvent.getTitle());
        // 事件描述(对应手机系统日历备注栏)
        event.put(CalendarContract.Events.DESCRIPTION, calendarEvent.getDescription());
        // 事件地点
        event.put(CalendarContract.Events.EVENT_LOCATION, calendarEvent.getEventLocation());
        // 事件时区
        event.put(CalendarContract.Events.EVENT_TIMEZONE, TimeZone.getDefault().getID());
        // 定义事件的显示,默认即可
        event.put(CalendarContract.Events.ACCESS_LEVEL, CalendarContract.Events.ACCESS_DEFAULT);
        // 事件的状态
        event.put(CalendarContract.Events.STATUS, 0);
        // 设置事件提醒警报可用
        event.put(CalendarContract.Events.HAS_ALARM, 1);
        // 设置事件忙
        event.put(CalendarContract.Events.AVAILABILITY, CalendarContract.Events.AVAILABILITY_BUSY);
        if (null != calendarEvent.getRRule()) {
            // 设置事件重复规则
            event.put(CalendarContract.Events.RRULE,
                    getFullRRuleForRRule(calendarEvent.getRRule(),
                            calendarEvent.getStart(), calendarEvent.getEnd()));
        }
    }
 
    /**
     * 获取完整的重复规则(包含终止时间)
     *
     * @param rRule     重复规则
     * @param beginTime 开始时间
     * @param endTime   结束时间
     */
    private static String getFullRRuleForRRule(String rRule, long beginTime, long endTime) {
        builder.delete(0, builder.length());
 
        switch (rRule) {
            case RRuleConstant.REPEAT_WEEKLY_BY_MO:
            case RRuleConstant.REPEAT_WEEKLY_BY_TU:
            case RRuleConstant.REPEAT_WEEKLY_BY_WE:
            case RRuleConstant.REPEAT_WEEKLY_BY_TH:
            case RRuleConstant.REPEAT_WEEKLY_BY_FR:
            case RRuleConstant.REPEAT_WEEKLY_BY_SA:
            case RRuleConstant.REPEAT_WEEKLY_BY_SU:
                return builder.append(rRule).append(Util.getFinalRRuleMode(endTime)).toString();
            case RRuleConstant.REPEAT_CYCLE_WEEKLY:
                return builder.append(rRule).append(Util.getWeekForDate(beginTime)).append("; UNTIL = ")
                        .append(Util.getFinalRRuleMode(endTime)).toString();
            case RRuleConstant.REPEAT_CYCLE_MONTHLY:
                return builder.append(rRule).append(Util.getDayOfMonth(beginTime))
                        .append("; UNTIL = ").append(Util.getFinalRRuleMode(endTime)).toString();
            default:
                return rRule;
        }
    }
 
 
    // ------------------------------- 通过Intent启动系统日历 -----------------------------------
 
    /*
        日历的Intent对象:
           动作                  描述                         附加功能
        ACTION_VIEW        打开指定时间的日历                    无
        ACTION_VIEW        查看由EVENT_ID指定的事件        开始时间,结束时间
        ACTION_EDIT        编辑由EVENT_ID指定的事件        开始时间,结束时间
        ACTION_INSERT      创建一个事件                         所有
        Intent对象的附加功能:
        Events.TITLE                                        事件标题
        CalendarContract.EXTRA_EVENT_BEGIN_TIME             开始时间
        CalendarContract.EXTRA_EVENT_END_TIME               结束时间
        CalendarContract.EXTRA_EVENT_ALL_DAY                是否全天
        Events.EVENT_LOCATION                               事件地点
        Events.DESCRIPTION                                  事件描述
        Intent.EXTRA_EMALL                                  受邀者电子邮件,用逗号分隔
        Events.RRULE                                        事件重复规则
        Events.ACCESS_LEVEL                                 事件私有还是公有
        Events.AVAILABILITY                                 预定事件是在忙时计数还是闲时计数
     */
 
    /**
     * 通过Intent启动系统日历新建事件界面插入新的事件
     * <p>
     * TIP: 这将不再需要声明读写日历数据的权限
     *
     * @param beginTime 事件开始时间
     * @param endTime   事件结束时间
     * @param title     事件标题
     * @param des       事件描述
     * @param location  事件地点
     * @param isAllDay  事件是否全天
     */
    public static void startCalendarForIntentToInsert(Context context, long beginTime, long endTime,
                                                      String title, String des, String location,
                                                      boolean isAllDay) {
        checkCalendarAccount(context);
 
 
        // FIXME: 2019/3/6 VIVO手机无法打开界面,找不到对应的Activity  com.bbk.calendar
        Intent intent = new Intent(Intent.ACTION_INSERT)
                .setData(CalendarContract.Events.CONTENT_URI)
                .putExtra(CalendarContract.EXTRA_EVENT_BEGIN_TIME, beginTime)
                .putExtra(CalendarContract.EXTRA_EVENT_END_TIME, endTime)
                .putExtra(CalendarContract.Events.ALL_DAY, isAllDay)
                .putExtra(CalendarContract.Events.TITLE, title)
                .putExtra(CalendarContract.Events.DESCRIPTION, des)
                .putExtra(CalendarContract.Events.EVENT_LOCATION, location);
 
        if (null != intent.resolveActivity(context.getPackageManager())) {
            context.startActivity(intent);
        }
    }
 
    /**
     * 通过Intent启动系统日历来编辑指定ID的事件
     * <p>
     *
     * @param eventID 要编辑的事件ID
     */
    public static void startCalendarForIntentToEdit(Context context, long eventID) {
        checkCalendarAccount(context);
 
        Uri uri = ContentUris.withAppendedId(CalendarContract.Events.CONTENT_URI, eventID);
        Intent intent = new Intent(Intent.ACTION_EDIT).setData(uri);
 
        if (null != intent.resolveActivity(context.getPackageManager())) {
            context.startActivity(intent);
        }
    }
 
    /**
     * 通过Intent启动系统日历来查看指定ID的事件
     *
     * @param eventID 要查看的事件ID
     */
    public static void startCalendarForIntentToView(Context context, long eventID) {
        checkCalendarAccount(context);
 
        Uri uri = ContentUris.withAppendedId(CalendarContract.Events.CONTENT_URI, eventID);
        Intent intent = new Intent(Intent.ACTION_VIEW).setData(uri);
 
        if (null != intent.resolveActivity(context.getPackageManager())) {
            context.startActivity(intent);
        }
    }
 
 
    // ----------------------------- 日历账户名相关设置 -----------------------------------
 
    public static String getCalendarName() {
        return CALENDAR_NAME;
    }
 
    public static void setCalendarName(String calendarName) {
        CALENDAR_NAME = calendarName;
    }
 
    public static String getCalendarAccountName() {
        return CALENDAR_ACCOUNT_NAME;
    }
 
    public static void setCalendarAccountName(String calendarAccountName) {
        CALENDAR_ACCOUNT_NAME = calendarAccountName;
    }
 
    public static String getCalendarDisplayName() {
        return CALENDAR_DISPLAY_NAME;
    }
 
    public static void setCalendarDisplayName(String calendarDisplayName) {
        CALENDAR_DISPLAY_NAME = calendarDisplayName;
    }
 
}

5、CalendarEvent类

public class CalendarEvent {
 
    // ----------------------- 事件属性 -----------------------
 
    /**
     * 事件在表中的ID
     */
    private long id;
    /**
     * 事件所属日历账户的ID
     */
    private long calID;
    private String title;
    private String description;
    private String eventLocation;
    private int displayColor;
    private int status;
    private long start;
    private long end;
    private String duration;
    private String eventTimeZone;
    private String eventEndTimeZone;
    private int allDay;
    private int accessLevel;
    private int availability;
    private int hasAlarm;
    private String rRule;
    private String rDate;
    private int hasAttendeeData;
    private int lastDate;
    private String organizer;
    private String isOrganizer;
 
 
    // ----------------------------------------------------------------------------------------
    /**
     * 注:此属性不属于CalendarEvent
     * 这里只是为了方便构造方法提供事件提醒时间
     */
    private int advanceTime;
    // ----------------------------------------------------------------------------------------
 
 
    // ----------------------- 事件提醒属性 -----------------------
    private List<EventReminders> reminders;
 
    CalendarEvent() {
    }
 
    /**
     * 用于方便添加完整日历事件提供一个构造方法
     *
     * @param title         事件标题
     * @param description   事件描述
     * @param eventLocation 事件地点
     * @param start         事件开始时间
     * @param end           事件结束时间  If is not a repeat event, this param is must need else null
     * @param advanceTime   事件提醒时间{@link AdvanceTime}
     *                      (If you don't need to remind the incoming parameters -2)
     * @param rRule         事件重复规则  {@link RRuleConstant}  {@code null} if dose not need
     */
    public CalendarEvent(String title, String description, String eventLocation,
                         long start, long end, int advanceTime, String rRule) {
        this.title = title;
        this.description = description;
        this.eventLocation = eventLocation;
        this.start = start;
        this.end = end;
        this.advanceTime = advanceTime;
        this.rRule = rRule;
    }
 
    public int getAdvanceTime() {
        return advanceTime;
    }
 
    public void setAdvanceTime(int advanceTime) {
        this.advanceTime = advanceTime;
    }
 
    public long getId() {
        return id;
    }
 
    void setId(long id) {
        this.id = id;
    }
 
    public long getCalID() {
        return calID;
    }
 
    void setCalID(long calID) {
        this.calID = calID;
    }
 
    public String getTitle() {
        return title;
    }
 
    void setTitle(String title) {
        this.title = title;
    }
 
    public String getDescription() {
        return description;
    }
 
    void setDescription(String description) {
        this.description = description;
    }
 
    public String getEventLocation() {
        return eventLocation;
    }
 
    void setEventLocation(String eventLocation) {
        this.eventLocation = eventLocation;
    }
 
    public int getDisplayColor() {
        return displayColor;
    }
 
    void setDisplayColor(int displayColor) {
        this.displayColor = displayColor;
    }
 
    public int getStatus() {
        return status;
    }
 
    void setStatus(int status) {
        this.status = status;
    }
 
    public long getStart() {
        return start;
    }
 
    void setStart(long start) {
        this.start = start;
    }
 
    public long getEnd() {
        return end;
    }
 
    void setEnd(long end) {
        this.end = end;
    }
 
    public String getDuration() {
        return duration;
    }
 
    void setDuration(String duration) {
        this.duration = duration;
    }
 
    public String getEventTimeZone() {
        return eventTimeZone;
    }
 
    void setEventTimeZone(String eventTimeZone) {
        this.eventTimeZone = eventTimeZone;
    }
 
    public String getEventEndTimeZone() {
        return eventEndTimeZone;
    }
 
    void setEventEndTimeZone(String eventEndTimeZone) {
        this.eventEndTimeZone = eventEndTimeZone;
    }
 
    public int getAllDay() {
        return allDay;
    }
 
    void setAllDay(int allDay) {
        this.allDay = allDay;
    }
 
    public int getAccessLevel() {
        return accessLevel;
    }
 
    void setAccessLevel(int accessLevel) {
        this.accessLevel = accessLevel;
    }
 
    public int getAvailability() {
        return availability;
    }
 
    void setAvailability(int availability) {
        this.availability = availability;
    }
 
    public int getHasAlarm() {
        return hasAlarm;
    }
 
    void setHasAlarm(int hasAlarm) {
        this.hasAlarm = hasAlarm;
    }
 
    public String getRRule() {
        return rRule;
    }
 
    void setRRule(String rRule) {
        this.rRule = rRule;
    }
 
    public String getRDate() {
        return rDate;
    }
 
    void setRDate(String rDate) {
        this.rDate = rDate;
    }
 
    public int getHasAttendeeData() {
        return hasAttendeeData;
    }
 
    void setHasAttendeeData(int hasAttendeeData) {
        this.hasAttendeeData = hasAttendeeData;
    }
 
    public int getLastDate() {
        return lastDate;
    }
 
    void setLastDate(int lastDate) {
        this.lastDate = lastDate;
    }
 
    public String getOrganizer() {
        return organizer;
    }
 
    void setOrganizer(String organizer) {
        this.organizer = organizer;
    }
 
    public String getIsOrganizer() {
        return isOrganizer;
    }
 
    void setIsOrganizer(String isOrganizer) {
        this.isOrganizer = isOrganizer;
    }
 
    public List<EventReminders> getReminders() {
        return reminders;
    }
 
    void setReminders(List<EventReminders> reminders) {
        this.reminders = reminders;
    }
 
    @NonNull
    @Override
    public String toString() {
        return "CalendarEvent{" +
                "\n id=" + id +
                "\n calID=" + calID +
                "\n title='" + title + '\'' +
                "\n description='" + description + '\'' +
                "\n eventLocation='" + eventLocation + '\'' +
                "\n displayColor=" + displayColor +
                "\n status=" + status +
                "\n start=" + start +
                "\n end=" + end +
                "\n duration='" + duration + '\'' +
                "\n eventTimeZone='" + eventTimeZone + '\'' +
                "\n eventEndTimeZone='" + eventEndTimeZone + '\'' +
                "\n allDay=" + allDay +
                "\n accessLevel=" + accessLevel +
                "\n availability=" + availability +
                "\n hasAlarm=" + hasAlarm +
                "\n rRule='" + rRule + '\'' +
                "\n rDate='" + rDate + '\'' +
                "\n hasAttendeeData=" + hasAttendeeData +
                "\n lastDate=" + lastDate +
                "\n organizer='" + organizer + '\'' +
                "\n isOrganizer='" + isOrganizer + '\'' +
                "\n reminders=" + reminders +
                '}';
    }
 
    @Override
    public int hashCode() {
        return (int) (id * 37 + calID);
    }
 
    /**
     * 事件提醒
     */
    static class EventReminders {
 
        // ----------------------- 事件提醒属性 -----------------------
        private long reminderId;
        private long reminderEventID;
        private int reminderMinute;
        private int reminderMethod;
 
        public long getReminderId() {
            return reminderId;
        }
 
        void setReminderId(long reminderId) {
            this.reminderId = reminderId;
        }
 
        public long getReminderEventID() {
            return reminderEventID;
        }
 
        void setReminderEventID(long reminderEventID) {
            this.reminderEventID = reminderEventID;
        }
 
        public int getReminderMinute() {
            return reminderMinute;
        }
 
        void setReminderMinute(int reminderMinute) {
            this.reminderMinute = reminderMinute;
        }
 
        public int getReminderMethod() {
            return reminderMethod;
        }
 
        void setReminderMethod(int reminderMethod) {
            this.reminderMethod = reminderMethod;
        }
 
    }
 
}

6、Util类

public class Util {
 
    /**
     * 获取日历事件结束日期
     *
     * @param time time in ms
     */
    private static String getEndDate(long time) {
        Date date = new Date(time);
        SimpleDateFormat format = new SimpleDateFormat("yyyyMMdd", Locale.getDefault());
        return format.format(date);
    }
 
    /**
     * 获取最终日历事件重复规则
     *
     * @param time time in ms
     *             "T235959" {@linkplain com.kyle.calendarprovider.calendar.RRuleConstant #51}
     */
    public static String getFinalRRuleMode(long time) {
        return getEndDate(time) + "T235959Z";
    }
 
    /**
     * 格式化星期
     */
    private static String formatWeek(int week) {
        switch (week) {
            case 0:
                return "SU";
            case 1:
                return "MO";
            case 2:
                return "TU";
            case 3:
                return "WE";
            case 4:
                return "TH";
            case 5:
                return "FR";
            case 6:
                return "SA";
            default:
                return null;
        }
    }
 
    /**
     * 获取重复周
     *
     * @param time time in ms
     */
    public static String getWeekForDate(long time) {
        Date date = new Date(time);
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        int week = calendar.get(Calendar.DAY_OF_WEEK) - 1;
        if (week < 0) {
            week = 0;
        }
        return formatWeek(week);
    }
 
    /**
     * 获取指定时间段在一个月中的哪一天
     *
     * @param time time in ms
     */
    public static int getDayOfMonth(long time) {
        Date date = new Date(time);
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        return calendar.get(Calendar.DAY_OF_MONTH);
    }
 
    /**
     * check null
     */
    public static void checkContextNull(Context context) {
        if (null == context) {
            throw new IllegalArgumentException("context can not be null");
        }
    }
 
}

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持程序员的世界。

Android实现系统日历同步日程的更多相关文章

  1. Android 中 WebView 的基本用法详解

    加载 URL (网络或者本地 assets 文件夹下的 html 文件)加载 html 代码Native 和 JavaScript 相互调用加载网络 URLwebview.loadUrl(https://www.baidu.com/);加载 assets 下的 html 文件webview.load......

  2. Android事件分发机制全面解析

    事件分发机制事件分发机制的两个阶段:分发:事件从父视图往子视图分发,被拦截后不再传递,进入回溯阶段回溯:事件从子视图往父视图回溯,被消费后不再回溯关键方法:ViewGroup.dispatchTouchEvent 往子视图分发事件ViewGroup.onInterceptTouchEvent 返回 ......

  3. android加密参数定位实现方法

    在逆向一个Android程序时,如果只是盲目的分析需要阅读N多代码才能找到程序的关键点或Hook点,本文将分享一下如何快速的找到APP程序的加密参数位置,其实不论是找关键位置、找hook点,找加密参数、代码逻辑追踪,都是类似的处理方法。巧用搜索-静态分析一般静态分析找加密参数的流程都是先查壳(脱壳)......

  4. Android 简单服务定位器模式实现

    依赖注入(Dependency Injection)和服务定位器(Service Locator)是实现控制反转(Inversion of Control)的两种主要手段。Android的主流依赖注入框架有:Dagger 和 Kion这些依赖注入框架都感觉比较重。服务定位器比如少见,这里提供一个一个......

  5. Kotlin + Flow 实现Android 应用初始化任务启动库

    特性Kotlin + Flow 实现的 Android 应用初始化任务启动库。支持模块化,按模块加载任务可指定工作进程名称,main 表示仅在主进程运行,all 表示在所有进程运行,默认值all可指定任务仅在工作线程执行可指定任务仅在调试模式执行可指定任务在满足合规条件后执行可指定任务优先级,决定同......

  6. Android实现view拖动到任意位置

    本文实现:将图片任意拖动,如果拖动到正确位置则成功,若抬起手时时错误位置则自动回到原位。定义private ImageView img;private ImageView imageView;//容器的宽高,需要在屏幕绘制好之后才能获取private int containerWidth;priva......

  7. Android 实现签到足迹功能

    UI 妹纸又给了个图叫我做,我一看是这样的:我们首先把这个控件划分成 几个部分:1.底下部分的直线 :2.左右两边的半圆弧度 :3.线上面的小图标 :4.最后的文字说明 :首先我们把线画出来,大概这个样子我们这里根据一个月得总天数,和一条线上需要画七个图,计算出总共需要画出的线条......

  8. Android开发之AppWidget详解

    Android通知系统是它的一大特色,而其中,AppWidget是其中一个亮点。在开发应用的中,很多时候可以为其添加一个AppWidget显示在桌面中,及时方便的与用户进行交互。这里就简单的熟悉一下开发一个AppWidget的流程吧。想要在应用中创建一个AppWidget,至少需要以下几样东西:需要......

  9. Android如何判断页面是否全屏

    Android 想判断 Activity 是否是全屏,网上找了些方法,看到有直接获取 flags 和一个具体的值比较,并没有用,其实分析下来也觉得应该不对。大多都是如何设置全屏和取消全屏,并没有判断是否全屏的方法。其实全屏控制要么通过主题设置,要么代码 addFlags,最终都会到 Window 的......

  10. 详解Android Lint的原理及其使用

    Android Lint 原理及使用详解Android Lint 是 ADT 16中引入的新工具,用于扫描 Android 项目源中的潜在错误。Lint 是 Android 提供的一个强大的,用于静态扫描应用源码并找出其中的潜在问题的实用工具。lint 工具可以检查你的 Android 项目源文件是......

随机推荐

  1. Android 实现抢购倒计时功能的示例

    一、效果图二、思路算多少秒,秒数取余60,(满足分后剩下的秒数)算多少分,秒数除60,再取余60 (总分数满足小时后剩下的分数)算多少时,秒数除60,除60,再取余24 (总小时满足天后剩下的小时)算多少天,秒数除60,除60,除24 等到的整数就是天数三、实现步骤:我们这里的时间格式为后台返回,格......

  2. MySQL GTID主备不一致的修复方案

    方案一:重建 ReplicasMySQL 5.6及以上版在复制中引入了新的全局事务ID(GTID)支持。 在启用了GTID模式的情况下执行MySQL和MySQL 5.7的备份时,Percona XtraBackup会自动将GTID值存储在xtrabackup_binlog_info中。 该信息可用于......

  3. html实现随机点名器的示例代码

    此点名器开始点名后需点击停止按钮完成点名,因为是精简版没有考虑自动停止需求。姓名数据以字符串形式储存,适合小范围点名使用,有大量需求可自己适当改进。<head><meta charset="UTF-8"><meta name="viewpo......

  4. spring使用RedisTemplate操作Redis数据库

    一.什么是RedisRedis是一个非关系型数据库,具有很高的存取性能,一般用作缓存数据库,减少正常存储数据库的压力。Redis可以存储键与5种不同数据结构类型之间的映射,这5种数据结构类型分别为String(字符串)、List(列表)、Set(集合)、Hash(散列)和 Zset(有序集合)。下面......

  5. Python列表推导式玩法

    前言列表做为python的基础,是必须学习的语法之一。一些基础的之前已经是反复温习和使用了,今天我们来学习它的进阶版--》列表推导式。列表推导式:优点:是将所有的值一次性加载到内存中,相比于for循环生成的列表执行速度快,并且语法精简,一行代码就完成for循环多行代码所要完成的事情。缺点:代码的可阅......

  6. 动态主机配置协议DHCP

    一---导读在日常生活中我们使用电脑,当我们连接到一个新的网络的时候,你知道中间发生了什么,最终你可以上网的吗?一个主机想要上网,需要如下配置信息:IP地址,子网掩码,默认网关,DNS服务器。如果手动去配置这些,容易出错还麻烦,这时就有一个解放人类双手的好工具-DHCP服务器,可为局域网主机中各主机......

  7. 使用 C# 9 的records作为强类型ID - JSON序列化

    在本系列的上一篇文章中,我们注意到强类型ID的实体,序列化为 JSON 的时候报错了,就像这样:{"id": {"value": 1},"name": "Apple","unitPrice": 0.8......

  8. php微信小程序解包过程实例详解

    这个解包只能看个大概1.找到小程序压缩包1.1、手机root或安装模拟器(我用的是夜神)1.2、在模拟器上安装微信(用android5系统的模拟器,低版本小程序容易打不开)1.3、打开登陆微信后,打开小程序1.4、打开模拟器自带的文件管理器来到目录:/data/data/com.tencent.mm......

  9. Python的flask接收前台的ajax的post数据和get数据的方法

    ajax向后台发送数据:①post方式ajax:@app.route("/find_worldByName",methods=['POST'])type:'post',data:{'cname':cname,'continent':continent},这是post方式传值那么在......

  10. JavaScript——深入了解this

    前言我曾以为func()其实就是window.func()function func(){console.log('this : ' + this);}func();//this : [object Window]window.func();//this : [object Window] 直到'u......