Si quieres crear una experiencia de seguimiento del sueño en tu app, puedes usar Health Connect para realizar las siguientes acciones:
- Cómo registrar sesiones de sueño
- Escribe datos de la etapa del sueño
- Escribir datos de sueño, como la frecuencia cardíaca, la saturación de oxígeno y la frecuencia respiratoria
- Leer datos de sueño de otras apps
En esta guía, se describe cómo compilar estas funciones de sueño, y se abarcan los tipos de datos, la ejecución en segundo plano, los permisos, los flujos de trabajo recomendados y las prácticas recomendadas.
Descripción general: Cómo compilar un dispositivo de monitoreo del sueño integral
Para crear una experiencia integral de monitoreo del sueño con Health Connect, sigue estos pasos principales:
- Implementar correctamente los permisos según los permisos de salud
- Graba sesiones con
SleepSessionRecord. - Escribir tipos de datos como las fases de sueño, la frecuencia cardíaca y la saturación de oxígeno de forma coherente durante la sesión
- Administrar correctamente la ejecución en segundo plano para verificar la captura continua de datos durante la noche
- Datos de la sesión de lectura para análisis y resúmenes posteriores al sueño
Este flujo de trabajo permite la interoperabilidad con otras apps de Health Connect y verifica el acceso a los datos controlado por el usuario.
Antes de comenzar
Antes de implementar las funciones de sueño, haz lo siguiente:
- Integra Health Connect con la dependencia adecuada.
- Crea una instancia de
HealthConnectClient. - Verifica que tu app implemente flujos de permisos en tiempo de ejecución basados en Health Permissions.
Conceptos clave
Health Connect representa los datos de sueño con algunos componentes principales. Un SleepSessionRecord actúa como el registro central del sueño, ya que contiene detalles como las horas de inicio o finalización y las fases del sueño. Durante una sesión, se pueden registrar varios tipos de datos, como HeartRateRecord o OxygenSaturationRecord.
Sesiones de sueño
Los datos de sueño se representan con SleepSessionRecord. Cada registro almacena lo siguiente:
startTimeendTimestages: Es una lista deSleepSessionRecord.Stageque incluye el sueño profundo, ligero, REM y de vigilia.- Metadatos de sesión opcionales (título, notas)
Las apps pueden escribir varios tipos de datos asociados con una sesión.
Tipos de datos
Entre los tipos de datos comunes que se registran durante una sesión de sueño, se incluyen los siguientes:
SleepSessionRecord: Registra la duración y las etapas del sueño, incluidos el sueño profundo, ligero, REM y en vigilia.HeartRateRecord: Registra la frecuencia cardíaca durante el sueño.OxygenSaturationRecord: Registra la saturación de oxígeno (SpO2) durante el sueño.RespiratoryRateRecord: Registra la frecuencia respiratoria durante el sueño.
Cada tipo de datos se almacena como un registro individual.
Consideraciones de desarrollo
Las apps de monitoreo del sueño suelen necesitar ejecutarse durante períodos prolongados, a menudo en segundo plano cuando la pantalla está apagada. Cuando crees tus funciones de sueño, es importante que consideres cómo administrar la ejecución en segundo plano y solicitar los permisos necesarios para los datos de sueño.
Ejecución en segundo plano
Las apps de monitoreo del sueño suelen ejecutarse durante la noche con la pantalla apagada. Cuando se encuentran en este estado, debes usar lo siguiente:
- Servicios en primer plano para la recopilación de datos
WorkManagerpara escritura o sincronización diferida- Estrategias de procesamiento por lotes para escrituras de registros regulares de datos detallados, como la frecuencia cardíaca
Mantén la continuidad conservando el ID de sesión coherente en todas las escrituras.
Permisos
Tu app debe solicitar los permisos pertinentes de Health Connect antes de leer o escribir datos de sueño. Para obtener una lista completa de los tipos de datos, consulta Tipos de datos de Health Connect. Los permisos comunes para el sueño incluyen sesiones de sueño y métricas como la frecuencia cardíaca o la saturación de oxígeno.
El acceso al sueño está protegido por los siguientes permisos:
android.permission.health.READ_SLEEPandroid.permission.health.WRITE_SLEEP
Para agregar la función de sueño a tu app, comienza por solicitar permisos para el tipo de datos SleepSession.
Este es el permiso que debes declarar para poder escribir el sueño:
<application>
<uses-permission
android:name="android.permission.health.WRITE_SLEEP" />
...
</application>
Para leer el sueño, debes solicitar los siguientes permisos:
<application>
<uses-permission
android:name="android.permission.health.READ_SLEEP" />
...
</application>
A continuación, se muestra un ejemplo de cómo solicitar permisos para una sesión de sueño que incluye datos de frecuencia cardíaca, saturación de oxígeno y frecuencia respiratoria:
Después de crear una instancia de cliente, tu app debe solicitarle permisos al usuario. Los usuarios deben poder otorgar o rechazar permisos en cualquier momento.
Para hacerlo, crea un conjunto de permisos para los tipos de datos necesarios. Primero, asegúrate de que los permisos del conjunto se declaren en tu manifiesto de Android.
// Create a set of permissions for required data types
val PERMISSIONS =
setOf(
HealthPermission.getReadPermission(SleepSessionRecord::class),
HealthPermission.getWritePermission(SleepSessionRecord::class),
HealthPermission.getReadPermission(HeartRateRecord::class),
HealthPermission.getWritePermission(HeartRateRecord::class),
HealthPermission.getReadPermission(OxygenSaturationRecord::class),
HealthPermission.getWritePermission(OxygenSaturationRecord::class),
HealthPermission.getReadPermission(RespiratoryRateRecord::class),
HealthPermission.getWritePermission(RespiratoryRateRecord::class)
)
Usa getGrantedPermissions para ver si tu app ya tiene otorgados los permisos necesarios. De lo contrario, usa createRequestPermissionResultContract para solicitarlos. Se mostrará la pantalla de permisos de 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)
}
}
Dado que los usuarios pueden otorgar o revocar permisos en cualquier momento, tu app debe verificar los permisos cada vez antes de usarlos y controlar las situaciones en las que se pierden los permisos.
Implementa una sesión de sueño
En esta sección, se describe el flujo de trabajo recomendado para registrar datos de sueño.
Para alinear tipos de datos como HeartRateRecord o OxygenSaturationRecord con una sesión de sueño, regístralos con marcas de tiempo que se encuentren entre startTime y endTime de la sesión. Health Connect no usa un identificador de sesión para vincular las sesiones de sueño con datos detallados. En cambio, la asociación es implícita a través de intervalos de tiempo superpuestos. Cuando lees datos de sueño, puedes usar el intervalo de tiempo de una sesión para consultar los tipos de datos asociados, como se muestra en Cómo leer datos de sueño.
Cómo escribir una sesión
Si bien los datos detallados, como la frecuencia cardíaca, se pueden registrar durante una sesión de sueño, el SleepSessionRecord en sí solo se debe escribir en Health Connect una vez que finalice la sesión, por ejemplo, cuando el usuario se despierte. El registro debe incluir la sesión startTime, endTime y una lista de objetos SleepSessionRecord.Stage registrados durante la sesión, ya que SleepSessionRecord requiere que endTime se encuentre después de startTime.
Para escribir una sesión de sueño, haz lo siguiente:
- Genera un ID de registro de cliente único.
- Cuando el usuario se despierta o se detiene el monitoreo del sueño, recopila todas las etapas del sueño y construye un objeto
SleepSessionRecord. - Inserta el registro con
insertRecords.
Ejemplo:
val clientRecordId = UUID.randomUUID().toString()
val sessionStartTime = LocalDateTime.of(2023, 10, 30, 22, 0).toInstant(ZoneOffset.UTC)
val sessionEndTime = LocalDateTime.of(2023, 10, 31, 7, 0).toInstant(ZoneOffset.UTC)
val stages = mutableListOf<SleepSessionRecord.Stage>()
// Add recorded stages, for example:
stages.add(SleepSessionRecord.Stage(
startTime = sessionStartTime.plusSeconds(3600),
endTime = sessionStartTime.plusSeconds(7200),
stage = SleepSessionRecord.STAGE_TYPE_LIGHT)
)
stages.add(SleepSessionRecord.Stage(
startTime = sessionStartTime.plusSeconds(7200),
endTime = sessionStartTime.plusSeconds(10800),
stage = SleepSessionRecord.STAGE_TYPE_DEEP)
)
// ... other stages
val session = SleepSessionRecord(
startTime = sessionStartTime,
startZoneOffset = ZoneOffset.UTC,
endTime = sessionEndTime,
endZoneOffset = ZoneOffset.UTC,
stages = stages,
metadata = Metadata(clientRecordId = clientRecordId)
)
healthConnectClient.insertRecords(listOf(session))
Cómo leer datos de sueño
Las apps pueden leer las sesiones de sueño y sus datos asociados para resumir la actividad, proporcionar estadísticas de salud o sincronizar datos con un servidor externo. Por ejemplo, puedes leer un SleepSessionRecord y, luego, consultar el HeartRateRecord que ocurrió durante ese mismo intervalo de tiempo.
Sesión de lectura con datos asociados
Puedes leer las sesiones de sueño con un ReadRecordsRequest que tenga SleepSessionRecord como tipo de registro, filtrado por un intervalo de tiempo. Para leer los datos asociados de una sesión determinada, realiza una segunda solicitud para el tipo de datos seleccionado, como HeartRateRecord, filtrando por el startTime y el endTime de la sesión de sueño.
En el siguiente ejemplo, se muestra cómo leer las sesiones de sueño con datos de frecuencia cardíaca asociados para un período determinado:
suspend fun readSleepSessionsWithAssociatedData(
healthConnectClient: HealthConnectClient,
startTime: Instant,
endTime: Instant
) {
val response = healthConnectClient.readRecords(
ReadRecordsRequest(
recordType = SleepSessionRecord::class,
timeRangeFilter = TimeRangeFilter.between(startTime, endTime)
)
)
for (sleepRecord in response.records) {
// Process each session
val stages = sleepRecord.stages
val notes = sleepRecord.notes
// To read specific granular data (like heart rate) that occurred during
// this session, use the session's startTime and endTime to filter
// the request for that data type.
val hrResponse = healthConnectClient.readRecords(
ReadRecordsRequest(
recordType = HeartRateRecord::class,
timeRangeFilter = TimeRangeFilter.between(
sleepRecord.startTime,
sleepRecord.endTime
)
)
)
for (heartRateRecord in hrResponse.records) {
for (sample in heartRateRecord.samples) {
val bpm = sample.beatsPerMinute
}
}
}
}
Prácticas recomendadas
Sigue estos lineamientos para mejorar la confiabilidad de los datos y la experiencia del usuario:
- Frecuencia de escritura
- Seguimiento activo(en primer plano): Para el seguimiento activo del sueño, escribe los datos a medida que estén disponibles o con un intervalo máximo de 15 minutos.
- Sincronización en segundo plano: Usa
WorkManagerpara escrituras diferidas. Intenta establecer un intervalo de 15 minutos para lograr un equilibrio entre los datos en tiempo real y la eficiencia de la batería. - Procesamiento por lotes: No escribas cada evento del sensor de forma individual. Fragmenta tus solicitudes. Health Connect controla hasta 1,000 registros por solicitud de escritura.
- Mantén los IDs de sesión estables y únicos: Usa identificadores coherentes para tus sesiones. Si se edita o actualiza una sesión, usar el mismo ID evita que se trate como una sesión de sueño nueva y separada.
- Usa el procesamiento por lotes para los tipos de datos: Para reducir la sobrecarga de entrada/salida y preservar la duración de la batería, agrupa tus datos en una sola llamada a
insertRecordsen lugar de escribir cada punto de forma individual. Evita escribir datos duplicados: Usa IDs de cliente Cuando crees registros, establece un
metadata.clientRecordId. Health Connect usa este campo para identificar registros únicos. Si intentas escribir un registro con unclientRecordIdque ya existe, Health Connect ignorará el duplicado o actualizará el registro existente en lugar de crear uno nuevo. Establecer unmetadata.clientRecordIdes la forma más eficaz de evitar duplicados durante los reintentos de sincronización o las reinstalaciones de la app.val record = RespiratoryRateRecord( rate = 16.0, time = time, zoneOffset = ZoneOffset.UTC, metadata = Metadata( // Use a unique ID from your own database clientRecordId = "respiratory_rate_20231030_1" ) )Verifica los datos existentes: Antes de la sincronización, consulta el período para ver si ya existen registros de tu app.
Asegúrate de que las marcas de tiempo no se superpongan: Verifica que una nueva sesión no comience antes de que finalice la anterior. Las sesiones superpuestas pueden causar conflictos en los paneles de actividad física y en los cálculos de resumen.
Proporciona justificaciones claras para los permisos: Usa el flujo de
Permission.createIntentpara explicar por qué tu app necesita acceso a los datos de salud, por ejemplo, "Para analizar tus patrones de sueño".Prueba sesiones de larga duración: Supervisa el consumo de batería durante las sesiones que duran varias horas para verificar que el intervalo de procesamiento por lotes y el uso del sensor no agoten el dispositivo.
Alinea las marcas de tiempo con las tasas de los sensores: Haz coincidir las marcas de tiempo de tus registros con la frecuencia real de tus sensores para mantener la alta fidelidad de los datos.
Prueba
Para verificar la exactitud de los datos y garantizar una experiencia del usuario de alta calidad, sigue estas estrategias de prueba y consulta la documentación oficial sobre cómo probar los principales casos de uso.
Herramientas de verificación
- Health Connect Toolbox: Usa esta app complementaria para inspeccionar registros de forma manual, borrar datos de prueba y simular cambios en la base de datos. Es la mejor manera de verificar que tus registros se almacenen correctamente.
- Pruebas de unidades con
FakeHealthConnectClient: Usa la biblioteca de pruebas para verificar cómo tu app controla los casos extremos, como la revocación de permisos o las excepciones de la API, sin necesidad de un dispositivo físico.
Lista de verificación de calidad
Arquitectura típica
Por lo general, la implementación del monitoreo del sueño incluye lo siguiente:
| Componente | Administra |
|---|---|
| Controlador de sesión | Estado de la sesión Temporizador Lógica de procesamiento por lotes Controladores de tipos de datos Recopilación de datos |
| Capa del repositorio (encapsula las operaciones de Health Connect): | Insertar sesión Insertar tipos de datos Insertar fases de sueño Leer resúmenes de sesiones |
| Capa de la IU (pantallas): | Duración Tipos de datos en vivo Visualización de las fases del sueño |
Solución de problemas
| Síntoma | Causa posible | Resolución |
|---|---|---|
| Faltan tipos de datos (por ejemplo, frecuencia cardíaca) | Faltan permisos de escritura o los filtros de tiempo son incorrectos. | Verifica que hayas solicitado y que el usuario haya otorgado el permiso de tipo de datos específico. Verifica que tu ReadRecordsRequest use un TimeRangeFilter que coincida con la sesión. Consulta Permisos. |
| No se puede escribir en la sesión | Marcas de tiempo superpuestas. | Es posible que Health Connect rechace los registros que se superpongan con los datos existentes de la misma app. Valida que el startTime de una sesión nueva sea posterior al endTime de la anterior. |
| No se registraron datos de sensores durante el sueño | Se cerró o se encuentra inactivo el servicio en primer plano. | Para recopilar datos de sensores durante la noche mientras la pantalla está apagada, puedes usar un servicio en primer plano con foregroundServiceType="health". |
| Aparecen registros duplicados | Falta clientRecordId |
Asigna un clientRecordId único en el Metadata de cada registro. Esto permite que Health Connect realice la eliminación de duplicados si los mismos datos se escriben dos veces durante un reintento de sincronización. Consulta las prácticas recomendadas. |
Pasos comunes de depuración
- Verifica el estado del permiso: Siempre llama a
getPermissionStatus()antes de intentar una operación de lectura o escritura. Los usuarios pueden revocar los permisos en la configuración del sistema en cualquier momento. - Verifica el modo de ejecución: Si tu app no recopila datos en segundo plano, verifica que hayas declarado los permisos correctos en tu
AndroidManifest.xmly que el usuario no haya colocado la app en el modo "Batería restringida".