次の例は、一般的なワークフローの一環として元データを読み取る方法を示しています。
データを読み取る
ヘルスコネクトでは、アプリがフォアグラウンドとバックグラウンドにあるときに、アプリがデータストアからデータを読み取ることができます。
フォアグラウンドの読み取り: 通常、アプリがフォアグラウンドにある場合は、ヘルスコネクトからデータを読み取ることができます。このような場合は、読み取りオペレーション中にユーザーまたはシステムがアプリをバックグラウンドに配置した場合に、フォアグラウンド サービスを使用してこのオペレーションを実行することを検討してください。
バックグラウンドでの読み取り: ユーザーに追加の権限をリクエストすることで、ユーザーまたはシステムがアプリをバックグラウンドに配置した後もデータを読み取ることができます。完全なバックグラウンド読み取りの例をご覧ください。
ヘルスコネクトのデータの種類「歩数」では、各読み取りの間にユーザーが歩いた歩数が記録されます。歩数は、健康、フィットネス、ウェルネスのプラットフォームで共通の測定値を表します。ヘルスコネクトでは、歩数データの読み取りと書き込みが簡単にできます。
レコードを読み取るには、ReadRecordsRequest
を作成し、readRecords
の呼び出し時に指定します。
次の例は、特定期間内のユーザーの歩数データを読み取る方法を示しています。SensorManager
を使用した拡張例については、歩数のデータガイドをご覧ください。
suspend fun readHeartRateByTimeRange(
healthConnectClient: HealthConnectClient,
startTime: Instant,
endTime: Instant
) {
try {
val response = healthConnectClient.readRecords(
ReadRecordsRequest(
HeartRateRecord::class,
timeRangeFilter = TimeRangeFilter.between(startTime, endTime)
)
)
for (record in response.records) {
// Process each record
}
} catch (e: Exception) {
// Run error handling here
}
}
また、aggregate
を使用して、データを集計して読み取ることもできます。
suspend fun readStepsByTimeRange(
healthConnectClient: HealthConnectClient,
startTime: Instant,
endTime: Instant
) {
try {
val response = healthConnectClient.aggregate(
AggregateRequest(
metrics = setOf(StepsRecord.COUNT_TOTAL),
timeRangeFilter = TimeRangeFilter.between(startTime, endTime)
)
)
// The result may be null if no data is available in the time range
val stepCount = response[StepsRecord.COUNT_TOTAL]
} catch (e: Exception) {
// Run error handling here
}
}
バックグラウンドでの読み取りの例
バックグラウンドでデータを読み取るには、マニフェスト ファイルで次の権限を宣言します。
<application>
<uses-permission android:name="android.permission.health.READ_HEALTH_DATA_IN_BACKGROUND" />
...
</application>
次の例は、WorkManager
を使用して、特定期間内のユーザーの歩数データをバックグラウンドで読み取る方法を示しています。
class ScheduleWorker(private val appContext: Context, workerParams: WorkerParameters):
CoroutineWorker(appContext, workerParams) {
override suspend fun doWork(): Result {
// Read data and process it.
...
// Return success indicating successful data retrieval
return Result.success()
}
}
if (healthConnectClient
.features
.getFeatureStatus(
HealthConnectFeatures.FEATURE_READ_HEALTH_DATA_IN_BACKGROUND
) == HealthConnectFeatures.FEATURE_STATUS_AVAILABLE) {
// Check if necessary permission is granted
val grantedPermissions = healthConnectClient.permissionController.getGrantedPermissions()
if (PERMISSION_READ_HEALTH_DATA_IN_BACKGROUND !in grantedPermissions) {
// Perform read in foreground
...
} else {
// Schedule the periodic work request in background
val periodicWorkRequest = PeriodicWorkRequestBuilder<ScheduleWorker>(1, TimeUnit.HOURS)
.build()
WorkManager.getInstance(context).enqueueUniquePeriodicWork(
"read_health_connect",
ExistingPeriodicWorkPolicy.KEEP,
periodicWorkRequest
)
}
} else {
// Background reading is not available, perform read in foreground
...
}
ReadRecordsRequest
パラメータのデフォルトの pageSize
値は 1000 です。単一の readResponse
のレコード数がリクエストの pageSize
を超える場合は、pageToken
を使用してレスポンスのすべてのページを反復処理し、すべてのレコードを取得する必要があります。ただし、レート制限に関する問題が発生しないように注意してください。
pageToken の読み取りの例
リクエストされた期間のすべての利用可能なデータを取得するには、レコードの読み取りに pageToken
を使用することをおすすめします。
次の例は、すべてのページトークンが使い果たされるまで、すべてのレコードを読み取る方法を示しています。
val type = HeartRateRecord::class
val endTime = Instant.now()
val startTime = endTime.minus(Duration.ofDays(7))
try {
var pageToken: String? = null
do {
val readResponse =
healthConnectClient.readRecords(
ReadRecordsRequest(
recordType = type,
timeRangeFilter = TimeRangeFilter.between(
startTime,
endTime
),
pageToken = pageToken
)
)
val records = readResponse.records
// Do something with records
pageToken = readResponse.pageToken
} while (pageToken != null)
} catch (quotaError: IllegalStateException) {
// Backoff
}
大規模なデータセットを読み取る際のベスト プラクティスについては、レート制限を回避するための計画をご覧ください。
以前に書き込まれたデータを読み取る
アプリが以前にヘルスコネクトにレコードを書き込んでいた場合は、そのアプリで履歴データを読み取ることができます。これは、ユーザーによるインストール後にヘルスコネクトと再同期する必要があるシナリオに該当します。
読み取りにはいくつかの制限があります。
Android 14 以降の場合
- アプリが自身のデータを読み取る際の過去の制限はありません。
- アプリが他のデータを読み取る際の 30 日間の制限。
Android 13 以前の場合
- アプリがデータを読み取る際の 30 日間の制限。
制限は、読み取り権限をリクエストすることで解除できます。
履歴データを読み取るには、ReadRecordsRequest
の dataOriginFilter
パラメータで、パッケージ名を DataOrigin
オブジェクトとして指定する必要があります。
次の例は、心拍数レコードを読み取るときにパッケージ名を指定する方法を示しています。
try {
val response = healthConnectClient.readRecords(
ReadRecordsRequest(
recordType = HeartRateRecord::class,
timeRangeFilter = TimeRangeFilter.between(startTime, endTime),
dataOriginFilter = setOf(DataOrigin("com.my.package.name"))
)
)
for (record in response.records) {
// Process each record
}
} catch (e: Exception) {
// Run error handling here
}
30 日以上前のデータを読み取る
デフォルトでは、すべてのアプリは、最初に権限が付与された日の 30 日前までのデータをヘルスコネクトから読み取ることができます。
デフォルトの制限を超えて読み取り権限を拡張する必要がある場合は、PERMISSION_READ_HEALTH_DATA_HISTORY
をリクエストします。この権限がない場合、30 日より古いレコードを読み取ろうとするとエラーが発生します。
削除されたアプリの権限の履歴
ユーザーがアプリを削除すると、履歴権限を含むすべての権限が取り消されます。ユーザーがアプリを再インストールして権限を再度付与すると、同じデフォルトの制限が適用され、アプリは新しい日付から最大 30 日間遡ってヘルスコネクトからデータを読み取れます。
たとえば、ユーザーが 2023 年 5 月 10 日にアプリを削除し、2023 年 5 月 15 日にアプリを再インストールして読み取り権限を付与したとします。この場合、アプリはデフォルトで 2023 年 4 月 15 日以降のデータを読み取れます。