Melacak sesi tidur

Panduan ini kompatibel dengan Health Connect versi 1.1.0-alpha12 atau yang lebih baru.

Health Connect menyediakan jenis data sesi tidur, untuk menyimpan informasi tentang tidur pengguna, seperti sesi tidur malam atau tidur siang. Jenis data SleepSessionRecord digunakan untuk merepresentasikan sesi ini.

Sesi memungkinkan pengguna mengukur performa berdasarkan waktu selama jangka waktu tertentu, seperti detak jantung berkelanjutan atau data lokasi.

Sesi SleepSessionRecord berisi data yang mencatat tahapan tidur, seperti AWAKE, SLEEPING, dan DEEP.

Data subjenis adalah data yang "termasuk" dalam sesi dan hanya bermanfaat jika dibaca dengan sesi induk. Misalnya, fase tidur.

Di sisi lain, Data terkait mengacu pada data yang dicatat secara independen, tetapi termasuk dalam rentang waktu sesi. Misalnya, jika pengguna mencatat Detak Jantung selama sesi tidur, data Detak Jantung akan menjadi data terkait. Tidak seperti data subjenis yang merupakan bagian dari data sesi, data terkait terdiri dari data independen, masing-masing dengan UUID-nya sendiri.

Memeriksa ketersediaan Health Connect

Sebelum mencoba menggunakan Health Connect, aplikasi Anda harus memverifikasi bahwa Health Connect tersedia di perangkat pengguna. Health Connect mungkin tidak diinstal di semua perangkat atau mungkin dinonaktifkan. Anda dapat memeriksa ketersediaan menggunakan metode HealthConnectClient.getSdkStatus().

Cara memeriksa ketersediaan Health Connect

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
}

Bergantung pada status yang ditampilkan oleh getSdkStatus(), Anda dapat memandu pengguna untuk menginstal atau mengupdate Health Connect dari Google Play Store jika perlu.

Ketersediaan fitur

Tidak ada tanda ketersediaan fitur untuk jenis data ini.

Izin yang diperlukan

Akses ke sesi tidur dilindungi oleh izin berikut:

  • android.permission.health.READ_SLEEP
  • android.permission.health.WRITE_SLEEP

Untuk menambahkan kemampuan sesi tidur ke aplikasi Anda, mulailah dengan meminta izin untuk jenis data SleepSession.

Berikut adalah izin yang harus Anda deklarasikan agar dapat menulis sesi tidur:

<application>
  <uses-permission
android:name="android.permission.health.WRITE_SLEEP" />
...
</application>

Untuk membaca sesi tidur, Anda perlu meminta izin berikut:

<application>
  <uses-permission
android:name="android.permission.health.READ_SLEEP" />
...
</application>

Meminta izin dari pengguna

Setelah membuat instance klien, aplikasi Anda perlu meminta izin dari pengguna. Pengguna harus diizinkan untuk memberikan atau menolak izin kapan saja. Untuk melakukannya, buat kumpulan izin untuk jenis data yang diperlukan. Pastikan izin dalam kumpulan dideklarasikan dalam manifes Android Anda terlebih dahulu.

val permissions =
    setOf(
        HealthPermission.getReadPermission(SleepSessionRecord::class),
        HealthPermission.getWritePermission(SleepSessionRecord::class)
    )
Gunakan getGrantedPermissions untuk mengetahui apakah aplikasi Anda sudah mendapatkan izin yang diperlukan. Jika belum, gunakan createRequestPermissionResultContract untuk meminta izin tersebut. Tindakan ini akan menampilkan layar izin Health Connect.
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.") }
    }
}
Karena pengguna dapat memberikan atau mencabut izin kapan saja, aplikasi Anda harus memeriksa izin setiap kali sebelum menggunakannya dan menangani skenario saat izin hilang.

Agregasi yang didukung

Nilai gabungan berikut tersedia untuk SleepSessionRecord:

Panduan umum

Berikut adalah beberapa panduan praktik terbaik tentang cara menggunakan sesi tidur di Health Connect.

  • Sesi harus digunakan untuk menambahkan data dari sesi tidur tertentu, untuk tidur:

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))
            ),
        )
    )
}

  • Data subjenis harus disejajarkan dalam sesi dengan stempel waktu berurutan yang tidak tumpang-tindih. Namun, celah diizinkan.
  • Data subjenis tidak berisi UUID, tetapi data terkait memiliki UUID yang berbeda.
  • Sesi akan berguna jika pengguna menginginkan data dikaitkan dengan (dan dilacak sebagai bagian dari) sesi, bukan dicatat secara terus-menerus.

Sesi tidur

Anda dapat membaca atau menulis data tidur di Health Connect. Data tidur ditampilkan sebagai sesi, dan dapat dibagi menjadi 8 tahapan tidur yang berbeda:

  • UNKNOWN: Tidak ditentukan atau tidak diketahui apakah pengguna sedang tidur.
  • AWAKE: Pengguna terbangun dalam siklus tidur, bukan pada siang hari.
  • SLEEPING: Deskripsi tidur umum atau tidak terperinci.
  • OUT_OF_BED: Pengguna beranjak dari tempat tidur di tengah sesi tidur.
  • AWAKE_IN_BED: Pengguna terbangun di tempat tidur.
  • LIGHT: Pengguna dalam siklus tidur ringan.
  • DEEP: Pengguna berada dalam siklus tidur nyenyak.
  • REM: Pengguna berada dalam siklus tidur REM.

Nilai ini mewakili jenis tidur yang dialami pengguna dalam rentang waktu. Menulis tahapan tidur bersifat opsional, tetapi sebaiknya dilakukan jika tersedia.

Menulis sesi tidur

Jenis data SleepSessionRecord memiliki dua bagian:

  1. Sesi keseluruhan yang mencakup seluruh durasi tidur.
  2. Masing-masing tahapan selama sesi tidur seperti tidur ringan atau tidur nyenyak.

Berikut ini cara menyisipkan sesi tidur tanpa tahapan:

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))
)

Berikut ini cara menambahkan tahapan yang mencakup seluruh periode sesi tidur:

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,
)

Membaca sesi tidur

Untuk setiap sesi tidur yang ditampilkan, Anda harus memeriksa apakah data tahapan tidur juga ada:

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
}

Menghapus sesi tidur

Berikut ini cara menghapus sesi. Untuk contoh ini, kita telah menggunakan sesi tidur:

val timeRangeFilter = TimeRangeFilter.between(sleepRecord.startTime, sleepRecord.endTime)
healthConnectClient.deleteRecords(SleepSessionRecord::class, timeRangeFilter)