このガイドでは、ヘルスコネクトでデータの書き込みまたは更新を行うプロセスについて説明します。
データ構造を設定する
データを書き込む前に、まずレコードを設定する必要があります。50 を超えるデータ型があり、各データ型にそれぞれの構造があります。使用可能なデータ型について詳しくは、Jetpack リファレンスをご覧ください。
基本のレコード
ヘルスコネクトの Steps データ型には、各読み取りの間にユーザーが歩いた歩数が記録されます。歩数は、健康、フィットネス、ウェルネスのプラットフォームで共通の測定値を表します。
次の例は、歩数データを設定する方法を示しています。
val stepsRecord = StepsRecord(
count = 120,
startTime = START_TIME,
endTime = END_TIME,
startZoneOffset = START_ZONE_OFFSET,
endZoneOffset = END_ZONE_OFFSET
)
測定単位を含むレコード
ヘルスコネクトでは、精度を高めるため、測定単位とともに値を格納できます。その一例が、広範囲を包括的にカバーする Nutrition データ型です。総炭水化物からビタミンまで、さまざまな栄養素項目が対象に含まれます。各データポイントは、食事または食品の一部として摂取された可能性のある栄養素を表します。
Nutrition データ型では、すべての栄養素が 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
)
系列データを含むレコード
ヘルスコネクトでは系列データのリストを格納できます。その一例が、読み取り間に検出された一連の心拍数のサンプルをキャプチャする Heart Rate データ型です。
このデータ型では、パラメータ 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(),
)
}
)
データを書き込む
ヘルスコネクトの一般的なワークフローとして、データの書き込みがあります。レコードを追加するには、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
}
}
データを更新する
1 つ以上のレコードを変更する必要がある場合、特にアプリのデータストアをヘルスコネクトのデータと同期する必要がある場合は、データを更新できます。既存のデータを更新するには、レコードの検索に使用される ID に応じて 2 つの方法があります。
メタデータ
データを更新するときに必要になるため、最初に Metadata
クラスを確認することをおすすめします。作成時、ヘルスコネクトの各 Record
には metadata
フィールドがあります。同期に関連するプロパティは次のとおりです。
プロパティ | 説明 |
---|---|
id
|
ヘルスコネクトの各 Record には一意の id 値があります。ヘルスコネクトでは、 新しいレコードを挿入するときに、この値が自動的に設定されます。 |
lastModifiedTime
|
各 Record にはレコードの最終更新日時も記録されます。この値はヘルスコネクトによって自動的に入力されます。 |
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 とクライアント レコード バージョンの値を使用している場合は、updateRecords
ではなく insertRecords
を使用することをおすすめします。
insertRecords
関数を使用するとデータをアップサートできます。指定されたクライアント レコード ID のセットに基づくデータがヘルスコネクトに存在する場合、データは上書きされます。存在しない場合は、新しいデータとして書き込まれます。このシナリオは、アプリのデータストアからヘルスコネクトにデータを同期する必要がある場合に便利です。
次の例は、アプリのデータストアから取得されたデータに対してアップサートを実行する方法を示しています。
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())
クライアント レコード バージョンの値のチェック
データをアップサートするプロセスにクライアント レコード バージョンが含まれている場合、ヘルスコネクトは clientRecordVersion
値の比較チェックを行います。挿入されるデータのバージョンが既存のデータのバージョンよりも高い場合は、アップサートが行われます。それ以外の場合は、この変更は無視され、値は同じままになります。
データにバージョニングを含めるには、バージョニングのロジックに基づいて Metadata.clientRecordVersion
に Long
値を指定する必要があります。
val sr = StepsRecord(
count = count,
startTime = startTime,
startZoneOffset = startZoneOffset,
endTime = endTime,
endZoneOffset = endZoneOffset,
metadata = Metadata(
clientRecordId = cid,
clientRecordVersion = version
)
)
Upsert は、データが予期せず上書きされるのを防ぐため、変更が発生しても version
を自動更新しません。そのため、今より大きな値を手動で指定する必要があります。
ベスト プラクティス
ロジックを構築したら、データの書き込みや更新を行う際にこちらのベスト プラクティスを検討してください。