מעקב אחר נתוני שינה

המדריך הזה תואם לגרסה 1.1.0-alpha11 של Health Connect.

אפליקציית Health Connect מספקת סוג נתונים של סשן שינה, כדי לאחסן מידע על השינה של המשתמש, כמו סשן לילי או תנומה במהלך היום. סוג הנתונים SleepSessionRecord משמש לייצוג של הסשנים האלה.

הסשנים מאפשרים למשתמשים למדוד את הביצועים לפי זמן לאורך תקופה מסוימת, כמו נתוני מיקום או דופק רציף.

סשנים של SleepSessionRecord מכילים נתונים שמתעדים את שלבי השינה, כמו AWAKE, SLEEPING ו-DEEP.

נתוני סוג משנה הם נתונים ש"שייכים" לסשן, והם משמעותיים רק כשקוראים אותם עם סשן אב. לדוגמה, שלב השינה.

בדיקת הזמינות של Health Connect

לפני שמנסים להשתמש ב-Health Connect, האפליקציה צריכה לוודא ש-Health Connect זמין במכשיר של המשתמש. יכול להיות שאפליקציית Health Connect לא מותקנת מראש בכל המכשירים או שהיא מושבתת. אפשר לבדוק את הזמינות באמצעות השיטה HealthConnectClient.getSdkStatus().

איך בודקים אם 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
}

בהתאם לסטטוס שמוחזר על ידי getSdkStatus(), תוכלו להנחות את המשתמש להתקין או לעדכן את Health Connect מחנות Google Play, אם יש צורך בכך.

זמינות התכונה

אין דגל זמינות תכונות לסוג הנתונים הזה.

הרשאות נדרשות

הגישה להפעלת מעקב השינה מוגנת על ידי ההרשאות הבאות:

  • android.permission.health.READ_SLEEP
  • android.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.

// Create a set of permissions for required data types
val PERMISSIONS =
    setOf(
  HealthPermission.getReadPermission(SleepSessionRecord::class),
  HealthPermission.getWritePermission(SleepSessionRecord::class)
)

אפשר להשתמש ב-getGrantedPermissions כדי לבדוק אם האפליקציה כבר קיבלה את ההרשאות הנדרשות. אם לא, צריך להשתמש ב-createRequestPermissionResultContract כדי לבקש את ההרשאות האלה. מוצג מסך ההרשאות של 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)
  }
}

המשתמשים יכולים לתת או לבטל הרשאות בכל שלב, ולכן האפליקציה צריכה לבדוק מעת לעת אם ההרשאות ניתנו, ולטפל בתרחישים שבהם ההרשאה בוטלה.

צבירות נתמכות

הערכים המצטברים הבאים זמינים עבור 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"
            ),
        )
    )
}
  • אין להשתמש בסשנים למדידות כלליות, כמו מספר הצעדים היומי.
  • נתוני סוג המשנה לא מכילים מזהה ייחודי, אבל לנתונים המשויכים יש מזהים ייחודיים שונים.
  • הנתונים של סוג המשנה צריכים להיות מיושרים בסשן עם חותמות זמן עוקבות שלא חופפות. אפשר להשתמש ברווחים.
  • הסשנים שימושיים אם המשתמש רוצה שהנתונים ישויכו לסשן (ויתועדו כחלק ממנו), ולא יתועדו באופן רציף.

רשומות שינה

אתם יכולים לקרוא או לכתוב נתוני שינה ב-Health Connect. נתוני השינה מוצגים כסשן, ואפשר לחלק אותם ל-8 שלבי שינה שונים:

  • UNKNOWN: לא צוין או לא ידוע אם המשתמש ישן.
  • AWAKE: המשתמש ער במהלך מחזור שינה, ולא במהלך היום.
  • SLEEPING: תיאור שינה גנרי או לא מפורט.
  • OUT_OF_BED: המשתמש קם מהמיטה באמצע סשן שינה.
  • AWAKE_IN_BED: המשתמש ער במיטה.
  • LIGHT: המשתמש נמצא במחזור שינה קל.
  • DEEP: המשתמש נמצא במצב שינה עמוקה.
  • REM: המשתמש נמצא במחזור שינה של REM.

הערכים האלה מייצגים את סוג השינה שהמשתמש חווה בטווח זמן מסוים. הוספת נתוני שלבי השינה היא אופציונלית, אבל מומלצת אם היא זמינה.

כתיבת נתוני השינה

סוג הנתונים SleepSessionRecord כולל שני חלקים:

  1. הסשן הכולל, שנמשך לאורך כל משך השינה.
  2. שלבים בודדים במהלך סשן השינה, כמו שינה קלה או שינה עמוקה.

כך מוסיפים סשן שינה בלי שלבים:

SleepSessionRecord(
      title = "weekend sleep",
      startTime = startTime,
      endTime = endTime,
      startZoneOffset = ZoneOffset.UTC,
      endZoneOffset = ZoneOffset.UTC,
)

כך מוסיפים שלבים שמכסים את כל התקופה של סשן שינה:

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

קריאת נתוני השינה

לכל סשן שינה שמוחזר, צריך לבדוק אם יש גם נתונים של שלבי שינה:

suspend fun readSleepSessions(
    healthConnectClient: HealthConnectClient,
    startTime: Instant,
    endTime: Instant
) {
    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
    }
}

מחיקת סשן שינה

כך מוחקים סשן. בדוגמה הזו השתמשנו בסשן שינה:

suspend fun deleteSleepSession(
    healthConnectClient: HealthConnectClient,
    sleepRecord: SleepSessionRecord,
) {
    val timeRangeFilter = TimeRangeFilter.between(sleepRecord.startTime, sleepRecord.endTime)
    healthConnectClient.deleteRecords(SleepSessionRecord::class, timeRangeFilter)
}