Android Calendar Provider(日历事件)
来源:互联网 发布:ubuntu如何重置系统 编辑:程序博客网 时间:2024/05/22 00:37
这篇文章的目的
写这篇文章的目的,主要是为了记录在日历事件中遇到的2个比较少见,在网上比较难查找资料的问题。
应用背景:
在应用中通过ContentProvider操作系统日历,向系统日历中添加、更新、删除日程事件。
所以应用中的日程事件,是与系统日历中的事件同步的。
问题1:
为应用不同的登录账号添加日历账号,用此日历账号在应用中添加日程事件,然后应用切换账号,日程事件消失。
问题2:
删除日历事件后,系统日历中已经删除,但在应用中通过ContentProvider还能查询到(小米、魅族、联想一些国产手机没有这个问题,三星有)。
Calendar Provider的详细操作,参见官方文章:
http://developer.android.com/guide/topics/providers/calendar-provider.html
对应的中文译文:
http://www.cnblogs.com/popapa/p/android_calendar-provider.html#sync-adapter
问题1
问题描述:
为应用不同的登录账号添加日历账号,用此日历账号在应用中添加日程事件,然后应用切换账号,日程事件消失。
问题原因:
这个问题,应该是(猜想)和Android系统日历的账号管理有关。
在项目中,添加日历账号的代码如下所示
private long addCalendarAccount(Context context) { boolean has_permission = Utils.hasPermission(context, "android.permission.WRITE_CALENDAR"); if (!has_permission) { Utils.toast(context, R.string.calendar_disable_hint); return -1; } TimeZone timeZone = TimeZone.getDefault(); ContentValues value = new ContentValues(); value.put(Calendars.NAME, CALENDARS_NAME); value.put(Calendars.ACCOUNT_NAME, CALENDARS_ACCOUNT_NAME); value.put(Calendars.ACCOUNT_TYPE, CalendarContract.ACCOUNT_TYPE_LOCAL); value.put(Calendars.CALENDAR_DISPLAY_NAME, CALENDARS_DISPLAY_NAME); value.put(Calendars.VISIBLE, 1); value.put(Calendars.CALENDAR_COLOR, Color.BLUE); value.put(Calendars.CALENDAR_ACCESS_LEVEL, Calendars.CAL_ACCESS_OWNER); value.put(Calendars.SYNC_EVENTS, 1); value.put(Calendars.CALENDAR_TIME_ZONE, timeZone.getID()); value.put(Calendars.OWNER_ACCOUNT, CALENDARS_ACCOUNT_NAME); value.put(Calendars.CAN_ORGANIZER_RESPOND, 0); Uri calendarUri = Uri.parse(uri); calendarUri = calendarUri.buildUpon().appendQueryParameter(CALLER_IS_SYNCADAPTER, "true") .appendQueryParameter(Calendars.ACCOUNT_NAME, CALENDARS_ACCOUNT_NAME) .appendQueryParameter(Calendars.ACCOUNT_TYPE, CalendarContract.ACCOUNT_TYPE_LOCAL).build(); Uri result = context.getContentResolver().insert(calendarUri, value); long id = result == null ? -1 : ContentUris.parseId(result); return id;}
有一句设置账号类型的代码:
value.put(Calendars.ACCOUNT_TYPE, CalendarContract.ACCOUNT_TYPE_LOCAL);
其中Calendars.ACCOUNT_TYPE的说明如下图:
说明中有一句英文:
A type of ACCOUNT_TYPE_LOCAL will keep this event form being deleted if there are no matching accounts on the device.
大意是:
当ACCOUNT_TYPE为ACCOUNT_TYPE_LOCAL时,可以防止在设备中没有找到账号时日程事件被删除。
解决方案:
因此,问题1的解决方案就是设置ACCOUNT_TYPE为ACCOUNT_TYPE_LOCAL:
value.put(Calendars.ACCOUNT_TYPE, CalendarContract.ACCOUNT_TYPE_LOCAL);
问题2
问题描述:
删除日历事件后,系统日历中已经删除,但在应用中通过ContentProvider还能查询到(小米、魅族、联想一些国产手机没有这个问题,三星有)。
这个问题,在网上找了很长时间,都没有找到相应的资料,在最后快要放弃的时候,在Stackoverflow上找到了解决办法。
http://stackoverflow.com/questions/22554130/calendar-deleted-event-exists-in-cursor
其实问题修改起来很简单,因为日程事件删除之后,系统并没有真的删除,只是对把标示删除的字段改了而已,也就是只做了逻辑删除,而没有做物理删除。
小米、魅族、联想一些国产手机没有这个问题的原因,可能是国产手机的系统定制化高,查询的时候,已经对这个问题进行了处理,而三星没有处理。
其实这个问题,如果会阅读源码的话,花些时间,放些耐心应该是可以从源码中分析出来的,所有阅读源码还是很有必要的。
解决方案:
清楚问题原因之后,解决方案其实很简单,就是查询的时候,再过滤一下,增加查询条件(deleted != 1)就OK了。
比如应用中查询的代码
private void fillData(Context context, String selection, String[] selectionArgs, List<CalendarEvent> calendarEvents) { selection+=" and (deleted != 1)"; Cursor cursor = context.getContentResolver().query(Uri.parse(eventUri),null, selection, selectionArgs, null); if (cursor.moveToFirst()) { do { CalendarEvent calendarEvent=new CalendarEvent(); String title = cursor.getString(cursor.getColumnIndex(Events.TITLE)); String description = cursor.getString(cursor.getColumnIndex(Events.DESCRIPTION)); String repeat = cursor.getString(cursor.getColumnIndex(Events.RRULE)); long eventId = cursor.getLong(cursor.getColumnIndex(Events._ID)); long beginTime = cursor.getLong(cursor.getColumnIndex(Events.DTSTART)); long endTime = cursor.getLong(cursor.getColumnIndex(Events.DTEND)); int remind = getRemindMunites(context, eventId); calendarEvent.setEventId(eventId); calendarEvent.setDescription(description); calendarEvent.setTitle(title); calendarEvent.setBeginTime(beginTime); calendarEvent.setEndTime(endTime); calendarEvent.setRemind(remind); calendarEvent.setRepeat(repeat); calendarEvent.setCalendarId(cursor.getLong(cursor.getColumnIndex(Events.CALENDAR_ID))); calendarEvents.add(calendarEvent); } while (cursor.moveToNext()); } cursor.close();}
结束
文章就写到这里,附上添加、修改、删除日程时间完整Demo,点击下载。
如果需要查询日程时间操作的详细资料,参见官方文章:
http://developer.android.com/guide/topics/providers/calendar-provider.html
对应的中文译文:
http://www.cnblogs.com/popapa/p/android_calendar-provider.html#sync-adapter
- Android Calendar Provider(日历事件)
- Calendar Provider 日历数据存储
- 往系统日历中增加与删除事件提醒,Calendar Provider 实现
- Android Calendar Provider基础
- Android Calendar Provider总结
- Calendar Provider(日历提供器)
- Android API Guides---Calendar Provider
- Android日历(Calendar,dataPicker)
- Android中的Calendar日历控件
- Calendar Provider
- Android 4.0日历(calendar)源码分析之CalendarController(事件分发)
- Android - Calendar Provider(未完待续)
- Android官方文档之Calendar Provider
- 日历Calendar
- Android学习笔记(27):日历视图Calendar
- Android源码之 Calendar日历 修改<一>
- Android日历事件提醒
- OpenCart之日历事件(Event Calendar)模块插件
- TensorFlow-BatchNormalization
- context:component-scan标签的use-default-filters属性的作用以及原理
- 一些社交软件介绍
- 数据库的增删改查案例
- C语言实现应用程序开机自启动(写进注册表)
- Android Calendar Provider(日历事件)
- 数组的合并
- 动态规划:击鼓传花
- Codeforces Round #407 (Div. 2) D Weird journey [dfs]
- POJ-1852 ants
- Java读写.properties文件实例,解决中文乱码问题
- A Bug's Life (分组 并查集)
- HDU2795 Billboard(线段树单点更新,区间最大值)
- JSP中EL表达式的取值