You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何查询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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.05 16:18:02