피부 온도 측정

이 가이드는 헬스 커넥트 버전 1.1.0-alpha12와 호환됩니다.

헬스 커넥트는 주변부 체온을 측정하는 피부 온도 데이터 유형을 제공합니다. 이 측정은 수면의 질, 생식 건강, 질병의 잠재적 발병을 감지하는 데 특히 유용한 신호입니다.

헬스 커넥트 사용 가능 여부 확인

헬스 커넥트를 사용하기 전에 앱에서 사용자의 기기에서 헬스 커넥트를 사용할 수 있는지 확인해야 합니다. 헬스 커넥트가 일부 기기에 사전 설치되어 있지 않거나 사용 중지되어 있을 수 있습니다. HealthConnectClient.getSdkStatus() 메서드를 사용하여 사용 가능 여부를 확인할 수 있습니다.

헬스 커넥트 사용 가능 여부를 확인하는 방법

fun checkHealthConnectAvailability(context: Context) {
    val providerPackageName = "com.google.android.apps.healthdata" // Or get from HealthConnectClient.DEFAULT_PROVIDER_PACKAGE_NAME
    val availabilityStatus = HealthConnectClient.getSdkStatus(context, providerPackageName)

    if (availabilityStatus == HealthConnectClient.SDK_UNAVAILABLE) {
      // Health Connect is not available. Guide the user to install/enable it.
      // For example, show a dialog.
      return // early return as there is no viable integration
    }
    if (availabilityStatus == HealthConnectClient.SDK_UNAVAILABLE_PROVIDER_UPDATE_REQUIRED) {
      // Health Connect is available but requires an update.
      // Optionally redirect to package installer to find a provider, for example:
      val uriString = "market://details?id=$providerPackageName&url=healthconnect%3A%2F%2Fonboarding"
      context.startActivity(
        Intent(Intent.ACTION_VIEW).apply {
          setPackage("com.android.vending")
          data = Uri.parse(uriString)
          putExtra("overlay", true)
          putExtra("callerId", context.packageName)
        }
      )
      return
    }
    // Health Connect is available, obtain a HealthConnectClient instance
    val healthConnectClient = HealthConnectClient.getOrCreate(context)
    // Issue operations with healthConnectClient
}

getSdkStatus()에서 반환된 상태에 따라 필요한 경우 Google Play 스토어에서 헬스 커넥트를 설치하거나 업데이트하도록 사용자에게 안내할 수 있습니다.

기능 사용 가능 여부

사용자 기기가 헬스 커넥트에서 피부 온도를 지원하는지 확인하려면 클라이언트에서 FEATURE_SKIN_TEMPERATURE의 사용 가능 여부를 확인하세요.

if (healthConnectClient
     .features
     .getFeatureStatus(
       HealthConnectFeatures.FEATURE_SKIN_TEMPERATURE
     ) == HealthConnectFeatures.FEATURE_STATUS_AVAILABLE) {

  // Feature is available
} else {
  // Feature isn't available
}
자세한 내용은 기능 사용 가능 여부 확인을 참고하세요.

필수 권한

피부 온도에 대한 액세스는 다음 권한으로 보호됩니다.

  • android.permission.health.READ_SKIN_TEMPERATURE
  • android.permission.health.WRITE_SKIN_TEMPERATURE

앱에 피부 온도 기능을 추가하려면 먼저 SkinTemperature 데이터 유형에 대한 권한을 요청하세요.

피부 온도를 쓰기 위해 선언해야 하는 권한은 다음과 같습니다.

<application>
  <uses-permission
android:name="android.permission.health.WRITE_SKIN_TEMPERATURE" />
...
</application>

피부 온도를 읽으려면 다음 권한을 요청해야 합니다.

<application>
  <uses-permission
android:name="android.permission.health.READ_SKIN_TEMPERATURE" />
...
</application>

사용자에게 권한 요청

클라이언트 인스턴스를 만든 후 앱은 사용자에게 권한을 요청해야 합니다. 사용자는 언제든지 권한을 부여하거나 거부할 수 있어야 합니다. 이렇게 하려면 필요한 데이터 유형의 권한 집합을 만드세요. 집합에 있는 권한이 먼저 Android 매니페스트에 선언되어 있는지 확인합니다.

val permissions =
    setOf(
        HealthPermission.getReadPermission(SkinTemperatureRecord::class),
        HealthPermission.getWritePermission(SkinTemperatureRecord::class)
    )
getGrantedPermissions을 사용하여 앱에 필요한 권한이 이미 부여되어 있는지 확인합니다. 그렇지 않은 경우 createRequestPermissionResultContract을 사용하여 해당 권한을 요청합니다. 헬스 커넥트 권한 화면이 표시됩니다.
val permissions = setOf(
        HealthPermission.getReadPermission(StepsRecord::class),
        HealthPermission.getWritePermission(StepsRecord::class),
        HealthPermission.getReadPermission(HeartRateRecord::class),
        HealthPermission.getWritePermission(HeartRateRecord::class)
    )

val requestPermissionsLauncher = rememberLauncherForActivityResult(
    contract = PermissionController.createRequestPermissionResultContract()
) { grantedPermissions ->
    if (grantedPermissions.containsAll(permissions)) {
        coroutineScope.launch { snackbarHostState.showSnackbar("Permissions granted!") }
    } else {
        coroutineScope.launch { snackbarHostState.showSnackbar("Permissions denied.") }
    }
}
사용자는 언제든지 권한을 부여하거나 취소할 수 있으므로 앱은 권한을 사용하기 전에 매번 권한을 확인하고 권한이 손실된 시나리오를 처리해야 합니다.

피부 온도 기록에 포함된 정보

피부 온도 측정값은 기록으로 정리됩니다. 각 레코드는 다음 정보로 구성됩니다.

  • 기초 온도(섭씨 또는 화씨) 이는 앱의 UI에서 시각화하는 데 가장 유용한 선택적 값입니다.
  • 피부 온도의 델타 목록입니다. 각 델타는 마지막 측정 이후의 피부 온도 변화를 보여줍니다. 기준 온도가 제공된 경우 이러한 델타는 동일한 온도 단위를 사용해야 합니다.
  • 측정이 이루어진 사용자의 신체 위치입니다(손가락, 발가락, 손목).

지원되는 집계

SkinTemperatureRecord에 사용할 수 있는 집계 값은 다음과 같습니다.

사용 예시

다음 코드 스니펫은 피부 온도 측정을 읽고 쓰는 방법을 보여줍니다.

피부 온도 기록 읽기

다음 코드 스니펫은 Jetpack 라이브러리를 사용하여 피부 온도 측정을 읽는 방법을 보여줍니다.

suspend fun readSkinTemperatures() {
    // Error handling, permission check, and feature availability check
    // aren't included.

    // Record includes measurements during the past hour.
    val recordEndTime = Instant.now()
    val recordStartTime = recordEndTime.minusSeconds(60 * 60)

    val response = healthConnectClient.readRecords(
        ReadRecordsRequest<SkinTemperatureRecord>(
            timeRangeFilter = TimeRangeFilter.between(
                recordStartTime, recordEndTime
            )
        )
    )

    for (skinTemperatureRecord in response.records) {
        // Process each skin temperature record here.
    }
}

피부 온도 기록 쓰기

다음 코드 스니펫은 Jetpack 라이브러리를 사용하여 피부 온도 측정을 쓰는 방법을 보여줍니다.


suspend fun writeSkinTemperatures(): InsertRecordsResponse {
    // Error handling, permission check, and feature availability check
    // aren't included.

    // Record includes measurements during the past hour.
    val recordEndTime: ZonedDateTime = now()
    val recordStartTime: ZonedDateTime = recordEndTime.minusHours(1)

    healthConnectClient.insertRecords(
        // For this example, there's only one skin temperature record.
        listOf(
            SkinTemperatureRecord(
                baseline = Temperature.celsius(37.0),
                startTime = recordStartTime.toInstant(),
                startZoneOffset = recordStartTime.offset,
                endTime = recordEndTime.toInstant(),
                endZoneOffset = recordEndTime.offset,
                deltas = listOf(
                    SkinTemperatureRecord.Delta(
                        recordEndTime.minusMinutes(50).toInstant(), celsius(0.5)
                    ), SkinTemperatureRecord.Delta(
                        recordEndTime.minusMinutes(30).toInstant(), celsius(-0.7)
                    )
                ),
                measurementLocation = SkinTemperatureRecord.MEASUREMENT_LOCATION_FINGER,
                metadata = Metadata.autoRecorded(
                    device = Device(type = Device.TYPE_RING)
                ),
            )
        )
    )
}