大多数与 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,请执行以下步骤
- 从应用的数据存储中获取新条目或更新条目的列表。
- 对于每个条目,创建一个适合该数据类型的
Record
对象。例如,为与体重相关的数据创建WeightRecord
对象。 使用应用数据存储中的唯一键和版本详细信息为每个
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 )
Upsert 使用
insertRecords
将数据更新到 Health Connect。更新数据意味着只要clientRecordId
值存在于 Health Connect 数据存储中,并且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))
)
检查数据更改
现在您已获得更改令牌,请使用它获取所有更改。我们建议创建一个循环来遍历所有更改,其中检查是否有可用的数据更改。以下是步骤:
- 使用令牌调用
getChanges
以获取更改列表。 - 检查每个更改,其更改类型是否为
UpsertionChange
或DeletionChange
,并执行必要的操作。- 对于
UpsertionChange
,仅获取未来自调用应用的更改,以确保您不会重新导入数据。
- 对于
- 将下一个更改令牌分配为您的新令牌。
- 重复步骤 1-3,直到没有剩余的更改。
- 存储下一个令牌并将其保留以供将来导入。
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
中的id
和lastModifiedTime
来上载记录。对于DeletionChange
,使用提供的id
来删除记录。
从 Health Connect 中删除数据
当用户从您的应用中删除其自己的数据时,请确保数据也从 Health Connect 中删除。使用deleteRecords
执行此操作。这需要记录类型以及id
和clientRecordId
值的列表,这使得批量删除多个数据变得很方便。还提供了一个替代的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 读取大量数据时同步过程中的中断,并在下次打开应用时继续。
导入时间
由于您的应用无法收到新数据的通知,因此请在以下两个时间点检查新数据:
- 每次您的应用在前台变为活动状态时。在这种情况下,使用生命周期事件。
- 定期,当您的应用保持在前台时。当有新数据可用时通知用户,让他们可以更新屏幕以反映更改。