Android 添加Calendar日历提醒事件

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

 

你可能感兴趣的:(Android 添加Calendar日历提醒事件)