同步数据

大多数与 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 函数返回一个 InsertRecordsResponse,其中包含 id 值列表。使用该响应获取记录 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. 检查每个更改,判断其更改类型是 UpsertionChange 还是 DeletionChange,并执行必要的操作。
    • 对于 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 值列表,这使得批量删除多个数据变得很方便。还提供了一个替代的 deleteRecords,它接收 timeRangeFilter

同步数据的最佳实践

以下因素会影响同步过程。

令牌过期

由于未使用的更改令牌会在 30 天内过期,因此您必须使用一种避免在这种情况下丢失信息的同步策略。您的策略可能包括以下方法:

  • 在应用数据存储中搜索最近使用的记录,该记录也具有 Health Connect 的 id
  • 请求从特定时间戳开始的 Health Connect 记录,然后将它们插入或更新到应用数据存储中。
  • 请求一个更改令牌以将其保留以备将来使用。

推荐的更改管理策略

如果您的应用正在获取无效或过期的更改令牌,我们建议根据其在您的逻辑中的应用选择以下管理策略:

  • 读取并对所有数据进行重复数据删除。这是最理想的策略。
    • 存储上次从 Health Connect 读取数据的时时间戳。
    • 在令牌过期时,重新读取所有从最近的时间戳开始或过去 30 天的数据。然后,使用标识符将其与先前读取的数据进行重复数据删除。
    • 最好实现客户端 ID,因为它们是数据更新所必需的。
  • 仅读取上次读取时间戳之后的数据。这会导致在更改令牌过期时出现一些数据差异,但时间段很短,可能只需几小时到几天。
    • 存储上次从 Health Connect 读取数据的时时间戳。
    • 在令牌过期时,从该时间戳开始读取所有数据。
  • 删除过去 30 天的数据,然后读取数据。这更符合第一次集成时的操作。
    • 删除应用从 Health Connect 读取的过去 30 天的所有数据。
    • 删除后,再次读取所有数据。
  • 在过去 30 天内读取数据,不进行重复数据删除。这是最不理想的策略,会导致用户看到重复数据。
    • 删除应用从 Health Connect 读取的过去 30 天的所有数据。
    • 允许重复条目。

数据类型更改令牌

如果您的应用独立使用多种数据类型,请为每种数据类型使用单独的更改令牌。仅当这些数据类型一起使用或根本不使用时,才在更改同步 API 中使用多种数据类型的列表。

前台读取

应用只能在其处于前台时从 Health Connect 读取数据。当从 Health Connect 同步数据时,对 Health Connect 的访问可能会在任何时候中断。例如,您的应用必须处理从 Health Connect 读取大量数据时同步过程中的中断,并在下次打开应用时继续。

导入时间

由于您的应用无法收到有关新数据的通知,因此请在以下两个时间点检查新数据:

  • 每次您的应用在前景中变得活跃时。在这种情况下,使用生命周期事件。
  • 您的应用在前景中保持活动状态期间定期检查。当有新数据可用时,通知用户,让他们更新其屏幕以反映更改。