同步Android手机系统日历事件(日程)

本文介绍如何在Android应用中同步手机系统日历日程,包括添加权限、适配不同版本的URL路径、查询数据库及处理查询结果的具体实现。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

之前开发的应用要求的一个功能是同步手机系统日历日程,发现网上也没什么总结好的答案,查阅了些资资料没有发现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(){
         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);
//            }
        }
    }

    

 
这段代码可以获取指点日期的系统日历事件,对于开始时间在指定日期 的重复事件也可以读出,当鉴于本人能力有限没有能解决了重复事件rrule规则,对于重复事件的处理还不完善,哪位大神有好方法,解决重复日程的问题,请指教

评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值