Ten przewodnik jest zgodny z Health Connect w wersji 1.1.0-alpha11.
Health Connect udostępnia typ danych sesja snu, który służy do przechowywania informacji o śnie użytkownika, np. o sesji nocnej lub drzemce w ciągu dnia.
Do reprezentowania tych sesji służy typ danych SleepSessionRecord.
Sesje umożliwiają użytkownikom mierzenie wydajności w czasie, np. ciągłego tętna lub danych o lokalizacji.
Sesje SleepSessionRecord zawierają dane, które rejestrują fazy snu, takie jak AWAKE (CZUWANIE), SLEEPING (SEN) i DEEP (SEN GŁĘBOKI).
Podtyp to dane, które „należą” do sesji i mają znaczenie tylko wtedy, gdy są odczytywane z sesją nadrzędną. Przykładem jest faza snu.
Powiązane dane to z kolei dane, które są rejestrowane niezależnie, ale mieszczą się w przedziale czasu sesji. Jeśli na przykład użytkownik rejestruje tętno podczas sesji snu, dane o tętnie będą powiązanymi danymi. W przeciwieństwie do danych podtypu, które są częścią rekordu sesji, powiązane dane składają się z niezależnych rekordów, z których każdy ma własny identyfikator UUID.
Sprawdzanie dostępności Health Connect
Zanim spróbujesz użyć Health Connect, Twoja aplikacja powinna sprawdzić, czy Health Connect jest dostępny na urządzeniu użytkownika. Health Connect może nie być wstępnie zainstalowany na wszystkich urządzeniach lub może być wyłączony.
Dostępność możesz sprawdzić za pomocą metody HealthConnectClient.getSdkStatus().
Jak sprawdzić dostępność Health Connect
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 }
W zależności od stanu zwróconego przez getSdkStatus() możesz w razie potrzeby poprosić użytkownika o zainstalowanie lub zaktualizowanie Health Connect ze Sklepu Google Play.
Dostępność funkcji
W przypadku tego typu danych nie ma flagi dostępności funkcji.
Wymagane uprawnienia
Dostęp do sesji snu jest chroniony przez te uprawnienia:
android.permission.health.READ_SLEEPandroid.permission.health.WRITE_SLEEP
Aby dodać do aplikacji możliwość korzystania z sesji snu, zacznij od poproszenia o uprawnienia do typu danych SleepSession.
Aby móc zapisywać sesje snu, musisz zadeklarować to uprawnienie:
<application>
<uses-permission
android:name="android.permission.health.WRITE_SLEEP" />
...
</application>
Aby odczytać sesję snu, musisz poprosić o te uprawnienia:
<application>
<uses-permission
android:name="android.permission.health.READ_SLEEP" />
...
</application>
Prośba o uprawnienia od użytkownika
Po utworzeniu instancji klienta aplikacja musi poprosić użytkownika o uprawnienia. Użytkownicy muszą mieć możliwość przyznawania i odmawiania uprawnień w dowolnym momencie.
Aby to zrobić, utwórz zestaw uprawnień dla wymaganych typów danych. Najpierw upewnij się, że uprawnienia w zestawie są zadeklarowane w pliku manifestu Androida.
// Create a set of permissions for required data types
val PERMISSIONS =
setOf(
HealthPermission.getReadPermission(SleepSessionRecord::class),
HealthPermission.getWritePermission(SleepSessionRecord::class)
)
Użyj getGrantedPermissions, aby sprawdzić, czy Twoja aplikacja ma już
wymagane uprawnienia. Jeśli nie, użyj
createRequestPermissionResultContract, aby poprosić
o te uprawnienia. Spowoduje to wyświetlenie ekranu uprawnień 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)
}
}
Ponieważ użytkownicy mogą przyznawać i cofać uprawnienia w dowolnym momencie, Twoja aplikacja musi sprawdzać uprawnienia za każdym razem przed ich użyciem i obsługiwać sytuacje, w których uprawnienia zostaną utracone.
Obsługiwane agregacje
W przypadku
SleepSessionRecord dostępne są te wartości zagregowane:
Ogólne wskazówki
Oto kilka sprawdzonych metod pracy z sesjami snu w Health Connect.
- Sesje należy wykorzystywać do dodawania danych z konkretnej sesji snu:
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" ), ) ) }
- Dane podtypu muszą być w sesji wyrównane z kolejnymi sygnaturami czasowymi, które się nie nakładają. Dozwolone są jednak luki.
- Dane podtypu nie zawierają identyfikatora UUID, ale powiązane dane mają odrębne identyfikatory UUID.
- Sesje są przydatne, jeśli użytkownik chce, aby dane były powiązane z sesją (i śledzone jako jej część), a nie rejestrowane w sposób ciągły.
Sesje snu
Możesz odczytywać i zapisywać dane o śnie w Health Connect. Dane o śnie są wyświetlane jako sesja i można je podzielić na 8 odrębnych faz snu:
UNKNOWN(NIEZNANE): nieokreślone lub nieznane, czy użytkownik śpi.AWAKE(CZUWANIE): użytkownik jest obudzony w cyklu snu, a nie w ciągu dnia.SLEEPING(SEN): ogólny lub nieprecyzyjny opis snu.OUT_OF_BED(POZA ŁÓŻKIEM): użytkownik wstaje z łóżka w środku sesji snu.AWAKE_IN_BED(CZUWANIE W ŁÓŻKU): użytkownik jest obudzony w łóżku.LIGHT(LEKKI): użytkownik jest w fazie snu płytkiego.DEEP(GŁĘBOKI): użytkownik jest w cyklu snu głębokiego.REM(REM): użytkownik jest w fazie snu REM.
Te wartości reprezentują rodzaj snu, w jakim użytkownik znajduje się w danym przedziale czasu. Zapisywanie faz snu jest opcjonalne, ale zalecane, jeśli są dostępne.
Zapisywanie sesji snu
Typ danych SleepSessionRecord składa się z 2 części:
- Ogólna sesja obejmująca cały czas snu.
- Poszczególne fazy podczas sesji snu, takie jak sen lekki lub głęboki.
Oto jak wstawić sesję snu bez faz:
SleepSessionRecord( title = "weekend sleep", startTime = startTime, endTime = endTime, startZoneOffset = ZoneOffset.UTC, endZoneOffset = ZoneOffset.UTC, )
Oto jak dodać fazy, które obejmują cały okres sesji snu:
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,
)
Odczytywanie sesji snu
W przypadku każdej zwróconej sesji snu należy sprawdzić, czy są też dostępne dane o fazach snu:
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 }
Usuwanie sesji snu
Oto jak usunąć sesję. W tym przykładzie używamy sesji snu:
val timeRangeFilter = TimeRangeFilter.between(sleepRecord.startTime, sleepRecord.endTime) healthConnectClient.deleteRecords(SleepSessionRecord::class, timeRangeFilter)