本文介绍如何在Android App中添加或删除一个提前10分钟提醒的日历日程。
实现分为两部分:申请Calendar权限;添加或删除日历日程。
相关知识:Android申请权限
完整代码下载
一、申请Calendar权限
Calendar权限属于系统权限中的危险权限,既要在AndroidManifest.xml文件中注册权限,又要动态申请权限。
1、AndroidManifest.xml文件中注册:
……
…
2、动态申请权限:
点击按钮时判断是否拥有权限:有-->添加/删除日程;无-->申请权限,申请成功后再添加/删除日程。
本例子的动态申请权限在fragment中完成。
mButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
int requestCode = 100;
int checkSelfPermission_calendar_write,checkSelfPermission_calendar_read;
try {
checkSelfPermission_calendar_write = ActivityCompat.checkSelfPermission(getContext(), Manifest.permission.WRITE_CALENDAR);
checkSelfPermission_calendar_read = ActivityCompat.checkSelfPermission(getContext(),Manifest.permission.READ_CALENDAR);
} catch (RuntimeException e) {
e.printStackTrace();
return;
}
// 如果有授权,走正常插入日历逻辑
if ((checkSelfPermission_calendar_read == PackageManager.PERMISSION_GRANTED)
&&(checkSelfPermission_calendar_write == PackageManager.PERMISSION_GRANTED)){
SetAutoRemindAsyncTask task = new SetAutoRemindAsyncTask(getContext(),mPara);
task.execute();
return;
} else {
// 如果没有授权,就请求用户授权
requestPermissions(new String[]{Manifest.permission.WRITE_CALENDAR,
Manifest.permission.READ_CALENDAR}, requestCode);
}
}
});
/*授权申请结果回调*/
@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
if (grantResults[0] == 0 && grantResults[1] == 0)/*Calendar读写申请成功*/
{
/*向calendar中写入提醒事件*/
SetAutoRemindAsyncTask task = new SetAutoRemindAsyncTask(getContext(),mPara);
task.execute();
}
}
二、添加/删除日历日程
我们在SetAutoRemindAsyncTask 中实现添加/删除日历日程。SetAutoRemindAsyncTask根据入参操作日历日程,并返回新增日程的eventId,供删除日程使用。
实现分为两部分:获取日历账户;添加/删除日历日程。
1、获取日历账户。
private static String CALENDAR_URL = "content://com.android.calendar/calendars";
private static String CALENDAR_EVENT_URL = "content://com.android.calendar/events";
private static String CALENDAR_REMINDER_URL = "content://com.android.calendar/reminders";
private static String CALENDARS_NAME = "mang";
private static String CALENDARS_ACCOUNT_NAME = "[email protected]";
private static String CALENDARS_ACCOUNT_TYPE = "com.android.mang";
private static String CALENDARS_DISPLAY_NAME = "mang";
public static int checkAndAddCalendarAccount(Context context) {
int id = checkCalendarAccount(context);
if (id != -1) return id;
else return (int)addCalendarAccount(context);
}
private static int checkCalendarAccount(Context context) {
Cursor userCursor = context.getContentResolver().query(Uri.parse(CALENDAR_URL),
null, null, null, null);
try {
if (userCursor == null) { // 查询返回空值
return -1;
}
int count = userCursor.getCount();
if (count > 0) { // 存在现有账户,取第一个账户的id返回
userCursor.moveToFirst();
return userCursor.getInt(userCursor.getColumnIndex(CalendarContract.Calendars._ID));
} else {
return -1;
}
} finally {
if (userCursor != null) {
userCursor.close();
}
}
}
private static long addCalendarAccount(Context context) {
TimeZone timeZone = TimeZone.getDefault();
ContentValues value = new 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.getID());
value.put(CalendarContract.Calendars.OWNER_ACCOUNT, CALENDARS_ACCOUNT_NAME);
value.put(CalendarContract.Calendars.CAN_ORGANIZER_RESPOND, 0);
Uri calendarUri = Uri.parse(CALENDAR_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();
Uri result = context.getContentResolver().insert(calendarUri, value);
long id = result == null ? -1 : ContentUris.parseId(result);
return id;
}
2、添加\删除日历日程。
public void operateCalendar()
{
int calId = checkAndAddCalendarAccount(mContext); // 获取日历账户的id
if (calId < 0) { // 获取账户id失败直接返回,添加日历事件失败
return ;
}
for (RemindPara para : mRParaList) {
if (para.action.equals("add"))
{
insertOneCalendarEvent(mContext, calId, para);
}
else
{
deleteOneCalendarEvent(mContext, para);
}
}
}
public static boolean insertOneCalendarEvent(Context context,int calId,RemindPara para)
{
long eventId = para.remindEventId;
if (eventId == -1)/**/
{
addNewRemindEvent(context,calId,para);
}
else
{
updateRemindEvent(context,calId,para);
}
return true;
}
public static boolean addNewRemindEvent(Context context,int calId,RemindPara para)
{
String beginTime = getTimeString(para,"begin");
String endTime = getTimeString(para,"end");
long beginTimeMillis = Utils.getTimeInMillis(beginTime);
long endTimeMillis = Utils.getTimeInMillis(endTime);
long eventId;
//Log.e(LOG_TAG,"addNewRemindEvent" + scheduleInformation.id + "..." + scheduleInformation.remindEventId+ "..." + mCourseInfo.autoRemind);
try {
/** 插入日程 */
ContentValues eventValues = new ContentValues();
eventValues.put(CalendarContract.Events.DTSTART, beginTimeMillis);
eventValues.put(CalendarContract.Events.DTEND, endTimeMillis);
eventValues.put(CalendarContract.Events.TITLE, para.action);
eventValues.put(CalendarContract.Events.DESCRIPTION, mContext.getString(R.string.app_name));
eventValues.put(CalendarContract.Events.CALENDAR_ID, calId);
eventValues.put(CalendarContract.Events.ACCESS_LEVEL, CalendarContract.Events.ACCESS_DEFAULT);
eventValues.put(CalendarContract.Events.EVENT_LOCATION, "here");
TimeZone tz = TimeZone.getDefault(); // 获取默认时区
eventValues.put(CalendarContract.Events.EVENT_TIMEZONE, tz.getID());
Uri eUri = context.getContentResolver().insert(Uri.parse(CALENDAR_EVENT_URL), eventValues);
eventId = ContentUris.parseId(eUri);
if (eventId == 0) { // 插入失败
return false;
}
mEventId = eventId;
/** 插入提醒 - 依赖插入日程成功 */
ContentValues reminderValues = new ContentValues();
reminderValues.put(CalendarContract.Reminders.EVENT_ID, eventId);
reminderValues.put(CalendarContract.Reminders.MINUTES, para.advanceRemindMinutes); // 提前提醒
reminderValues.put(CalendarContract.Reminders.METHOD,
CalendarContract.Reminders.METHOD_ALERT);
Uri rUri = context.getContentResolver().insert(Uri.parse(CALENDAR_REMINDER_URL),
reminderValues);
if (rUri == null || ContentUris.parseId(rUri) == 0) {
return false;
}
} catch (Exception e) {
e.printStackTrace();
return false;
}
return true;
}
public static boolean updateRemindEvent(Context context,int calId,RemindPara para)
{
String beginTime = getTimeString(para,"begin");
String endTime = getTimeString(para,"end");
long beginTimeMillis = Utils.getTimeInMillis(beginTime);
long endTimeMillis = Utils.getTimeInMillis(endTime);
long eventId = para.remindEventId;
try {
/* 更新日程 */
ContentValues eventValues = new ContentValues();
eventValues.put(CalendarContract.Events.DTSTART, beginTimeMillis);
eventValues.put(CalendarContract.Events.DTEND, endTimeMillis);
eventValues.put(CalendarContract.Events.TITLE, para.action);
eventValues.put(CalendarContract.Events.DESCRIPTION, mContext.getString(R.string.app_name));
eventValues.put(CalendarContract.Events.CALENDAR_ID, calId);
eventValues.put(CalendarContract.Events.ACCESS_LEVEL, CalendarContract.Events.ACCESS_DEFAULT);
eventValues.put(CalendarContract.Events.EVENT_LOCATION, "here");
TimeZone tz = TimeZone.getDefault(); // 获取默认时区
eventValues.put(CalendarContract.Events.EVENT_TIMEZONE, tz.getID());
Uri updateUri = ContentUris.withAppendedId(Uri.parse(CALENDAR_EVENT_URL), eventId);
int rowNum = context.getContentResolver().update(updateUri, eventValues, null, null);
if (rowNum <= 0)/*更新event不成功,说明用户在日历中删除了提醒事件,重新添加*/
{
return addNewRemindEvent(context,calId,para);
}
else
{
/** 更新提醒 - 依赖更新日程成功 */
ContentValues reminderValues = new ContentValues();
reminderValues.put(CalendarContract.Reminders.MINUTES, para.advanceRemindMinutes); // 提前提醒
Uri rUri = Uri.parse(CALENDAR_REMINDER_URL);
context.getContentResolver().update(rUri, reminderValues, CalendarContract.Reminders.EVENT_ID + "= ?", new String[]{String.valueOf(eventId)});
return true;
}
} catch (Exception e) {
e.printStackTrace();
return false;
}
}
public static void deleteOneCalendarEvent(Context context,RemindPara para) {
if (context == null) {
return;
}
if (para.remindEventId == -1)
return;
Uri deleteUri = ContentUris.withAppendedId(Uri.parse(CALENDAR_EVENT_URL), para.remindEventId);
int rows = context.getContentResolver().delete(deleteUri, null, null);
}
-------------------------------------------------------------------
That's all. Thank you!