android - 如何处理android日历中实例的日期、日期和时间戳?
问题描述
我最近开始使用 Kotlin 学习 android 开发。我正在尝试查询 Google 日历并检查用户参与的活动。我可以成功获取数据,但我无法理解如何处理此处提到的数据中提供的时间戳/日期Query the event instance。
这是我正在使用的逻辑:
class CalendarService {
companion object {
private val CALENDAR_INSTANCE_EVENT_PROJECTION: Array<String> = arrayOf(
CalendarContract.Calendars._ID, // 0
CalendarContract.Calendars.ACCOUNT_NAME, // 1
CalendarContract.Calendars.CALENDAR_DISPLAY_NAME, // 2
CalendarContract.Calendars.OWNER_ACCOUNT, // 3
CalendarContract.Instances.DTSTART, // 4
CalendarContract.Instances.DTEND, // 5
CalendarContract.Instances.DURATION, // 6
CalendarContract.Instances.TITLE, // 7
CalendarContract.Instances.RRULE, // 8
CalendarContract.Events.RDATE, // 9
CalendarContract.Events.CALENDAR_ID, // 10
CalendarContract.Instances.START_DAY, // 11
CalendarContract.Instances.END_DAY, // 12
CalendarContract.Instances.START_MINUTE, // 13
CalendarContract.Instances.END_MINUTE, // 14
CalendarContract.Instances._ID, // 15
CalendarContract.Instances.EVENT_ID, // 16
CalendarContract.Instances.BEGIN, // 17
CalendarContract.Instances.END, // 18
CalendarContract.Instances.CALENDAR_TIME_ZONE, // 19
CalendarContract.Instances.EVENT_END_TIMEZONE, // 20
CalendarContract.Instances.EVENT_TIMEZONE, // 21
CalendarContract.Calendars.ACCOUNT_TYPE // 22
)
private const val CAL_ID_IDX: Int = 0;
private const val ACC_NAME_IDX: Int = 1;
private const val CAL_DISPLAY_NAME_IDX: Int = 2;
private const val OWNER_ACC_IDX: Int = 3;
private const val DATE_START_IDX: Int = 4;
private const val DATE_END_IDX: Int = 5;
private const val DURATION_IDX: Int = 6;
private const val TITLE_IDX: Int = 7;
private const val RRULE_IDX: Int = 8;
private const val EVT_RDATE_IDX: Int = 9;
private const val EVT_CAL_ID_IDX: Int = 10;
private const val START_DAY_IDX: Int = 11;
private const val END_DAY_IDX: Int = 12;
private const val START_MINUTE_IDX: Int = 13;
private const val END_MINUTE_IDX: Int = 14;
private const val INSTANCE_ID_IDX: Int = 15;
private const val INSTANCE_EVT_ID_IDX: Int = 16;
private const val BEGIN_IDX: Int = 17;
private const val END_IDX: Int = 18;
private const val CAL_TIME_ZONE_IDX: Int = 19;
private const val EVENT_END_IDX: Int = 20;
private const val EVENT_TIMEZONE_IDX: Int = 21;
private const val ACCOUNT_TYPE_IDX: Int = 22;
}
private fun getInstanceUrl(): Uri {
val builder = Uri.parse(CalendarContract.Instances.CONTENT_URI.toString()).buildUpon()
println("Builder: $builder")
val now: Long = Date().time
ContentUris.appendId(builder, now)
ContentUris.appendId(builder, now + 2 * DateUtils.DAY_IN_MILLIS)
return builder.build()
}
private fun getSelectionQuery(): String {
return "((${CalendarContract.Calendars.ACCOUNT_NAME} = ?) AND " +
"(${CalendarContract.Calendars.OWNER_ACCOUNT} = ?) AND " +
"(${CalendarContract.Calendars.ACCOUNT_TYPE} = ?))"
}
private fun getCalendarCursor(uri: Uri, query: String, params: Array<String>): Cursor? {
return MainActivity.instance.contentResolver.query(uri, CALENDAR_INSTANCE_EVENT_PROJECTION, query, params, CalendarContract.Instances.BEGIN + " ASC")
}
fun getCalendarInstanceData(emailId: String) {
println("Getting calendar instance data: $emailId")
val uri: Uri = this.getInstanceUrl()
println("Uri: $uri")
val selectionQuery = this.getSelectionQuery()
println("Selection: $selectionQuery")
val selectionArgs: Array<String> = arrayOf(emailId, emailId, "com.google")
println("Selection arguments: $selectionArgs")
val cur: Cursor? = this.getCalendarCursor(uri, selectionQuery, selectionArgs)
if (cur != null) {
println("Processing calendar data: $cur")
this.processCalendarData(cur)
}
}
private fun processCalendarData(cur: Cursor) {
while (cur.moveToNext()) {
val calData: MutableMap<String, String> = mutableMapOf()
for (i in 0 until cur.columnCount) {
println("Processing column: ${cur.getColumnName(i)}, value: ${getValue(cur, i)}")
}
}
println("Cal data list: $calDataList")
}
private fun getValue(cursor: Cursor, columnIndex: Int): String {
val value = when(cursor.getType(columnIndex)) {
Cursor.FIELD_TYPE_NULL -> ""
Cursor.FIELD_TYPE_INTEGER -> cursor.getInt(columnIndex).toString()
Cursor.FIELD_TYPE_FLOAT -> cursor.getFloat(columnIndex).toString()
Cursor.FIELD_TYPE_STRING -> cursor.getString(columnIndex)
Cursor.FIELD_TYPE_BLOB -> cursor.getBlob(columnIndex).toString()
else -> ""
}
return value
}
}
下面提到的是 2021 年 9 月 24 日上午 9:00 IST (GMT+5:30) 的事件的输出。
Processing column: _id, value: 23
Processing column: account_name, value: abc@gmail.com
Processing column: calendar_displayName, value: abc@gmail.com
Processing column: ownerAccount, value: abc@gmail.com
Processing column: dtstart, value: -497372480
Processing column: dtend, value:
Processing column: duration, value: P3600S
Processing column: title, value: Test app event
Processing column: rrule, value: FREQ=DAILY;WKST=MO
Processing column: rdate, value:
Processing column: calendar_id, value: 3
Processing column: startDay, value: 2459482
Processing column: endDay, value: 2459482
Processing column: startMinute, value: 540
Processing column: endMinute, value: 600
Processing column: _id, value: 23
Processing column: event_id, value: 126
Processing column: begin, value: 366627520
Processing column: end, value: 370227520
Processing column: calendar_timezone, value: Asia/Kolkata
Processing column: eventEndTimezone, value:
Processing column: eventTimezone, value: Asia/Kolkata
Processing column: account_type, value: com.google
我可以看到 dtstart、dtend、startDay、endDay、begin、end 但我无法弄清楚如何处理这些值,因为:
- dtstart 为负数且 dtend i 为空白
- 开始和结束不是预期的时间
- startDay 和 endDay 是儒略开始日期。我使用以下等式计算时间:(startDay - 2440588) * 24 * 3600 + startMinute * 60
如何处理实例的时间戳?任何帮助将不胜感激。
解决方案
推荐阅读
- c# - 通过 Xamarin.Forms 中 JSON 上的组件对 ListView 进行分组
- f# - 部分应用函数并在运行时动态调用该函数
- android - 回退到用完原始 dex 文件
- javascript - Google 跟踪代码管理器 (GTM) 错误。预期的主要表达
- react-native - ReadableNativeMap 不能转换为 java.lang.String
- python - 如何使用 Reportlab 编写选项卡?
- typescript - Typescript - union types
- eclipse - Ctrl + 空格给出错误说“计算附加信息”遇到问题
- docker - 在 docker 容器中针对 Localstack 运行 shell 脚本
- image-processing - 如何平铺单个克隆图像图形魔术