之前开发的应用要求的一个功能是同步手机系统日历日程,发现网上也没什么总结好的答案,查阅了些资资料没有发现Android有获取指定日期事件的方法,于是自己就研究了一番。
1、先在Android的配置文件中添加读取日历的权限
<!--读取与写入系统日历权限--> <uses-permission android:name="android.permission.READ_CALENDAR" /> <uses-permission android:name="android.permission.WRITE_CALENDAR" />2、不同版本的日历URL路径:
if (Integer.parseInt(Build.VERSION.SDK) >= 8) { calanderEventURL = "content://com.android.calendar/events"; } else { calanderEventURL = "content://calendar/events"; }3、我通过handler_message机制发送消息查询数据库,在查询数据库之前对于于Android6.0以后的系统,要先判断相应的权限是否打开,判断代码如下
int result = 0; if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.M) { result = mContext.checkSelfPermission("android.permission.READ_CALENDAR"); }如果result为0的话说明相应的权限已打开,若不为0,则未打开,即可不进行查询或通知用户打开相应权限等后续操作
4、查询数据库
private List<Event> events=new ArrayList<>;//存储查询结果 public void query(){这段代码可以获取指点日期的系统日历事件,对于开始时间在指定日期 的重复事件也可以读出,当鉴于本人能力有限没有能解决了重复事件rrule规则,对于重复事件的处理还不完善,哪位大神有好方法,解决重复日程的问题,请指教Uri uri = Uri.parse(url); //查询所有事件 String selection = "((" + CalendarContract.Events.DTSTART + " <> ?)And(" + CalendarContract.Events.CALENDAR_ID + "<>?))"; // MyLog.e("string", selection); Cursor cursor = cr.query(uri, null, selection, new String[]{"null", "3"}, null); while (cursor.moveToNext()) { String duration = cursor.getString(cursor.getColumnIndex(CalendarContract.Events.DURATION)); if (!TextUtils.isEmpty(duration)) { //重复事件 结束时间为null 有重复的type和规则 setRepeatEvents(cursor, startTime); } else if (TextUtils.isEmpty(duration)) { //正常事件 一定存在开始结束时间 setNormalEvents(cursor, startTime, EndTime); } } if (cursor != null && !cursor.isClosed()) { cursor.close(); } Message msg = new Message(); msg.what = MainActivity.QUERY_SYSTEM_EVENTS; msg.obj = events;; handler.sendMessage(msg); }
}
//开始时间和结束时间是13位时间戳private void setNormalEvents(Cursor cursor, String startTime, String EndTime) { Event bean = new Event(); long dstart = Long.parseLong(cursor.getString(cursor.getColumnIndex(CalendarContract.Events.DTSTART))); long dtend = Long.parseLong(cursor.getString(cursor.getColumnIndex(CalendarContract.Events.DTEND))); long start = Long.parseLong(startTime); long end = Long.parseLong(EndTime); //事件包含在当天 String allday = cursor.getString(cursor.getColumnIndex(CalendarContract.Events.ALL_DAY)); if ("1".equals(allday)) {//全天事件 if (dstart > start && dstart < end && dtend > end) { setBasedate(cursor, bean); } } else {//在当天的正常事件 if (dstart > start && dtend < end && dstart < dtend) { setBasedate(cursor, bean); } else if (dstart < start && dtend > start && dtend < end) { setBasedate(cursor, bean); } else if (dstart < start && dtend > end) { setBasedate(cursor, bean); } else if (dstart > start && dstart < end && dtend > end) { setBasedate(cursor, bean); } } } /** * 设置基本数据 * * @param cursor * @param bean */ private void setBasedate(Cursor cursor, Event bean) { bean.set_id(cursor.getString(cursor.getColumnIndex(CalendarContract.Events._ID))); bean.setTitle(cursor.getString(cursor.getColumnIndex(CalendarContract.Events.TITLE))); bean.setStart_time(cursor.getString(cursor.getColumnIndex(CalendarContract.Events.DTSTART))); bean.setEnd_time(cursor.getString(cursor.getColumnIndex(CalendarContract.Events.DTEND))); //全天事件 bean.setAllday(cursor.getString(cursor.getColumnIndex(CalendarContract.Events.ALL_DAY))); //重复事件 bean.setRepeatRule(cursor.getString(cursor.getColumnIndex(CalendarContract.Events.RRULE))); events.add(bean); // MyLog.e("params", bean.toString()); } //重复事件重复规则没有找到好方法进行解析还在研究中 private void setRepeatEvents(Cursor cursor, String startTime) { Event bean = new Event(); long start = Long.parseLong(startTime); long dstart = Long.parseLong(cursor.getString(cursor.getColumnIndex(CalendarContract.Events.DTSTART))); if (MyTimeUtil.isSameDayOfMillis(start, dstart)) {//重复事件的起始天显示 setBasedate(cursor, bean); } else if (dstart < start) {//重复的全天事件 //TODO // String allday = cursor.getString(cursor.getColumnIndex(CalendarContract.Events.ALL_DAY)); // if ("1".equals(allday)) { // setBasedate(cursor, bean); // } } }