1.问题背景:最近遇到一个问题,就是要删除Calendar Event 的Instance,但是在看官方Api,发现 google并没有提供删除Instance的接口,也就是,你只能差而不能删除Instance
链接如下:https://developer.android.com/guide/topics/providers/calendar-provider?hl=zh-cn
关系图如下:
从图中我们看到每个Event中对应多个Instances,(所谓的Instance就是每个事件) ,比如,创建一个日常重复的事件,那么就会产生一个Event和无数个Instance
思考:
1.既然不能从Insance去入手删除,那只能从Event入手了,既然系统能删除单个Instance,那一定有一个触发的时机
2.我们在定义重复的repeat Event的时候会去设置rRule,也就是重复规则
3.在Event 中有一个ExDate字段,也就是在设置重复规则的时候会,根据ExDate去将字段中的日期排除
4.那就是说我们只要设置ExDate,就能够排出掉我们想要删除的ExDate。
尝试:
1.直接去Update ExDate
ContentResolver resolver = context.getContentResolver();
Uri eventUri = ContentUris.withAppendedId(CalendarContract.Events.CONTENT_URI, eventId);
values.put(CalendarContract.Events.EXDATE, resultExDate.toString());
发现没有作用。当时做到这边的时候感觉一脸懵逼,觉得官方在骗我,这个根本没用!。
2.后来继续查找资料,发现说ExDate 要跟 DTStart还有RRule一起使用
思考:
1.也就是说单纯设置ExDate的话没办法触发事件的变化
2.那设置DTStart 和Rrule会有什么效果
于是我做了以下尝试:
1.单独更新DTStart
ContentResolver resolver = context.getContentResolver();
Uri eventUri = ContentUris.withAppendedId(CalendarContract.Events.CONTENT_URI, eventId);
values.put(CalendarContract.Events.DTSTART, dStart);
结果:之前的重复事件全部没有了!只剩下当前的startTime的事件‘
2.单独设置rRule,也就是重复规则
ContentResolver resolver = context.getContentResolver();
Uri eventUri = ContentUris.withAppendedId(CalendarContract.Events.CONTENT_URI, eventId);
values.put(CalendarContract.Events.RRULE, rRule);
结果没有效果
3.同时设置DTstart和RRule
结果:生成了一些列重复事件。
思考:
1.从上面的尝试得出结论,DTSTart是触发更新的必要元素
2.单纯设了DTSTart之前的事件会被删除,说明更新后,会有一个删除旧数据然后重新创建的过程
3.结合以上几点,只要同时设置三个参数 ,应该就能达到我们想要的效果,也就是重新制定所有的规则,让他重新生成一些列事件。
尝试:
ContentResolver resolver = context.getContentResolver();
Uri eventUri = ContentUris.withAppendedId(CalendarContract.Events.CONTENT_URI, eventId);
ContentValues values = new ContentValues();
values.put(CalendarContract.Events.DTSTART, dStart);
values.put(CalendarContract.Events.EXDATE, resultExDate.toString());
values.put(CalendarContract.Events.RRULE, rRule);
结果:这个时候还是不行!
不对一定是写代码的姿势不够帅!!!!
继续找答案:发现了这个东西
https://stackoverflow.com/questions/14522393/android-exdate-format-when-adding-a-calendar-event
DtStartTime的格式,发现用的是UTC时间格式,
格式化方式如下:
SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyyMMdd'T'HHmmss'Z'", Locale.getDefault());
simpleDateFormat.setTimeZone(TimeZone.getTimeZone("UTC"));
然后再跑一下。
结果:可行!!!!!!
无敌!!!我真的是无敌,还有谁!!!!!!!
经过一些列的探索,解决了问题,于是我决定,将革命进行到底,去瞅瞅源码
源码分析:主要看CalendarProvider2.java RecurrenceSet CalendarInstancesHelper RecurrenceProcessor
链接如下: