如何查询Android原生日历中本App创建的日程事件?
实现仅查询本App创建的日历事件的修改方案
实现原理
Android 4.1(API 16)及以上系统的日历提供了CalendarContract.Events.CUSTOM_APP_PACKAGE字段,专门用于存储创建该事件的应用包名,我们只要在插入事件时写入自己的包名,查询时过滤该字段即可。
第一步:修改插入事件的代码
在你构建ContentValues的逻辑中新增一行,写入当前App的包名:
fun insertEventInNativeCalendar(eventEntity: EventEntity) { val calId: Long = 1 val recurringRule = getRecurringRule(repetition = eventEntity.repetition) val values = ContentValues().apply { put(CalendarContract.Events.DTSTART, eventEntity.startTime.timeInMillis) put(CalendarContract.Events.DTEND, eventEntity.endTime.timeInMillis) put(CalendarContract.Events.TITLE, eventEntity.title) put(CalendarContract.Events.DESCRIPTION, eventEntity.description) put(CalendarContract.Events.EVENT_LOCATION, eventEntity.location) put(CalendarContract.Events.EVENT_COLOR, eventEntity.color.toString()) put(CalendarContract.Events.CALENDAR_ID, calId) put(CalendarContract.Events.ALL_DAY, eventEntity.isAllDay.toInt()) if (!recurringRule.contains("NEVER")) { put(CalendarContract.Events.RRULE, recurringRule) } put(CalendarContract.Events.EVENT_TIMEZONE, TimeZone.getDefault().id) // 新增行:写入当前App包名作为标识 put(CalendarContract.Events.CUSTOM_APP_PACKAGE, context.packageName) } context.contentResolver.insert(CalendarContract.Events.CONTENT_URI, values) }
第二步:修改查询事件的代码
查询时增加过滤条件,仅返回包名匹配本App的事件:
fun readCalendarEvent() { val dummyEvents = mutableListOf<DummyEvent>() // 新增过滤规则:仅查询本App创建的事件 val selection = "${CalendarContract.Events.CUSTOM_APP_PACKAGE} = ?" val selectionArgs = arrayOf(context.packageName) val cursor: Cursor? = context.contentResolver.query( CalendarContract.Events.CONTENT_URI, arrayOf("calendar_id", "title", "description", "dtstart", "dtend", "eventLocation"), // 替换原有的null为过滤条件 selection, selectionArgs, null ) cursor?.let { while (it.moveToNext()) { val calendarId = it.getString(0) val title = it.getString(1) val description = it.getString(2) val dtStart = it.getString(3) val dtEnd = it.getString(4) val eventLocation = it.getString(5) val dummyEvent = DummyEvent( calendarId, title, description, dtStart, dtEnd, eventLocation ) dummyEvents.add(dummyEvent) } // 补充:用完关闭cursor避免内存泄漏 it.close() } Log.d(TAG, "readCalendarEvent: $dummyEvents") }
低版本兼容方案(API<16)
如果你的App需要兼容Android 4.1以下的系统,可以在插入事件时在描述字段末尾加一个用户不可见的专属标识,比如<!--MY_APP_CREATED_EVENT_FLAG-->,查询时过滤描述字段包含该标识即可,展示给用户前把该标识从描述内容中删掉就行。
额外优化提示
你当前插入代码里硬编码了calId = 1,不同设备的默认日历ID不一定是1,建议先查询系统中可用的可写入日历账户,获取正确的日历ID再写入,避免部分设备写入失败。
内容的提问来源于stack exchange,提问作者TheRock
相关产品推荐
相关产品推荐

