אם אתם רוצים ליצור באפליקציה שלכם חוויה של מעקב אחר השינה, אתם יכולים להשתמש ב-Health Connect כדי לבצע פעולות כמו:
- כתיבה של נתוני השינה
- כתיבה של נתוני שלב השינה
- כתיבה של נתוני שינה כמו דופק, רמת החמצן בדם וקצב הנשימה
- קריאת נתוני שינה מאפליקציות אחרות
במדריך הזה מוסבר איך ליצור את תכונות השינה האלה, כולל סוגי נתונים, הרשאות, תהליכי עבודה מומלצים ושיטות מומלצות.
סקירה כללית: יצירת כלי מקיף למעקב אחרי השינה
כדי ליצור חוויית מעקב מקיפה אחרי השינה באמצעות Health Connect, פועלים לפי השלבים העיקריים הבאים:
- הטמעה נכונה של הרשאות על סמך ההרשאות לגישה למידע רפואי.
- הקלטת סשנים באמצעות
SleepSessionRecord. - כתיבת סוגי נתונים כמו שלבי שינה, דופק ורמת החמצן בדם באופן עקבי במהלך הסשן.
- ניהול נכון של הרצה ברקע כדי לוודא שמתבצע איסוף רציף של נתונים במהלך הלילה.
- קריאת נתוני סשן לצורך סיכומים וניתוחים של נתוני שינה.
תהליך העבודה הזה מאפשר יכולת פעולה הדדית עם אפליקציות אחרות של Health Connect ומוודא גישה לנתונים בשליטת המשתמש.
לפני שמתחילים
לפני שמטמיעים תכונות שינה:
- משלבים את Health Connect באמצעות התלות המתאימה.
- יוצרים מכונת
HealthConnectClient. - מוודאים שהאפליקציה מטמיעה תהליכי הרשאה בזמן ריצה על סמך Health Permissions.
קונספטים מרכזיים
נתוני השינה ב-Health Connect מיוצגים באמצעות כמה רכיבי ליבה. SleepSessionRecord משמש כרשומה מרכזית של נתוני השינה, ומכיל פרטים כמו שעת ההתחלה או הסיום ושלבי השינה. במהלך סשן, יכולים להירשם סוגים שונים של נתונים, כמו HeartRateRecord או OxygenSaturationRecord.
רשומות שינה
נתוני השינה מיוצגים על ידי SleepSessionRecord. כל רשומה מכילה את הפרטים הבאים:
startTimeendTime-
stages: רשימה שלSleepSessionRecord.Stageכולל שינה עמוקה, שינה קלה, שנת REM וערות. - מטא-נתונים אופציונליים של הסשן (שם, הערות)
אפליקציות יכולות לכתוב כמה סוגי נתונים שמשויכים לסשן.
סוגי הנתונים
סוגי הנתונים הנפוצים שנרשמים במהלך רשומת שינה כוללים:
-
SleepSessionRecord: מתעד את משך השינה ואת השלבים שלה, כולל שינה עמוקה, שינה קלה, שנת REM ושינה עם התעוררויות. -
HeartRateRecord: תיעוד הדופק במהלך השינה. -
OxygenSaturationRecord: תיעוד רמת החמצן בדם (סטורציה) במהלך השינה. -
RespiratoryRateRecord: מתעד את קצב הנשימה במהלך השינה.
כל סוג נתונים נשמר כרשומה נפרדת.
שיקולי פיתוח
אפליקציות למעקב אחרי השינה צריכות לפעול לפרקי זמן ארוכים, ולעתים קרובות ברקע כשהמסך כבוי. כשמפתחים תכונות שקשורות לשינה, חשוב לחשוב איך לנהל את ההרצה ברקע ולבקש את ההרשאות הנדרשות לנתוני השינה.
הרצה ברקע
אפליקציות למעקב אחרי שינה פועלות בדרך כלל בלילה כשהמסך כבוי. במצב הזה, צריך להשתמש ב:
- שירותים שפועלים בחזית לצורך איסוף נתונים
WorkManagerלכתיבה או לסנכרון מאוחרים- שיטות לאיגום נתונים בכתיבה רגילה של רשומות של נתונים גרנולריים, כמו דופק
כדי לשמור על רציפות, חשוב להקפיד שמזהה הסשן יהיה זהה בכל הפעולות.
הרשאות
האפליקציה צריכה לבקש את ההרשאות הרלוונטיות ל-Health Connect לפני שהיא קוראת או כותבת נתוני שינה. רשימה מלאה של סוגי הנתונים זמינה במאמר סוגי הנתונים ב-Health Connect. הרשאות נפוצות לשינה כוללות רשומות שינה ומדדים כמו דופק או רמת החמצן בדם.
הגישה למצב שינה מוגנת על ידי ההרשאות הבאות:
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.
// 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)
)
אפשר להשתמש ב-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)
}
}
המשתמשים יכולים לתת או לבטל הרשאות בכל שלב, ולכן האפליקציה צריכה לבדוק אם ההרשאות ניתנו בכל פעם לפני שהיא משתמשת בהן, ולטפל במקרים שבהם הרשאה כלשהי בוטלה.
הטמעה של רשומת שינה
בקטע הזה מתואר תהליך העבודה המומלץ לתיעוד נתוני שינה.
כדי להתאים סוגי נתונים כמו HeartRateRecord או OxygenSaturationRecord לרשומת שינה, צריך לתעד אותם עם חותמות זמן שחלות בין startTime לבין endTime של הרשומה. אפליקציית Health Connect לא משתמשת במזהה סשן כדי לקשר בין סשנים של שינה לבין נתונים מפורטים. במקום זאת, השיוך הוא מרומז באמצעות חפיפה בין מרווחי זמן. כשקוראים נתוני שינה, אפשר להשתמש בטווח הזמן של סשן כדי לשלוח שאילתה לגבי סוגי נתונים משויכים, כמו שמוצג במאמר קריאת נתוני שינה.
כתיבת נתוני סשן
אפשר לתעד נתונים מפורטים כמו דופק במהלך סשן שינה, אבל את SleepSessionRecord עצמו צריך לכתוב ל-Health Connect רק אחרי שהסשן מסתיים, למשל כשהמשתמש מתעורר. הרשומה צריכה לכלול את הסשן startTime, endTime ורשימה של אובייקטים SleepSessionRecord.Stage שתועדו במהלך הסשן, כי SleepSessionRecord דורש ש-endTime יופיע אחרי startTime.
כדי לכתוב רשומת שינה:
- יוצרים מזהה ייחודי של רשומת לקוח.
- כשהמשתמש מתעורר או כשמעקב אחר השינה מופסק, אוספים את כל שלבי השינה ויוצרים
SleepSessionRecord. - מוסיפים את ההקלטה באמצעות
insertRecords.
דוגמה:
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))
קריאת נתוני השינה
אפליקציות יכולות לקרוא את נתוני סשני השינה ואת הנתונים שמשויכים אליהם כדי לסכם את הפעילות, לספק תובנות לגבי הבריאות או לסנכרן את הנתונים עם שרת חיצוני. לדוגמה, אפשר לקרוא SleepSessionRecord ואז לשלוח שאילתה לגבי HeartRateRecord שהתרחש במהלך אותו מרווח זמן.
סשן קריאה עם נתונים משויכים
אפשר לקרוא סשנים של שינה באמצעות ReadRecordsRequest עם SleepSessionRecord כסוג הרשומה, מסונן לפי טווח זמן. כדי לקרוא נתונים משויכים של רשומת שינה נתונה, שולחים בקשה שנייה לסוג הנתונים שנבחר, למשל HeartRateRecord – סינון לפי startTime ו-endTime של רשומת השינה.
בדוגמה הבאה מוצגות דרכים לקריאת רשומות שינה עם נתוני דופק משויכים לטווח תאריכים נתון:
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
}
}
}
}
שיטות מומלצות
כדי לשפר את מהימנות הנתונים ואת חוויית המשתמש, כדאי לפעול בהתאם להנחיות הבאות:
- תדירות הכתיבה
- מעקב פעיל(חזיתי): כדי לעקוב אחרי השינה באופן פעיל, צריך לכתוב את הנתונים כשהם זמינים או במרווחים של 15 דקות לכל היותר.
- סנכרון ברקע: משתמשים ב-
WorkManagerלכתיבה מושהית. כדי לאזן בין נתונים בזמן אמת לבין יעילות הסוללה, מומלץ להגדיר מרווח של 15 דקות. - עיבוד באצווה: אל תכתבו כל אירוע של חיישן בנפרד. מפצלים את הבקשות. Health Connect יכול לטפל בעד 1,000 רשומות לכל בקשת כתיבה.
- שמירה על יציבות וייחודיות של מזהי הסשנים: צריך להשתמש במזהים עקביים לסשנים. אם עורכים או מעדכנים רשומת שינה, שימוש באותו מזהה מונע את ההתייחסות אליה כאל רשומת שינה חדשה ונפרדת.
- שימוש באצווה לסוגי נתונים: כדי לצמצם את התקורה של קלט/פלט ולשמור על חיי הסוללה, כדאי לקבץ את נקודות הנתונים לקריאה יחידה של
insertRecordsבמקום לכתוב כל נקודה בנפרד. הימנעות מכתיבת נתונים כפולים: שימוש במזהי לקוח כשיוצרים רשומות, צריך להגדיר
metadata.clientRecordId. הוא משמש את Health Connect לזיהוי רשומות ייחודיות. אם תנסו לכתוב רשומה עםclientRecordIdשכבר קיים, מערכת Health Connect תתעלם מהכפילות או תעדכן את הרשומה הקיימת במקום ליצור רשומה חדשה. ההגדרה שלmetadata.clientRecordIdהיא הדרך היעילה ביותר למנוע כפילויות במהלך ניסיונות חוזרים של סנכרון או התקנה מחדש של האפליקציה.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" ) )בדיקת נתונים קיימים: לפני שמסנכרנים, שולחים שאילתה לטווח הזמן כדי לראות אם כבר קיימים רשומות מהאפליקציה.
מוודאים שחותמות הזמן לא חופפות: צריך לוודא שסשן חדש לא מתחיל לפני שהסשן הקודם מסתיים. סשנים חופפים עלולים לגרום לקונפליקטים בלוחות הבקרה של הכושר ובחישובים של הסיכומים.
צריך לספק הסברים ברורים למה נדרשת הרשאה: בתהליך
Permission.createIntentצריך להסביר למה האפליקציה צריכה גישה לנתונים בריאותיים, למשל: "כדי לנתח את דפוסי השינה שלך".בדיקת סשנים ארוכים: מעקב אחרי צריכת הסוללה במהלך סשנים שנמשכים כמה שעות כדי לוודא שמרווח האצווה והשימוש בחיישן לא מרוקנים את המכשיר.
התאמת חותמות הזמן לקצב החיישנים: כדי לשמור על רמת דיוק גבוהה של הנתונים, צריך להתאים את חותמות הזמן של הרשומה לתדירות בפועל של החיישנים.
בדיקה
כדי לוודא שהנתונים נכונים ושהמשתמשים נהנים מחוויה איכותית, כדאי לפעול לפי אסטרטגיות הבדיקה האלה ולעיין במסמכי התיעוד הרשמיים בנושא בדיקת תרחישי שימוש מרכזיים.
כלי אימות
- ארגז הכלים של Health Connect: אפשר להשתמש באפליקציה הנלווית הזו כדי לבדוק רשומות באופן ידני, למחוק נתוני בדיקה ולדמות שינויים במסד הנתונים. זו הדרך הכי טובה לוודא שהרשומות שלכם מאוחסנות בצורה נכונה.
- בדיקות יחידה באמצעות
FakeHealthConnectClient: אפשר להשתמש בספריית הבדיקות כדי לבדוק איך האפליקציה מטפלת במקרים קיצוניים, כמו ביטול הרשאה או חריגות ב-API, בלי צורך במכשיר פיזי.
רשימת משימות לבדיקת איכות
ארכיטקטורה אופיינית
הטמעה של מעקב אחר השינה כוללת בדרך כלל:
| רכיב | מנהל/ת |
|---|---|
| בקר סשנים | מצב הסשן טיימר לוגיקה של עיבוד באצווה בקרי סוגי נתונים איסוף נתונים |
| שכבת מאגר (עוטפת פעולות של Health Connect): | הוספת סשן הוספת סוגי נתונים הוספת שלבי שינה קריאת סיכומי סשנים |
| שכבת ממשק המשתמש (מסכים): | משך זמן סוגי נתונים בזמן אמת תרשים להמחשת שלבי השינה |
פתרון בעיות
| תיאור הבעיה | סיבה אפשרית | רזולוציה |
|---|---|---|
| חסרים סוגי נתונים (לדוגמה, דופק) | הרשאות הכתיבה חסרות או שהמסננים של הזמן שגויים. | בודקים שביקשתם מהמשתמש הרשאה לסוג הנתונים הספציפי והמשתמש אישר את הבקשה. צריך לוודא שReadRecordsRequest משתמש בTimeRangeFilter שתואם לסשן. מידע נוסף על הרשאות |
| הכתיבה של הסשן נכשלת | חותמות זמן חופפות. | יכול להיות שאפליקציית Health Connect תדחה רשומות שחופפות לנתונים קיימים מאותה אפליקציה. צריך לוודא שstartTime של סשן חדש מופיע אחרי endTime של הסשן הקודם. |
| לא מתועדים נתוני חיישנים במהלך השינה | השירות שפועל בחזית הופסק או לא פעיל. | כדי לאסוף נתוני חיישנים במהלך הלילה כשהמסך כבוי, אפשר להשתמש בשירות שפועל בחזית עם foregroundServiceType="health". |
| מופיעות רשומות כפולות | חסר: clientRecordId |
להקצות clientRecordId ייחודי בMetadata של כל רשומה. כך, אם אותם נתונים נכתבים פעמיים במהלך ניסיון חוזר של סנכרון, אפליקציית Health Connect יכולה לבצע הסרת כפילויות. שיטות מומלצות |
שלבים נפוצים לניפוי באגים
- בדיקת מצב ההרשאה: תמיד צריך להתקשר אל
getPermissionStatus()לפני שמנסים לבצע פעולת קריאה או כתיבה. המשתמשים יכולים לבטל את ההרשאות בהגדרות המערכת בכל שלב. - אימות מצב ההפעלה: אם האפליקציה לא אוספת נתונים ברקע, צריך לוודא שהצהרתם על ההרשאות הנכונות ב-
AndroidManifest.xmlושהמשתמש לא העביר את האפליקציה למצב 'הגבלת השימוש בסוללה'.