本文介紹如何在Android App中添加或刪除一個提前10分鐘提醒的日曆日程。
實現分爲兩部分:申請Calendar權限;添加或刪除日曆日程。
相關知識:Android申請權限
一、申請Calendar權限
Calendar權限屬於系統權限中的危險權限,既要在AndroidManifest.xml文件中註冊權限,又要動態申請權限。
1、AndroidManifest.xml文件中註冊:
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:dist="http://schemas.android.com/apk/distribution"
package="com.xu.jin.addcalendarreminddemo">
<uses-permission android:name="android.permission.READ_CALENDAR" />
<uses-permission android:name="android.permission.WRITE_CALENDAR" />
……
<application>… </application>
</manifest>
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!