本指南將介紹在 Health Connect 中寫入或更新資料的程序。
設定資料結構
在寫入資料之前,我們需要先設定記錄。資料類型有超過 50 種,每種都有各自的結構。如要進一步瞭解可用的資料類型,請參閱 Jetpack 參考資料。
基本記錄
Health Connect 中的「步數」資料類型會擷取使用者在兩次讀取作業間的步數。步數是各健康與健身平台上的常見測量指標。
以下範例說明如何設定步數資料:
val stepsRecord = StepsRecord(
count = 120,
startTime = START_TIME,
endTime = END_TIME,
startZoneOffset = START_ZONE_OFFSET,
endZoneOffset = END_ZONE_OFFSET
)
含有測量單位的記錄
Health Connect 可以儲存值及其測量單位,因此能提供準確資料。舉例來說,「營養」資料類型相當龐大且全面,包括各種選用的營養素欄位,從碳水化合物總量到維生素應有盡有。每個資料點都代表可做為膳食或食品的一部分攝取的營養素。
在這個資料類型中,所有營養素均以 Mass
為單位,而 energy
則以 Energy
為單位。
以下範例說明如何為吃了香蕉的使用者設定營養資料:
val banana = NutritionRecord(
name = "banana",
energy = 105.0.kilocalories,
dietaryFiber = 3.1.grams,
potassium = 0.422.grams,
totalCarbohydrate = 27.0.grams,
totalFat = 0.4.grams,
saturatedFat = 0.1.grams,
sodium = 0.001.grams,
sugar = 14.0.grams,
vitaminB6 = 0.0005.grams,
vitaminC = 0.0103.grams,
startTime = START_TIME,
endTime = END_TIME,
startZoneOffset = START_ZONE_OFFSET,
endZoneOffset = END_ZONE_OFFSET
)
含有系列資料的記錄
Health Connect 可儲存系列資料清單。舉例來說,「心率」資料類型會擷取系統在讀取作業間偵測到的一系列心跳資料樣本。
在這個資料類型中,samples
參數會以心率樣本清單表示。每個樣本都包含 beatsPerMinute
值和 time
值。
以下範例說明如何設定心率系列資料:
val heartRateRecord = HeartRateRecord(
startTime = START_TIME,
startZoneOffset = START_ZONE_OFFSET,
endTime = END_TIME,
endZoneOffset = END_ZONE_OFFSET,
// records 10 arbitrary data, to replace with actual data
samples = List(10) { index ->
HeartRateRecord.Sample(
time = START_TIME + Duration.ofSeconds(index.toLong()),
beatsPerMinute = 100 + index.toLong(),
)
}
)
寫入資料
Health Connect 中常見的一項工作流程就是寫入資料。如要新增記錄,請使用 insertRecords
。
以下範例說明如何透過插入步數來寫入資料:
suspend fun insertSteps(healthConnectClient: HealthConnectClient) {
try {
val stepsRecord = StepsRecord(
count = 120,
startTime = START_TIME,
endTime = END_TIME,
startZoneOffset = START_ZONE_OFFSET,
endZoneOffset = END_ZONE_OFFSET
)
healthConnectClient.insertRecords(listOf(stepsRecord))
} catch (e: Exception) {
// Run error handling here
}
}
更新資料
如果您需要變更一或多筆記錄,特別是在需要將應用程式資料儲存庫與 Health Connect 的資料同步時,您就可以更新資料。更新現有資料的方法有兩種,至於要採取哪一種,則視用於尋找記錄的 ID 而定。
Metadata
建議您先檢查 Metadata
類別,因為這是更新資料前的必要操作。Health Connect 中的每個 Record
在建立時都包含 metadata
欄位。下列屬性與同步處理相關:
屬性 | 說明 |
---|---|
id
|
Health Connect 中的每筆 Record 都有專屬的 id 值。在插入新記錄時 ,Health Connect 會自動填入這項資料。 |
lastModifiedTime
|
每筆 Record 也會追蹤上次修改記錄的時間。Health Connect 會自動填入這項資料。 |
clientRecordId
|
每筆 Record 都具有與之關聯的專屬 ID,可做為應用程式資料儲存庫中的參考資料。您的應用程式提供了這個值。 |
clientRecordVersion
|
如果記錄包含 clientRecordId ,就能使用 clientRecordVersion 讓資料與應用程式資料儲存庫中的版本保持同步。您的應用程式提供了這個值。 |
透過記錄 ID 更新
如要更新資料,請先備妥所需的記錄,接著對記錄進行任何必要更動,然後呼叫 updateRecords
即可變更。
以下範例說明如何更新資料。為此,每筆記錄的時區偏移值均已調整成 PST。
suspend fun updateSteps(
healthConnectClient: HealthConnectClient,
prevRecordStartTime: Instant,
prevRecordEndTime: Instant
) {
try {
val request = healthConnectClient.readRecords(
ReadRecordsRequest(
recordType = StepsRecord::class,
timeRangeFilter = TimeRangeFilter.between(
prevRecordStartTime,
prevRecordEndTime
)
)
)
val newStepsRecords = arrayListOf<StepsRecord>()
for (record in request.records) {
// Adjusted both offset values to reflect changes
val sr = StepsRecord(
count = record.count,
startTime = record.startTime,
startZoneOffset = record.startTime.atZone(ZoneId.of("PST")).offset,
endTime = record.endTime,
endZoneOffset = record.endTime.atZone(ZoneId.of("PST")).offset,
metadata = record.metadata
)
newStepsRecords.add(sr)
}
client.updateRecords(newStepsRecords)
} catch (e: Exception) {
// Run error handling here
}
}
透過用戶端記錄 ID 更新/插入
如果您使用選用的用戶端記錄 ID 和用戶端記錄版本值,我們會建議您使用 insertRecords
,而非 updateRecords
。
insertRecords
函式可以更新/插入資料。如果 Health Connect 中的資料以指定的一組用戶端記錄 ID 為依據,系統會覆寫這類資料。但如果不是的話,則會以新資料的形式寫入。當您需要將應用程式資料儲存庫中的資料同步到 Health Connect 時,這就非常實用。
以下範例說明如何對從應用程式資料儲存庫提取的資料執行更新/插入作業:
suspend fun pullStepsFromDatastore() : ArrayList<StepsRecord> {
val appStepsRecords = arrayListOf<StepsRecord>()
// Pull data from app datastore
// ...
// Make changes to data if necessary
// ...
// Store data in appStepsRecords
// ...
var sr = StepsRecord(
// Assign parameters for this record
metadata = Metadata(
clientRecordId = cid
)
)
appStepsRecords.add(sr)
// ...
return appStepsRecords
}
suspend fun upsertSteps(
healthConnectClient: HealthConnectClient,
newStepsRecords: ArrayList<StepsRecord>
) {
try {
healthConnectClient.insertRecords(newStepsRecords)
} catch (e: Exception) {
// Run error handling here
}
}
之後,您可以在主執行緒中呼叫這些函式。
upsertSteps(healthConnectClient, pullStepsFromDatastore())
檢查用戶端記錄版本中的值
如果您在更新/插入資料的程序中包括用戶端記錄版本,Health Connect 會對 clientRecordVersion
值執行比較檢查。假如插入資料的版本高於現有資料版本,系統就會執行更新/插入作業。但如果不是的話,該程序會忽略變更,而值也會保持不變。
如要在資料中加入版本編號,您需要依據版本編號邏輯為 Metadata.clientRecordVersion
提供 Long
值。
val sr = StepsRecord(
count = count,
startTime = startTime,
startZoneOffset = startZoneOffset,
endTime = endTime,
endZoneOffset = endZoneOffset,
metadata = Metadata(
clientRecordId = cid,
clientRecordVersion = version
)
)
為防止意外覆寫資料的情況,每當變更發生時,更新/插入作業不會自動依累加原則設定 version
。因此,您必須為該項目手動設定較高的值。
寫入資料的最佳做法
應用程式只能將「擁有來源」的資料寫入 Health Connect。
如果應用程式資料是從另一個應用程式匯入,則應由該應用程式負責將其擁有的資料寫入 Health Connect。
此外,建議您針對資料寫入例外狀況導入處理邏輯,例如資料在邊界外或發生內部系統錯誤時。您可以對工作排程機制套用輪詢和重試策略。如果最終無法順利寫入 Health Connect,請確保應用程式能夠移出該匯出點。請務必記錄並回報錯誤,以利診斷作業。
追蹤資料時,您可以根據應用程式寫入資料的方式採用以下幾項建議。
被動追蹤
這包括提供被動健身或健康追蹤功能的應用程式,例如在背景持續記錄步數或心率。
應用程式需採用以下做法,定期將資料寫入 Health Connect:
- 在每次同步處理時,僅寫入自上次同步處理以來修改過的新資料和更新資料。
- 在每個寫入要求中,區塊要求最多為 1000 條記錄。
- 使用
WorkManager
安排週期性背景工作,時間長度至少為 15 分鐘。 請限制只在裝置處於閒置狀態且電量充足時執行工作。
val constraints = Constraints.Builder() .requiresBatteryNotLow() .requiresDeviceIdle(true) .build() val writeDataWork = PeriodicWorkRequestBuilder<WriteDataToHealthConnectWorker>( 15, TimeUnit.MINUTES, 5, TimeUnit.MINUTES ) .setConstraints(constraints) .build()
主動追蹤
這類應用程式功能包括執行以運動和睡眠等事件為基礎的追蹤功能,或讓使用者手動輸入營養攝取等資訊。如果應用程式是在前景運作,或事件發生頻率相當低 (如一天幾次),就會建立這類記錄。
請確保在整個事件期間,應用程式不會要求 Health Connect 保持在執行狀態。
資料必須透過以下其中一種方式寫入 Health Connect:
- 在事件完成後,將資料同步處理至 Health Connect。例如在使用者結束追蹤的運動時段後同步處理資料。
- 使用
WorkManager
排定一次性工作,稍後再同步處理資料。
精細程度和寫入頻率的最佳做法
將資料寫入 Health Connect 時,請使用適當的解析度。使用適當的解析度有助於降低儲存空間負載,同時確保資料保持一致且準確。資料解析包含 2 件事:
- 寫入頻率:應用程式將任何新資料推送至 Health Connect 的頻率。例如每 15 分鐘寫入新資料。
- 寫入資料的精細程度:推送資料的取樣頻率。例如,每 5 秒寫入一次心率樣本。並非所有資料類型都需要相同的取樣率。相較於較低的頻率 (例如每 60 秒),更新每秒步數資料並沒有什麼好處。不過,取樣率較高可能會讓使用者更詳細地瞭解自己的健康與健身資料。您應在精細程度和效能之間取得平衡,採用適當的取樣頻率。
寫入全天候監控的資料
針對持續收集的資料 (例如步數),應用程式應每天至少每 15 分鐘寫入 Health Connect。
資料類型 |
單位 |
預期中 |
範例 |
操作步驟 |
步數 |
每分鐘 |
23:14 - 23:15 - 5 步 23:16 - 23:17 - 22 步 23:17 - 23:18 - 8 步 |
步頻 |
步/分鐘 |
每分鐘 |
23:14 - 23:15 - 5 秒 下午 23:16 - 23:17 - 22 下午 23:17 - 23:18 - 8 秒 |
推動輪椅次數 |
推送 |
每分鐘 |
23:14 - 23:15 - 5 次推播 23:16 - 23:17 - 22 次推播 23:17 - 23:18 - 8 下推式 |
活動卡路里燃燒量 |
卡路里 |
每隔 15 分鐘 |
23:15 - 23:30 - 2 卡路里 23:30 - 23:45 - 25 卡路里 23:45 - 00:00 - 5 卡路里 |
卡路里燃燒總量 |
卡路里 |
每隔 15 分鐘 |
23:15 - 23:30 - 16 卡路里 23:30 - 23:45 - 16 卡路里 23:45 - 00:00 - 16 卡路里 |
距離 |
公里/分鐘 |
每分鐘 |
23:14-23:15 - 0.008 公里 23:16 - 23:16 - 0.021 公里 23:17 - 23:18 - 0.012 公里 |
爬升高度 |
分鐘 |
每分鐘 |
20:36 - 20:37 - 3.048 公尺 20:39 - 20:40 - 3.048 公尺 23:23 - 23:24 - 9.144 公尺 |
攀爬樓層數 |
層樓 |
每分鐘 |
23:14 - 23:15 - 5 層樓 23:16 - 23:16 - 22 層樓 23:17 - 23:18 - 8 層樓 |
心率 |
bpm |
每分鐘 |
06:11 - 55 bpm |
心率變異基因段 |
毫秒 |
每分鐘 |
上午 6:11 - 23 毫秒 |
呼吸速率 |
呼吸/分鐘 |
每分鐘 |
23:14 - 23:15 - 60 次呼吸 23:16 - 23:16 - 62 次呼吸/分鐘 23:17 - 23:18 - 64 次呼吸 |
血氧濃度 |
% |
每小時 |
6:11 - 95.208% |
寫入工作階段
健身或睡眠時段結束時,資料應寫入 Health Connect。
根據最佳做法,所有睡眠時段或運動時段應使用記錄裝置及適當的中繼資料 (包括 RecordingMethod
) 寫入。
您的應用程式應至少遵循下方「預期」欄中的指引。在可能的情況下,請遵循「最佳」指南。
運動時追蹤的資料
資料類型 |
單位 |
預期中 |
祝一切順心! |
範例 |
操作步驟 |
步數 |
每分鐘 |
每 1 秒 |
23:14-23:15 - 5 步 23:16 - 23:17 - 22 步 23:17 - 23:18 - 8 步 |
步頻 |
步/分鐘 |
每分鐘 |
每 1 秒 |
下午 23:14-23:15 - 35 下午 23:16 - 23:17 - 37 下午 23:17 - 23:18 - 40 |
推動輪椅次數 |
推送 |
每分鐘 |
每 1 秒 |
23:14-23:15 - 5 次推播 23:16 - 23:17 - 22 次推播 23:17 - 23:18 - 8 下推式 |
自行車踩踏頻率 |
rpm:每分鐘呼吸次數 |
每分鐘 |
每 1 秒 |
23:14-23:15 - 65 rpm 23:16 - 23:17 - 70 rpm 23:17 - 23:18 - 68 rpm |
功率 |
瓦特 |
每分鐘 |
每 1 秒 |
23:14-23:15 - 250 瓦特 23:16 - 23:17 - 255 W 23:17 - 23:18 - 245 W |
速度 |
公里/分鐘 |
每分鐘 |
每 1 秒 |
23:14-23:15 - 0.3 公里/分鐘 23:16 - 23:17 - 0.4 公里/分鐘 23:17 - 23:18 -0.4 公里/分鐘 |
距離 |
公里/公尺 |
每分鐘 |
每 1 秒 |
23:14-23:15 - 0.008 公里 23:16 - 23:16 - 0.021 公里 23:17 - 23:18 - 0.012 公里 |
活動卡路里燃燒量 |
卡路里 |
每分鐘 |
每 1 秒 |
23:14-23:15 - 20 卡路里 23:16 - 23:17 - 20 卡路里 23:17 - 23:18 - 25 卡路里 |
卡路里燃燒總量 |
卡路里 |
每分鐘 |
每 1 秒 |
23:14-23:15 - 36 卡路里 23:16 - 23:17 - 36 卡路里 23:17 - 23:18 - 41 卡路里 |
爬升高度 |
分鐘 |
每分鐘 |
每 1 秒 |
20:36 - 20:37 - 3.048 公尺 20:39 - 20:40 - 3.048 公尺 23:23 - 23:24 - 9.144 公尺 |
運動路線 |
經緯度/alt |
每 3 到 5 秒 |
每 1 秒 |
|
心率 |
bpm |
每分鐘 |
每 1 秒 |
23:14-23:15 - 150 bpm 23:16 - 23:17 -152 bpm 23:17 - 23:18 - 155 bpm |
睡眠期間追蹤的資料
資料類型 |
單位 |
預期的樣本 |
範例 |
睡眠時段 |
在此流程的各個階段 |
每個睡眠階段的精細時間範圍 |
23:46 - 23:50 - 清醒 23:50 - 23:56 - 淺層睡眠 23:56 - 00:16 - 深層睡眠 |
靜止心率 |
bpm |
單一每日價值 (早上一晚預計要推出的項目) |
06:11 - 60 bpm |
血氧濃度 |
% |
單一每日價值 (早上一晚預計要推出的項目) |
6:11 - 95.208% |