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
相关产品推荐
相关产品推荐

