Это руководство совместимо с платформой "Здоровье и спорт" версии 1.1.0-alpha11.
Платформа "Здоровье и спорт" предоставляет тип данных Сеанс сна, чтобы хранить информацию о сне пользователя, например о ночном сне или дневном сне.
Для представления этих сеансов используется тип данных SleepSessionRecord.
Сеансы позволяют отслеживать показатели, связанные со временем, например непрерывные данные о пульсе или местоположении.
Сеансы SleepSessionRecord содержат данные о фазах сна, например AWAKE, SLEEPING и DEEP.
Данные подтипа относятся к сеансу и имеют смысл только при чтении с родительским сеансом. Например, фаза сна.
Связанные данные – это данные, которые регистрируются независимо, но относятся к временному диапазону сеанса. Например, если пользователь записывает пульс во время сеанса сна, то данные о пульсе будут считаться связанными данными. В отличие от данных подтипа, которые являются частью записи сеанса, связанные данные состоят из отдельных записей, у каждой из которых есть собственный UUID.
Проверьте доступность платформы "Здоровье и спорт"
Прежде чем пытаться использовать Здоровье и спорт, ваше приложение должно проверить, доступна ли эта платформа на устройстве пользователя. Приложение "Здоровье и спорт" может быть не предустановлено на некоторых устройствах или отключено.
Проверить доступность можно с помощью метода 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_SLEEPandroid.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.
val permissions = setOf( HealthPermission.getReadPermission(SleepSessionRecord::class), HealthPermission.getWritePermission(SleepSessionRecord::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.") } } }
Поддерживаемые агрегации
Для параметра 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", metadata = Metadata.activelyRecorded(device = Device(type = Device.TYPE_WATCH)) ), ) ) }
- Данные подтипа должны быть выровнены в сеансе с последовательными временными метками, которые не перекрываются. но пробелы допускаются.
- Данные подтипа не содержат UUID, но связанные данные имеют разные UUID.
- Сеансы полезны, если пользователь хочет, чтобы данные были связаны с сеансом и отслеживались как его часть, а не регистрировались непрерывно.
Сеансы сна
Вы можете читать и записывать данные о сне в Health Connect. Данные о сне отображаются в виде сеансов и могут быть разделены на восемь фаз:
UNKNOWN– не указано или неизвестно, спит ли пользователь.AWAKE: пользователь проснулся в течение цикла сна, а не днем.SLEEPING– общее описание сна.OUT_OF_BED– пользователь встал с кровати во время сеанса сна.AWAKE_IN_BED– пользователь бодрствует в постели.LIGHT– пользователь находится в фазе поверхностного сна.DEEP– пользователь находится в фазе глубокого сна.REM– пользователь находится в фазе быстрого сна.
Эти значения представляют собой тип сна пользователя в определенном временном диапазоне. Записывать этапы сна необязательно, но рекомендуется, если такая возможность есть.
Запись данных о сеансах сна
Тип данных SleepSessionRecord состоит из двух частей:
- Общий сеанс, охватывающий весь период сна.
- Отдельные фазы сна, например поверхностный или глубокий сон.
Вот как добавить сеанс сна без фаз:
val zoneRules = ZoneId.systemDefault().rules // Calculate the specific offset for both start and end times val startOffset = zoneRules.getOffset(startTime) val endOffset = zoneRules.getOffset(endTime) SleepSessionRecord( title = "weekend sleep", startTime = startTime, endTime = endTime, startZoneOffset = startOffset, endZoneOffset = endOffset, metadata = Metadata.activelyRecorded(device = Device(type = Device.TYPE_WATCH)) )
Вот как добавить фазы, которые охватывают весь период сеанса сна:
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,
)
Как читать данные о сеансах сна
Для каждого сеанса сна, возвращенного в ответе, необходимо проверить, есть ли данные о фазах сна:
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 }
Как удалить сеанс сна
Вот как удалить сеанс. В этом примере мы использовали сеанс сна:
val timeRangeFilter = TimeRangeFilter.between(sleepRecord.startTime, sleepRecord.endTime) healthConnectClient.deleteRecords(SleepSessionRecord::class, timeRangeFilter)