Android实现系统日历同步日程

本文实例为大家分享了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实现系统日历同步日程 的全部内容, 来源链接: utcz.com/p/243501.html

回到顶部