同步数据

大多数与 Health Connect 集成的应用都有自己的数据存储区,以用作可信来源。Health Connect 提供了多种方法来让您的应用保持同步。

请确保您的应用会采取以下做法:

  • 将新数据或更新后数据从应用的数据存储区馈送至 Health Connect。
  • 从 Health Connect 拉取数据更改,这些更改会反映在应用的数据存储区中。
  • 从应用的数据存储区中删除数据时,会一并从 Health Connect 中删除这些数据。

无论是哪种情况,都要确保同步过程能使 Health Connect 与应用的数据存储区保持一致。

将数据馈送到 Health Connect

同步过程的第一部分是将数据从应用的数据存储区馈送到 Health Connect 数据存储区。

准备数据

应用的数据存储区中的记录通常包含以下详细信息:

  • 唯一键,例如 UUID
  • 版本或时间戳。

设计应用的数据存储区,以跟踪记录已馈送至 Health Connect 的数据。为了实现这一点,请应用以下逻辑:

  • 提供一个更改列表和一个令牌(用于检索自上次发出令牌后更新的记录)。
  • 跟踪导出数据的上次修改时间。

这些步骤对于确保仅将新数据或更新后数据馈送到 Health Connect 而言至关重要。

向 Health Connect 中写入数据

如需将数据馈送到 Health Connect,请按以下步骤操作:

  1. 从应用的数据存储区获取新条目或更新条目的列表。
  2. 对于每个条目,创建相应数据类型的 Record 对象。例如,为与权重相关的数据创建 WeightRecord 对象。
  3. 使用应用的数据存储区中的唯一键和版本详细信息,为每个 Record 指定一个 Metadata 对象:如果您的数据未进行版本控制,您可以使用当前时间戳的 Long 值作为替代方案。

    val record = WeightRecord(
        metadata = Metadata(
            clientRecordId = "<Your record's Client ID>",
            clientRecordVersion = <Your record's version>
        ),
        weight = weight,
        time = time,
        zoneOffset = zoneOffset
    )
    
  4. 使用 insertRecords 向 Health Connect 更新/插入数据。更新/插入数据是指,只要 Health Connect 数据存储区中存在 clientRecordId 值且 clientRecordVersion 高于现有值,那么 Health Connect 中的任何现有数据都会被覆盖。否则,更新/插入的数据会作为新数据写入。

    healthConnectClient.insertRecords(arrayListOf(record))
    

如需了解馈送数据的实际注意事项,请查看写入数据的最佳实践。

存储 Health Connect ID

将记录更新/插入 Health Connect 后,应用的数据存储区需要存储每条记录的 Health Connect id。这样一来,您的应用便可以在拉取数据后检查各项传入更改是需要创建新记录,还是更新现有记录。

insertRecords 函数会返回包含 id 值列表的 InsertRecordsResponse。使用响应获取记录 ID 并存储它们。

val response = healthConnectClient.insertRecords(arrayListOf(record))

for (recordId in response.recordIdsList) {
    // Store recordId to your app's datastore
}

从 Health Connect 中拉取数据

同步过程的第二部分是将 Health Connect 中的所有数据更改拉取到应用的数据存储区。数据更改可能包括更新和删除。

获取更改令牌

如需获取要从 Health Connect 拉取的更改列表,您的应用需要跟踪更改令牌。您可以在请求更改时使用这些令牌,从而返回数据更改列表,以及返回新的更改令牌供下次使用。

要获取更改令牌,请调用 getChangesToken 并提供所需的数据类型。

val changesToken = healthConnectClient.getChangesToken(
    ChangesTokenRequest(recordTypes = setOf(WeightRecord::class))
)

检查数据更改

现在,您已经获得了更改令牌,可以用它来获取所有更改了。我们建议您创建一个循环来获取所有更改,从而检查是否有可用数据更改。具体步骤如下:

  1. 使用令牌调用 getChanges 以获取更改列表。
  2. 检查各项更改的类型是否为 UpsertionChangeDeletionChange,然后执行必要的操作。
    • 对于 UpsertionChange,请仅进行并非来自调用应用的更改,从而确保不会重新导入数据。
  3. 将下一个更改令牌分配为新令牌。
  4. 重复步骤 1-3,直到没有剩余的更改为止
  5. 存储下一个令牌,并将其预留以供日后导入。
suspend fun processChanges(token: String): String {
    var nextChangesToken = token
    do {
        val response = healthConnectClient.getChanges(nextChangesToken)
        response.changes.forEach { change ->
            when (change) {
                is UpsertionChange ->
                    if (change.record.metadata.dataOrigin.packageName != context.packageName) {
                        processUpsertionChange(change)
                    }
                is DeletionChange -> processDeletionChange(change)
            }
        }
        nextChangesToken = response.nextChangesToken
    } while (response.hasMore)
    // Return and store the changes token for use next time.
    return nextChangesToken
}

如需了解有关拉取数据的实际注意事项,请参阅同步数据的最佳实践。

处理数据更改

反映对应用数据存储区所做的更改。对于 UpsertionChange,请使用 metadata 中的 idlastModifiedTime更新/插入记录。对于 DeletionChange,请使用提供的 id 删除该记录。

从 Health Connect 中删除数据

当用户从您的应用中删除自己的数据时,请确保这些数据也会从 Health Connect 中移除。请使用 deleteRecords 执行此操作。这需要使用 idclientRecordId 值的列表,方便批量处理多种待删除的数据。