Android 添加Calendar日曆提醒事件

本文介紹如何在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!

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章