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

Android通过Insert Intent添加日历事件后,如何高效获取事件ID?

解决日历事件插入后获取ID的最优方案

方案1:结合唯一标识主动查询(推荐)

通过Intent.ACTION_INSERT发起插入时,给事件添加一个唯一标识(比如自定义的UUID),待用户从日历界面返回后,主动查询最近新增的事件并匹配该标识,就能快速拿到事件ID,比ContentObserver延迟低很多。

具体实现:

  • 发起插入Intent时,把唯一标识写入事件描述或其他自定义字段:
    val uniqueTag = UUID.randomUUID().toString()
    val insertIntent = Intent(Intent.ACTION_INSERT)
        .setData(CalendarContract.Events.CONTENT_URI)
        .putExtra(CalendarContract.Events.TITLE, "会议")
        .putExtra(CalendarContract.Events.DESCRIPTION, "唯一标识:$uniqueTag")
        .putExtra(CalendarContract.Events.DTSTART, System.currentTimeMillis() + 3600000)
    startActivity(insertIntent)
    
  • 在你的Activity的onResume方法中执行查询,筛选10秒内新增且包含唯一标识的事件:
    override fun onResume() {
        super.onResume()
        val projection = arrayOf(CalendarContract.Events._ID)
        val selection = "${CalendarContract.Events.DESCRIPTION} LIKE ? AND ${CalendarContract.Events.DT_CREATED} > ?"
        val selectionArgs = arrayOf(
            "%唯一标识:$uniqueTag%",
            (System.currentTimeMillis() - 10000).toString()
        )
        contentResolver.query(
            CalendarContract.Events.CONTENT_URI,
            projection,
            selection,
            selectionArgs,
            "${CalendarContract.Events.DT_CREATED} DESC"
        )?.use { cursor ->
            if (cursor.moveToFirst()) {
                val eventId = cursor.getLong(cursor.getColumnIndexOrThrow(CalendarContract.Events._ID))
                // 拿到ID做后续处理
            }
        }
    }
    

方案2:直接静默插入事件(无用户交互场景)

如果业务允许跳过系统日历的编辑界面,可以直接用ContentResolver插入事件(需申请WRITE_CALENDAR权限),插入后能直接获取事件ID,完全没有延迟:

// 先获取默认日历ID
fun getDefaultCalendarId(): Long {
    val projection = arrayOf(CalendarContract.Calendars._ID)
    val selection = "${CalendarContract.Calendars.IS_PRIMARY} = 1"
    contentResolver.query(
        CalendarContract.Calendars.CONTENT_URI,
        projection,
        selection,
        null,
        null
    )?.use { cursor ->
        if (cursor.moveToFirst()) {
            return cursor.getLong(0)
        }
    }
    return 0
}

// 插入事件并获取ID
val values = ContentValues().apply {
    put(CalendarContract.Events.TITLE, "自动添加的会议")
    put(CalendarContract.Events.DTSTART, System.currentTimeMillis() + 3600000)
    put(CalendarContract.Events.DTEND, System.currentTimeMillis() + 7200000)
    put(CalendarContract.Events.CALENDAR_ID, getDefaultCalendarId())
    put(CalendarContract.Events.EVENT_TIMEZONE, TimeZone.getDefault().id)
}
val insertedUri = contentResolver.insert(CalendarContract.Events.CONTENT_URI, values)
val eventId = insertedUri?.lastPathSegment?.toLong()

方案3:优化ContentObserver监听

如果必须用ContentObserver,缩小监听范围并结合唯一标识匹配,能降低延迟:

val observer = object : ContentObserver(Handler(Looper.getMainLooper())) {
    override fun onChange(selfChange: Boolean, uri: Uri?) {
        super.onChange(selfChange, uri)
        // 执行方案1中的查询逻辑,用唯一标识匹配最新事件
    }
}

// 仅监听日历事件的Uri,开启子节点通知
contentResolver.registerContentObserver(
    CalendarContract.Events.CONTENT_URI,
    true,
    observer
)

// 记得在页面销毁时注销
override fun onDestroy() {
    super.onDestroy()
    contentResolver.unregisterContentObserver(observer)
}

内容的提问来源于stack exchange,提问作者Hasan Kucuk

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.10 00:05:17