这个类 CalendarReminderUtils 是一个工具类,主要用于管理 Android 手机上的日历事件和提醒
。它提供了以下功能:
添加日历事件:
addCalendarEvent(context: Context?, data: ArrayList<ScheduleDetail>):
根据传入的 ScheduleDetail 列表, 在日历中创建新的事件, 并设置提醒。
删除日历事件:
deleteCalendarEvent(context: Context?, startTime: Long, endTime: Long, callBack: DeleteCalendarCallBack):
删除指定时间范围内的所有日历事件。
回调接口:
DeleteCalendarCallBack: 用于在删除日历事件完成时进行回调的接口。
CalendarReminderUtils具体实现:
import ScheduleDetail
import android.annotation.SuppressLint
import android.provider.CalendarContract
import android.content.ContentValues
import android.content.ContentUris
import android.content.Context
import android.graphics.Color
import android.net.Uri
import android.text.TextUtils
import android.util.Log
import android.util.Log.e
import java.lang.Exception
import java.util.*
object CalendarReminderUtils {
private const val CALENDER_URL = "content://com.android.calendar/calendars"
private const val CALENDER_EVENT_URL = "content://com.android.calendar/events"
private const val CALENDER_REMINDER_URL = "content://com.android.calendar/reminders"
private const val CALENDARS_NAME = "android"
private const val CALENDARS_ACCOUNT_NAME = "android.project.cn"
private const val CALENDARS_ACCOUNT_TYPE = "com.android.project"
private const val CALENDARS_DISPLAY_NAME = "android"
private const val PREFIX_CALENDAR_ID = "93285712"
var isCalendarHandle = false
/**
* 检查是否已经添加了日历账户,如果没有添加先添加一个日历账户再查询
* 获取账户成功返回账户id,否则返回-1
*/
private fun checkAndAddCalendarAccount(context: Context): Int {
val oldId = checkCalendarAccount(context)
return if (oldId >= 0) {
oldId
} else {
val addId = addCalendarAccount(context)
if (addId >= 0) {
checkCalendarAccount(context)
} else {
-1
}
}
}
/**
* 检查是否存在现有账户,存在则返回账户id,否则返回-1
*/
@SuppressLint("Range")
private fun checkCalendarAccount(context: Context): Int {
val userCursor = context.contentResolver.query(Uri.parse(CALENDER_URL), null, null, null, null)
return try {
if (userCursor == null) {
return -1
}
val count = userCursor.count
if (count > 0) { //存在现有账户,取第一个账户的id返回
userCursor.moveToFirst()
userCursor.getInt(userCursor.getColumnIndex(CalendarContract.Calendars._ID))
} else {
-1
}
} finally {
userCursor?.close()
}
}
/**
* 添加日历账户,账户创建成功则返回账户id,否则返回-1
*/
private fun addCalendarAccount(context: Context): Long {
if(!isCalendarHandle){
isCalendarHandle = true
val timeZone = TimeZone.getDefault()
val value = ContentValues()
value.put(CalendarContract.Calendars.NAME, CALENDARS_NAME)
value.put(CalendarContract.Calendars.ACCOUNT_NAME, CALENDARS_ACCOUNT_NAME)
value.put(CalendarContract.Calendars.ACCOUNT_TYPE, CALENDARS_ACCOUNT_TYPE)
value.put(CalendarContract.Calendars.CALENDAR_DISPLAY_NAME, CALENDARS_DISPLAY_NAME)
value.put(CalendarContract.Calendars.VISIBLE, 1)
value.put(CalendarContract.Calendars.CALENDAR_COLOR, Color.BLUE)
value.put(CalendarContract.Calendars.CALENDAR_ACCESS_LEVEL, CalendarContract.Calendars.CAL_ACCESS_OWNER)
value.put(CalendarContract.Calendars.SYNC_EVENTS, 1)
value.put(CalendarContract.Calendars.CALENDAR_TIME_ZONE, timeZone.id)
value.put(CalendarContract.Calendars.OWNER_ACCOUNT, CALENDARS_ACCOUNT_NAME)
value.put(CalendarContract.Calendars.CAN_ORGANIZER_RESPOND, 0)
var calendarUri = Uri.parse(CALENDER_URL)
calendarUri = calendarUri.buildUpon()
.appendQueryParameter(CalendarContract.CALLER_IS_SYNCADAPTER, "true")
.appendQueryParameter(CalendarContract.Calendars.ACCOUNT_NAME, CALENDARS_ACCOUNT_NAME)
.appendQueryParameter(CalendarContract.Calendars.ACCOUNT_TYPE, CALENDARS_ACCOUNT_TYPE)
.build()
val result = context.contentResolver.insert(calendarUri, value)
isCalendarHandle = false
return if (result == null) -1 else ContentUris.parseId(result)
}
return -1
}
/**
* 添加日历事件
*/
fun addCalendarEvent(context: Context?, data: ArrayList<ScheduleDetail>) {
try {
if (context == null) {
return
}
val calId = checkAndAddCalendarAccount(context)
if (calId < 0) { //获取账户id失败直接返回,添加日历事件失败
return
}
if (!isCalendarHandle){
isCalendarHandle = true
for (item in data){
val calendarTitle: String = item.name.toString()
//添加日历事件
val mCalendar = Calendar.getInstance()
mCalendar.timeInMillis = item.startTimestamp
val start = mCalendar.time.time
mCalendar.timeInMillis = item.endTimestamp
val end = mCalendar.time.time
val event = ContentValues()
event.put(CalendarContract.Events.TITLE, calendarTitle)
event.put(CalendarContract.Events.EVENT_LOCATION, item.location)
event.put(CalendarContract.Events.DESCRIPTION, item.description)
event.put(CalendarContract.Events.ORIGINAL_ID, PREFIX_CALENDAR_ID+ item.id) //插入数据的id
event.put(CalendarContract.Events.CALENDAR_ID, calId) //插入账户的id
event.put(CalendarContract.Events.DTSTART, start)
event.put(CalendarContract.Events.DTEND, end)
event.put(CalendarContract.Events.HAS_ALARM, 1) //设置有闹钟提醒
event.put(CalendarContract.Events.EVENT_TIMEZONE, "Asia/Shanghai")
val newEvent = context.contentResolver.insert(Uri.parse(CALENDER_EVENT_URL), event)
?: //添加日历事件失败直接返回
return //添加事件
//事件提醒的设定
val values = ContentValues()
values.put(CalendarContract.Reminders.EVENT_ID, ContentUris.parseId(newEvent))
values.put(CalendarContract.Reminders.MINUTES, item.previousMinutes) // 提前previousDate分钟有提醒
values.put(CalendarContract.Reminders.METHOD, CalendarContract.Reminders.METHOD_ALERT)
val uri = context.contentResolver.insert(Uri.parse(CALENDER_REMINDER_URL), values)
?: //添加事件提醒失败直接返回
return
}
isCalendarHandle = false
}
} catch (e: Exception) {
Log.e("jerome",e.message.orEmpty())
isCalendarHandle = false
}
}
/**
* 删除日历事件
*/
@SuppressLint("Range")
fun deleteCalendarEvent(context: Context?, dataIdList: ArrayList<String>?) {
if (context == null || dataIdList == null) {
return
}
val eventCursor = context.contentResolver.query(Uri.parse(CALENDER_EVENT_URL), null, null, null, null)
try {
if (eventCursor == null) {
return
}
if (!isCalendarHandle){
isCalendarHandle = true
if (eventCursor.count > 0) {
//遍历所有事件,找到id跟需要查询的id一样的项
eventCursor.moveToFirst()
while (!eventCursor.isAfterLast) {
val eventId = eventCursor.getString(eventCursor.getColumnIndex(CalendarContract.Events.ORIGINAL_ID))
for (item in dataIdList) {
val itemId = PREFIX_CALENDAR_ID + item
if (!TextUtils.isEmpty(itemId) && itemId == eventId) {
val id = eventCursor.getInt(eventCursor.getColumnIndex(CalendarContract.Calendars._ID)) //取得id
val deleteUri = ContentUris.withAppendedId(Uri.parse(CALENDER_EVENT_URL), id.toLong())
val rows = context.contentResolver.delete(deleteUri, null, null)
if (rows == -1) {
Log.e("jerome","日历事件删除失败:$itemId")
}
}
}
eventCursor.moveToNext()
}
}
isCalendarHandle = false
}
} finally {
eventCursor?.close()
isCalendarHandle = false
}
}
/**
* 删除[startTime],[endTime]时间段日历事件
*/
@SuppressLint("Range")
fun deleteCalendarEvent(context: Context?, startTime: Long, endTime: Long, callBack: DeleteCalendarCallBack) {
if (context == null) {
callBack.onDeleteComplete()
return
}
try {
val eventCursor = context.contentResolver.query(Uri.parse(CALENDER_EVENT_URL), null, null, null, null)
eventCursor.use { eventCursor ->
if (eventCursor == null) {
callBack.onDeleteComplete()
return
}
if (!isCalendarHandle){
isCalendarHandle = true
if (eventCursor.count > 0) {
eventCursor.moveToFirst()
while (!eventCursor.isAfterLast) {
val eventId = eventCursor.getString(eventCursor.getColumnIndex(CalendarContract.Events.ORIGINAL_ID))
val dtStart = eventCursor.getLong(eventCursor.getColumnIndex(CalendarContract.Events.DTSTART))
val dtEnd = eventCursor.getLong(eventCursor.getColumnIndex(CalendarContract.Events.DTEND))
if (dtEnd> startTime && dtStart < endTime){
//日历事件在[startTime],[endTime]时间段内
if (eventId.startsWith(PREFIX_CALENDAR_ID)){
//删除添加的日历
val id = eventCursor.getInt(eventCursor.getColumnIndex(CalendarContract.Calendars._ID))
val deleteUri = ContentUris.withAppendedId(Uri.parse(CALENDER_EVENT_URL), id.toLong())
val rows = context.contentResolver.delete(deleteUri, null, null)
if (rows == -1) {
Log.e("jerome","日历事件删除失败:$eventId")
}else{
e("jerome","日历事件删除成功:$eventId")
}
}
}
eventCursor.moveToNext()
}
}
isCalendarHandle = false
}
callBack.onDeleteComplete()
}
}catch (e : Exception){
isCalendarHandle = false
callBack.onDeleteComplete()
Log.d("jerome",e.toString())
}
}
interface DeleteCalendarCallBack {
fun onDeleteComplete()
}
}
需要添加的日历数据:
/**
* 日历详情
* @author jerome
*/
class ScheduleDetail {
var id: String? = null
var name: String? = null//标题
var location: String? = null//位置信息
var startTimestamp: Long = 0//日历事件开始时间
var endTimestamp: Long = 0//日历事件结束时间
var description: String? = null//描述
var previousMinutes: Int = 0//日历提前提醒时间
}
添加日历权限
<uses-permission android:name="android.permission.READ_CALENDAR" />
<uses-permission android:name="android.permission.WRITE_CALENDAR" />
申请日历权限
Manifest.permission.WRITE_CALENDAR, Manifest.permission.READ_CALENDAR
调用方式:
if (!CalendarReminderUtils.isCalendarHandle) {
Thread {
//按时间删除日历
CalendarReminderUtils.deleteCalendarEvent(
context, startTime, endTime,
object : CalendarReminderUtils.DeleteCalendarCallBack {
override fun onDeleteComplete() {
//添加日历
CalendarReminderUtils.addCalendarEvent(context, data)
}
})
}.start()
}
总的来说, 这个类提供了一系列方法, 用于管理手机上的日历, 包括添加、删除事件, 以及账户的查询和添加等功能。它可以在 Android 应用中被用来方便地操作用户的日历信息。