首页 > 解决方案 > 如何处理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 但我无法弄清楚如何处理这些值,因为:

  1. dtstart 为负数且 dtend i 为空白
  2. 开始和结束不是预期的时间
  3. startDay 和 endDay 是儒略开始日期。我使用以下等式计算时间:(startDay - 2440588) * 24 * 3600 + startMinute * 60

如何处理实例的时间戳?任何帮助将不胜感激。

标签: androidkotlinandroid-calendar

解决方案


推荐阅读