本指南適用於「健康資料同步」1.1.0-alpha11 版。
健康資料同步提供睡眠階段資料類型,可儲存使用者的睡眠資訊,例如夜間睡眠或午睡。SleepSessionRecord
資料類型用於表示這些工作階段。
使用者可利用時段,在一段時間內依據時間來評估成效,例如連續心率或位置資料。
SleepSessionRecord
時段包含記錄睡眠階段的資料,例如 AWAKE
、SLEEPING
和 DEEP
。
子類型資料是「屬於」時段的資料,而且只在與父項時段一併讀取時才有意義。例如睡眠階段。
確認「健康資料同步」適用情形
嘗試使用健康資料同步前,應用程式應先確認使用者的裝置是否支援健康資料同步。部分裝置可能未預先安裝「健康資料同步」或已停用這項功能。
您可以使用 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 商店安裝或更新「健康資料同步」。
功能適用情況
這個資料類型沒有功能可用性旗標。
所需權限
存取睡眠記錄時,系統會要求下列權限:
android.permission.health.READ_SLEEP
android.permission.health.WRITE_SLEEP
如要為應用程式新增睡眠記錄功能,請先要求 SleepSession
資料類型的寫入權限。
您需要宣告以下權限,才能寫入睡眠記錄:
<application>
<uses-permission
android:name="android.permission.health.WRITE_SLEEP" />
...
</application>
如要讀取睡眠記錄,您必須要求下列權限:
<application>
<uses-permission
android:name="android.permission.health.READ_SLEEP" />
...
</application>
要求使用者授予權限
建立用戶端執行個體後,應用程式必須要求使用者授予權限。使用者必須能隨時授予或拒絕權限。
如要這麼做,請為所需資料類型建立一組權限。請務必先在 Android 資訊清單中聲明該組權限。
// Create a set of permissions for required data types
val PERMISSIONS =
setOf(
HealthPermission.getReadPermission(SleepSessionRecord::class),
HealthPermission.getWritePermission(SleepSessionRecord::class)
)
使用 getGrantedPermissions
查看應用程式是否已具備所需權限。如果沒有,請使用 createRequestPermissionResultContract
要求這些權限。系統接著會顯示 Health Connect 權限畫面。
// Create the permissions launcher
val requestPermissionActivityContract = PermissionController.createRequestPermissionResultContract()
val requestPermissions = registerForActivityResult(requestPermissionActivityContract) { granted ->
if (granted.containsAll(PERMISSIONS)) {
// Permissions successfully granted
} else {
// Lack of required permissions
}
}
suspend fun checkPermissionsAndRun(healthConnectClient: HealthConnectClient) {
val granted = healthConnectClient.permissionController.getGrantedPermissions()
if (granted.containsAll(PERMISSIONS)) {
// Permissions already granted; proceed with inserting or reading data
} else {
requestPermissions.launch(PERMISSIONS)
}
}
由於使用者可以隨時授予或撤銷權限,應用程式需要定期檢查獲得的權限,並處理權限遺失的情況。
支援的匯總
下列匯總值適用於 SleepSessionRecord
:
一般指南
以下提供一些最佳做法指南,說明如何在 Health Connect 中使用睡眠時段。
- 時段應用於新增來自特定睡眠時段的資料,或針對睡眠的資料:
suspend fun writeSleepSession(healthConnectClient: HealthConnectClient) {
healthConnectClient.insertRecords(
listOf(
SleepSessionRecord(
startTime = Instant.parse("2022-05-10T23:00:00.000Z"),
startZoneOffset = ZoneOffset.of("-08:00"),
endTime = Instant.parse("2022-05-11T07:00:00.000Z"),
endZoneOffset = ZoneOffset.of("-08:00"),
title = "My Sleep"
),
)
)
}
- 時段不應用於一般測量項目,例如每日步數。
- 子類型資料不包含 UID,但關聯資料具有不同的 UID。
- 子類型資料必須符合時段中不重疊的序列時間戳記,不過可以出現間隔。
- 如果使用者想將資料與時段建立關聯 並以時段的形式加以追蹤,而非持續記錄資料,這時就適合使用時段。
睡眠記錄
您可以在「健康資料同步」中讀取或寫入睡眠資料。睡眠資料會顯示為時段,並且可分為 8 個不同的睡眠階段:
UNKNOWN
:未指定或不知道使用者是否入睡。AWAKE
:使用者在睡眠週期內 (而非日間) 醒來。SLEEPING
:一般或不精細的睡眠描述。OUT_OF_BED
:使用者在睡眠時段中離開床鋪。AWAKE_IN_BED
:使用者在床上醒來。LIGHT
:使用者處於淺眠週期。DEEP
:使用者處於深層睡眠週期。REM
:使用者處於快速動眼睡眠週期。
這些值代表使用者在特定時間範圍內的睡眠類型。您可選擇是否寫入睡眠階段,但在可用的情況下,建議您選擇寫入。
寫入睡眠時段
SleepSessionRecord
資料類型包含兩個部分:
- 整個時段,範圍涵蓋整個睡眠期間。
- 睡眠時段中的個別階段,例如淺眠或深層睡眠。
以下說明如何插入不含睡眠階段的睡眠時段:
SleepSessionRecord(
title = "weekend sleep",
startTime = startTime,
endTime = endTime,
startZoneOffset = ZoneOffset.UTC,
endZoneOffset = ZoneOffset.UTC,
)
以下說明如何新增涵蓋整個睡眠時段的睡眠階段:
val stages = listOf(
SleepSessionRecord.Stage(
startTime = START_TIME
endTime = END_TIME,
stage = SleepSessionRecord.STAGE_TYPE_SLEEPING,
)
)
SleepSessionRecord(
title = "weekend sleep",
startTime = START_TIME,
endTime = END_TIME,
startZoneOffset = START_ZONE_OFFSET,
endZoneOffset = END_ZONE_OFFSET,
stages = stages,
)
讀取睡眠時段
針對系統傳回的每個睡眠時段,您應該檢查是否同時顯示睡眠階段資料:
suspend fun readSleepSessions(
healthConnectClient: HealthConnectClient,
startTime: Instant,
endTime: Instant
) {
val response =
healthConnectClient.readRecords(
ReadRecordsRequest(
SleepSessionRecord::class,
timeRangeFilter = TimeRangeFilter.between(startTime, endTime)
)
)
for (sleepRecord in response.records) {
// Retrieve relevant sleep stages from each sleep record
val sleepStages = sleepRecord.stages
}
}
刪除睡眠記錄
以下說明如何刪除時段。在這個範例中,我們使用的是睡眠時段:
suspend fun deleteSleepSession(
healthConnectClient: HealthConnectClient,
sleepRecord: SleepSessionRecord,
) {
val timeRangeFilter = TimeRangeFilter.between(sleepRecord.startTime, sleepRecord.endTime)
healthConnectClient.deleteRecords(SleepSessionRecord::class, timeRangeFilter)
}