Это руководство совместимо с платформой "Здоровье и спорт" версии 1.1.0-alpha12 или более поздней.
На платформе "Здоровье и спорт" есть тип данных Сеанс сна, который позволяет хранить информацию о сне пользователя, например о ночном или дневном сне.
Для представления таких сеансов используется тип данных SleepSessionRecord.
Сеансы позволяют пользователям отслеживать показатели за определенный период времени, например непрерывно измерять пульс или собирать данные о местоположении.
Сеансы SleepSessionRecord содержат данные о фазах сна, например AWAKE, SLEEPING и DEEP.
Подтип – это данные, которые "принадлежат" сеансу и имеют смысл только при чтении с родительским сеансом. Например, фаза сна.
Связанные данные, с другой стороны, регистрируются независимо, но относятся к интервалу времени сеанса. Например, если пользователь записывает пульс во время сеанса сна, то данные о пульсе будут связанными. В отличие от данных подтипа, которые являются частью записи сеанса, связанные данные состоят из независимых записей, каждая из которых имеет собственный UUID.
Как проверить доступность платформы "Здоровье и спорт"
Прежде чем использовать платформу "Здоровье и спорт", приложение должно проверить, доступна ли она на устройстве пользователя. Платформа "Здоровье и спорт" может быть не предустановлена на некоторых устройствах или отключена.
Проверить доступность можно с помощью метода HealthConnectClient.getSdkStatus().
Как проверить доступность платформы "Здоровье и спорт"
fun checkHealthConnectAvailability(context: Context) { val providerPackageName = "com.google.android.apps.healthdata" 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 доступны следующие агрегированные значения:
Общие рекомендации
Ниже приведены рекомендации по работе с сеансами сна в платформе "Здоровье и спорт".
- Сеансы следует использовать для добавления данных из определенного сеанса сна, для сна:
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.
- Сеансы полезны, если пользователь хочет, чтобы данные были связаны с сеансом (и отслеживались как его часть), а не записывались непрерывно.
Сеансы сна
Вы можете читать и записывать данные о сне в приложении "Здоровье и спорт". Данные о сне отображаются в виде сеанса и могут быть разделены на восемь отдельных фаз сна:
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)