Google Calendar API 不透明密钥字符串与本机事件 ID 长

问题描述 投票:0回答:1

我正在尝试与 iOS 和 Android 进行 Google 日历同步。

对于 iOS,我正在使用 google-api-objectivec-client-for-rest

对于 Android,我使用 contentResolver 和 ContentValues 的方法 日历提供商

据我所知,iOS 端使用 Rest API,Android 端使用内容提供程序。

为了不重复事件,我使用了来自 android 的 ID,它是一个长值。当我在iOS上实现时,我发现ID是一个字符串(很长而且不是整数)。

在 iOS 上我发现:

**
*  Opaque identifier of the event. When creating new single or recurring
*  events, you can specify their IDs. Provided IDs must follow these rules:
*  - characters allowed in the ID are those used in base32hex encoding, i.e.
*  lowercase letters a-v and digits 0-9, see section 3.1.2 in RFC2938
*  - the length of the ID must be between 5 and 1024 characters
*  - the ID must be unique per calendar Due to the globally distributed nature
*  of the system, we cannot guarantee that ID collisions will be detected at
*  event creation time. To minimize the risk of collisions we recommend using
*  an established UUID algorithm such as one described in RFC4122.
*  If you do not specify an ID, it will be automatically generated by the
*  server.
*  Note that the icalUID and the id are not identical and only one of them
*  should be supplied at event creation time. One difference in their semantics
*  is that in recurring events, all occurrences of one event have different ids
*  while they all share the same icalUIDs.
*
*  identifier property maps to 'id' in JSON (to avoid Objective C's 'id').
*
@property(nonatomic, copy, nullable) NSString *identifier;

原来来自rest的ID是一个Opaque iD,但来自Android的ID实际上是Google在事件创建后生成的序列。

我尝试从 Android 端搜索不透明 ID,但我无法在文档中找到它。这可能是故意这样做的,因为

ContentUris.withAppendedId(CalendarContract.Events.CONTENT_URI, googleID)
实际上需要很长的 ID。

我在here找到了类似的答案,并且我按照它在Android端为参数CalendarContract.Events.UID_2445设置了自定义UID。 (即使我尝试在插入后进行查询也不会自动生成)

UUID.randomUUID().toString()
        .replace("-", "")
        .lowercase()

但是当我尝试从 iOS 获取相同的事件时,我无法做到这一点,因为我收到错误未找到。

我尝试获取所有事件和列,看看是否可以通过查询来获取它,但实际上它不是一个字段。

例如在Android端我设置了uID = 62b92a9f626c4a7da7653f7f5c758d04

但是在 iOS 上我得到了这个:

Events result

API 之间的这种差异是故意的吗?

我应该在android上使用rest api来得到同样的东西吗?我没有找到开箱即用的东西。

如果生成的事件id不同,如何同步Android和iOS之间的事件?

android ios swift google-calendar-api android-calendar
1个回答
0
投票

进一步调查,我发现在 Android 端,与在线日历同步完成后,内容解析器还会返回

_SYNC_ID
字段,该字段填充的 ID 与从 iOS Rest api 返回的 ID 相同。

为了得到它,在

contentResolver.insert
之后,我为插入的事件的相同URI注册了一个ContentObserver:

 val uri = contentResolver.insert(CalendarContract.Events.CONTENT_URI, values)
 val longGoogleID = uri!!.lastPathSegment?.toLongOrNull()

 val eventChangeObserver = object : ContentObserver(null)
            {
                override fun onChange(selfChange: Boolean)
                {
                   super.onChange(selfChange)
                   val syncID = getEventSyncID(context, longGoogleID) 
                    
                   contentResolver.unregisterContentObserver(this)
                }
            }

 contentResolver.registerContentObserver(uri, true, eventChangeObserver)

并使用函数获取同步ID:

private fun getEventSyncID(context: Context, longID: Long): String?
{
    try
    {
        val contentResolver = context.contentResolver

        val uri = ContentUris.withAppendedId(CalendarContract.Events.CONTENT_URI, longID)

        val projection = arrayOf(CalendarContract.Events._ID, CalendarContract.Events._SYNC_ID)

        val cursor = contentResolver.query(uri, projection, null, null, null) ?: return null

        if (!cursor.moveToFirst()) return null

        val eventSyncID = cursor.getString(1)
        return eventSyncID

    } catch (ex: Exception)
    {
        println(ex)
    }

    return null
}

这很可能是需要的,因为事件未在插入的同一时刻与 Google 服务器同步,因此我们必须在第二时刻获取它们。

© www.soinside.com 2019 - 2024. All rights reserved.