다음 예는 원시 데이터를 일반적인 워크플로의 일부로 읽는 방법을 보여줍니다.
데이터 읽기
헬스 커넥트를 사용하면 앱이 포그라운드 및 백그라운드에 있을 때 데이터 스토어에서 데이터를 읽을 수 있습니다.
포그라운드 읽기: 일반적으로 앱이 포그라운드에 있을 때 헬스 커넥트에서 데이터를 읽을 수 있습니다. 이러한 경우 읽기 작업 중에 사용자 또는 시스템이 앱을 백그라운드에 배치할 경우 포그라운드 서비스를 사용하여 이 작업을 실행하는 것이 좋습니다.
백그라운드 읽기: 사용자에게 추가 권한을 요청하여 사용자 또는 시스템이 앱을 백그라운드에 배치한 후 데이터를 읽을 수 있습니다. 전체 백그라운드 읽기 예를 참고하세요.
헬스 커넥트의 걸음 수 데이터 유형은 측정 시점과 시점 사이에 사용자가 걸은 걸음 수를 포착합니다. 걸음 수는 건강, 피트니스, 웰빙 플랫폼에서 공통으로 측정되는 수치를 나타냅니다. 헬스 커넥트를 사용하면 걸음 수 데이터를 읽고 쓸 수 있습니다.
기록을 읽으려면 ReadRecordsRequest를 만들고
를 호출할 때 제공합니다.readRecords
다음 예는 특정 시간 내에 사용자의 걸음 수 데이터를 읽는 방법을 보여줍니다. SensorManager,
확장된 예는 걸음 수 데이터 가이드를 참고하세요.
val response = healthConnectClient.readRecords( ReadRecordsRequest( HeartRateRecord::class, timeRangeFilter = TimeRangeFilter.between(startTime, endTime) ) ) response.records.forEach { record -> /* Process records */ }
`aggregate`를 사용하여 집계된 방식으로 데이터를 읽을 수도 있습니다.
suspend fun readStepsAggregate(startTime: Instant, endTime: Instant): Long { val response = healthConnectClient.aggregate( AggregateRequest( metrics = setOf(StepsRecord.COUNT_TOTAL), timeRangeFilter = TimeRangeFilter.between(startTime, endTime) ) ) return response[StepsRecord.COUNT_TOTAL] ?: 0L }
모바일 걸음 수 읽기
Android 14 (API 수준 34) 및 SDK 확장 프로그램 버전 20 이상을 사용하면 헬스 커넥트에서 기기 내 걸음 수 계산을 제공합니다. 앱에 READ_STEPS 권한이 부여된 경우 헬스 커넥트에서 Android 지원 기기의 걸음 수 포착을 시작하고 사용자는 헬스 커넥트 걸음 수 항목에 걸음 수 데이터가 자동으로 추가되는 것을 볼 수 있습니다.
기기 내 걸음 수 계산을 사용할 수 있는지 확인하려면 기기가 Android 14 (API 수준 34)를 실행하고 SDK 확장 프로그램 버전 20 이상이 있는지 확인하세요.
val isStepTrackingAvailable =
Build.VERSION.SDK_INT >= Build.VERSION_CODES.UPSIDE_DOWN_CAKE &&
SdkExtensions.getExtensionVersion(Build.VERSION_CODES.UPSIDE_DOWN_CAKE) >= 20
앱이 집계된 걸음 수를 사용하여
aggregate를 읽고 DataOrigin로 필터링하지 않는 경우 기기 내
걸음 수가 총계에 자동으로 포함되며
2026년 6월 업데이트에 변경사항이 필요하지 않습니다.
기기 내 걸음 수의 기여도 변경
2026년 6월 업데이트부터 헬스
커넥트에서 기본적으로 추적되는 걸음 수는 합성 패키지 이름 (SPN)에 기여됩니다.
com.android.healthconnect.phone.jd5bdd37e1a8d3667a05d0abebfc4a89e
이전에는 기본 제공 걸음 수가 패키지 이름 android에 기여되었습니다.
2026년 6월 이전에 기록된 이전 걸음 수 데이터는 android 패키지 이름을 유지합니다.
SPN은 기기별이며 사용자 개인 정보 보호를 위해 애플리케이션별로 범위가 지정됩니다.
- 안정적: 현재 기기의 SPN은 애플리케이션에서 안정적입니다.
- 애플리케이션 범위: 동일한 기기의 여러 애플리케이션은 기기 내 걸음 수 데이터에 대해 서로 다른 SPN을 확인합니다.
기기 내 걸음 수 쿼리
SPN은 범위가 지정되고 기기별이므로 SPN 값을 하드 코딩하면 안 됩니다. 대신 getCurrentDeviceDataSource() API를 사용하여 현재 기기의 SPN을 가져옵니다.
기기 내 걸음 수 계산에는 SDK 확장 프로그램 버전 20 이상이 필요하지만 getCurrentDeviceDataSource() API는 SDK 확장 프로그램 버전 11 이상이 있는 Android 14 (API 수준 34)에서 사용할 수 있습니다.
getCurrentDeviceDataSource() API는 아직 헬스 커넥트 Jetpack 라이브러리에서 사용할 수 없습니다. 다음 예에서는 대신 Android 프레임워크 API를 사용합니다.
import android.content.Context
import android.health.connect.HealthConnectManager
val healthConnectManager = context.getSystemService(HealthConnectManager::class.java)
val deviceDataSource = healthConnectManager?.getCurrentDeviceDataSource()
val currentDeviceSpn = deviceDataSource?.deviceDataOrigin?.packageName
앱에서 기기 내 걸음 수를 읽어야 하거나 소스 애플리케이션 또는 기기별로 분류된 걸음 수 데이터를 표시하는 경우 DataOrigin이 android 이거나 기기의 SPN과 일치하는 기록을 쿼리해야 합니다. 앱에서 걸음 수 데이터의 기여도를 표시하는 경우 metadata.device를 사용하여 개별 기록의 소스 기기를 식별합니다. 집계된 데이터에서 SPN으로 식별되는 기기 내 걸음 수의 경우 기여도에 DeviceDataSource의 model 또는 manufacturer와 같은 기기 메타데이터를 사용하거나 기기 내 걸음 수에 '내 휴대전화'와 같은 일반적인 라벨을 사용할 수 있습니다.
다음 예는 android와 현재 기기 SPN을 모두 필터링하여 집계된 기기 내 걸음 수 데이터를 읽는 방법을 보여줍니다.
import android.content.Context
import android.health.connect.HealthConnectManager
import android.os.Build
import android.os.ext.SdkExtensions
import androidx.health.connect.client.HealthConnectClient
import androidx.health.connect.client.records.StepsRecord
import androidx.health.connect.client.records.metadata.DataOrigin
import androidx.health.connect.client.request.AggregateRequest
import androidx.health.connect.client.time.TimeRangeFilter
import java.time.Instant
suspend fun readDeviceStepsByTimeRange(
healthConnectClient: HealthConnectClient,
context: Context,
startTime: Instant,
endTime: Instant
) {
// 1. Check if SDK Extension 11+ is available for getCurrentDeviceDataSource()
val isDataSourceApiAvailable = Build.VERSION.SDK_INT >= Build.VERSION_CODES.U &&
SdkExtensions.getExtensionVersion(Build.VERSION_CODES.U) >= 11
try {
val healthConnectManager = context.getSystemService(HealthConnectManager::class.java)
// 2. Safely fetch the package name only if API is available and data exists
val currentDeviceSpn = if (isDataSourceApiAvailable) {
healthConnectManager?.getCurrentDeviceDataSource()?.deviceDataOrigin?.packageName
} else {
null
}
val dataOriginFilters = mutableSetOf(DataOrigin("android"))
// 3. Explicit null-safety check using .let
currentDeviceSpn?.let {
dataOriginFilters.add(DataOrigin(it))
}
val response = healthConnectClient.aggregate(
AggregateRequest(
metrics = setOf(StepsRecord.COUNT_TOTAL),
timeRangeFilter = TimeRangeFilter.between(startTime, endTime),
dataOriginFilter = dataOriginFilters
)
)
val stepCount = response[StepsRecord.COUNT_TOTAL]
} catch (e: Exception) {
// Now this catch block only handles actual runtime exceptions,
// rather than Errors from missing methods.
}
}
기기 내 걸음 수 계산
- 센서 사용량: 헬스 커넥트는
TYPE_STEP_COUNTER센서를SensorManager에서 활용합니다. 이 센서는 전력 소비를 최소화하도록 최적화되어 있어 지속적인 백그라운드 걸음 수 추적에 적합합니다. - 데이터 세분성: 배터리 수명을 보존하기 위해 걸음 수 데이터는 일반적으로 일괄 처리되어 헬스 커넥트 데이터베이스에 1분에 한 번 이하로 기록됩니다.
- 기여도: 2026년 6월 이전에 이 기능으로 기록된 걸음 수는
android패키지 이름에 기여됩니다.DataOrigin. 이 날짜 이후에는 기기별 SPN에 기여됩니다. 기기 내 걸음 수의 기여도 변경을 참고하세요. - 활성화: 기기 내 걸음 수 계산 메커니즘은 기기의 애플리케이션 중 하나 이상에 헬스 커넥트 내에서
READ_STEPS권한이 부여된 경우에만 활성화됩니다.
백그라운드 읽기 예
백그라운드에서 데이터를 읽으려면 매니페스트 파일에서 다음 권한을 선언합니다.
<application>
<uses-permission android:name="android.permission.health.READ_HEALTH_DATA_IN_BACKGROUND" />
...
</application>
다음 예는 WorkManager를 사용하여 특정 시간 내에 사용자의 백그라운드에서 걸음 수 데이터를 읽는 방법을 보여줍니다.
class ScheduleWorker(appContext: Context, workerParams: WorkerParameters) : CoroutineWorker(appContext, workerParams) { override suspend fun doWork(): Result { val healthConnectClient = HealthConnectClient.getOrCreate(applicationContext) // Perform background read logic here return Result.success() } }
@OptIn(ExperimentalFeatureAvailabilityApi::class) fun enqueueBackgroundReadWorker(context: Context, healthConnectClient: HealthConnectClient) { if (healthConnectClient .features .getFeatureStatus( HealthConnectFeatures.FEATURE_READ_HEALTH_DATA_IN_BACKGROUND ) == HealthConnectFeatures.FEATURE_STATUS_AVAILABLE ) { val periodicWorkRequest = PeriodicWorkRequestBuilder<ScheduleWorker>(1, TimeUnit.HOURS) .build() WorkManager.getInstance(context).enqueueUniquePeriodicWork( "read_health_connect", ExistingPeriodicWorkPolicy.KEEP, periodicWorkRequest ) } }
ReadRecordsRequest 매개변수의 기본 pageSize 값은 1,000입니다.
단일 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일 제한이 있습니다.
이전 데이터를 읽으려면 dataOriginFilter 매개변수에서 패키지 이름을
DataOrigin 객체로 표시해야 합니다.ReadRecordsRequest
다음 예는 심박수 기록을 읽을 때 패키지 이름을 표시하는 방법을 보여줍니다.
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일 입니다.
예외 처리
헬스 커넥트는 문제가 발생하면 CRUD 작업에 관한 표준 예외를 발생시킵니다. 앱은 이러한 예외를 적절하게 포착하고 처리해야 합니다.
HealthConnectClient의 각 메서드는 발생할 수 있는 예외를 나열합니다.
앱에서는 일반적으로 다음을 처리해야 합니다.
| 예외 | 설명 | 권장사항 |
|---|---|---|
IllegalStateException
| 다음 시나리오 중 하나가 발생했습니다.
| 요청을 진행하기 전에 먼저 입력과 관련하여 발생할 수 있는 문제를 해결합니다. 오류 처리 전략을 적용할 수 있도록, 요청에서 값을 직접 사용하는 대신 값을 변수에 할당하거나 사용자설정 함수 내에서 매개변수로 사용합니다. |
IOException
| 디스크에서 데이터를 읽고 쓸 때 문제가 발생합니다. | 이 문제를 방지하기 위한 권장사항은 다음과 같습니다.
|
RemoteException
| SDK가 연결되는 기본 서비스에서 또는 서비스와 통신하면서 오류가 발생했습니다. 예를 들어, 앱이 주어진 uid를 사용하여 레코드를 삭제하려고 하지만 앱이 기본 서비스에서 레코드가 존재하지 않는다는 사실을 확인한 후에 예외가 발생합니다.
| 이 문제를 방지하기 위한 권장사항은 다음과 같습니다.
|
SecurityException
| 요청에 부여되지 않은 권한이 필요한 경우 문제가 발생합니다. | 이를 방지하려면 게시된 앱에 헬스 커넥트 데이터 유형을 사용한다고 선언해야 합니다. 또한 매니페스트 파일과 활동에서 헬스 커넥트 권한을 선언해야 합니다. |