המדריך הזה תואם לגרסה 1.1.0-alpha12 של Health Connect.
במדריך הזה מוסבר איך לכתוב או לעדכן נתונים ב-Health Connect.
טיפול בערכים אפסיים
יכול להיות שלחלק מסוגי הנתונים, כמו צעדים, מרחק או קלוריות, יהיה ערך של 0.
אפשר לכתוב ערכים של אפס רק אם הם משקפים חוסר פעילות אמיתי בזמן שהמשתמש ענד את המכשיר. לא לכתוב ערכים של אפס אם המכשיר לא היה בשימוש, אם חסרים נתונים או אם הסוללה התרוקנה. במקרים כאלה, כדאי להשמיט את הרשומה כדי למנוע נתונים מטעים.
הגדרת מבנה נתונים
לפני שכותבים נתונים, צריך להגדיר את הרשומות. יש יותר מ-50 סוגי נתונים, ולכל אחד מהם יש מבנה משלו. מידע נוסף על סוגי הנתונים שזמינים מופיע במאמרי העזרה בנושא Jetpack.
רשומות בסיסיות
סוג הנתונים Steps (צעדים) ב-Health Connect מתעד את מספר הצעדים שמשתמש עשה בין קריאות. מספר הצעדים הוא מדד נפוץ בפלטפורמות של בריאות, כושר ואיכות חיים.
בדוגמה הבאה אפשר לראות איך מגדירים נתונים של ספירת צעדים:
val zoneOffset = ZoneOffset.systemDefault().rules.getOffset(startTime) val stepsRecord = StepsRecord( count = 120, startTime = startTime, endTime = endTime, startZoneOffset = zoneOffset, endZoneOffset = zoneOffset, metadata = Metadata.autoRecorded( device = Device(type = Device.TYPE_WATCH) ) ) healthConnectClient.insertRecords(listOf(stepsRecord))
רשומות עם יחידות מידה
ב-Health Connect אפשר לשמור ערכים יחד עם יחידות המידה שלהם כדי לספק דיוק. דוגמה אחת היא סוג הנתונים Nutrition, שהוא נרחב ומקיף. הוא כולל מגוון רחב של שדות אופציונליים של רכיבי תזונה, החל מפחמימות כוללות ועד ויטמינים. כל נקודה על הגרף מייצגת את רכיבי התזונה שאולי נצרכו כחלק מארוחה או מפריט מזון.
בסוג הנתונים הזה, כל רכיבי התזונה מיוצגים ביחידות של מסה, ואילו energy מיוצג ביחידה של אנרגיה.
בדוגמה הבאה מוצג איך להגדיר נתוני תזונה למשתמש שאכל בננה:
val endTime = Instant.now() val startTime = endTime.minus(Duration.ofMinutes(1)) val banana = NutritionRecord( name = "banana", energy = 105.0.kilocalories, dietaryFiber = 3.1.grams, potassium = 0.422.grams, totalCarbohydrate = 27.0.grams, totalFat = 0.4.grams, saturatedFat = 0.1.grams, sodium = 0.001.grams, sugar = 14.0.grams, vitaminB6 = 0.0005.grams, vitaminC = 0.0103.grams, startTime = startTime, endTime = endTime, startZoneOffset = ZoneOffset.UTC, endZoneOffset = ZoneOffset.UTC, metadata = Metadata.activelyRecorded( device = Device(type = Device.TYPE_PHONE) ) )
רשומות עם נתוני סדרות
אפליקציית Health Connect יכולה לאחסן רשימה של נתונים מסדרות. דוגמה אחת היא סוג הנתונים Heart Rate (דופק) שמתעד סדרה של דגימות של פעימות הלב שזוהו בין קריאות.
בסוג הנתונים הזה, הפרמטר samples מיוצג על ידי רשימה של דגימות של דופק. כל דוגמה מכילה ערך beatsPerMinute
וערך time.
בדוגמה הבאה אפשר לראות איך מגדירים נתוני סדרות של קצב הלב:
val endTime = Instant.now() val startTime = endTime.minus(Duration.ofMinutes(5)) val heartRateRecord = HeartRateRecord( startTime = startTime, startZoneOffset = ZoneOffset.UTC, endTime = endTime, endZoneOffset = ZoneOffset.UTC, // records 10 arbitrary data, to replace with actual data samples = List(10) { index -> HeartRateRecord.Sample( time = startTime + Duration.ofSeconds(index.toLong()), beatsPerMinute = 100 + index.toLong(), ) }, metadata = Metadata.activelyRecorded( device = Device(type = Device.TYPE_WATCH) ))
בקשת הרשאות מהמשתמש
אחרי שיוצרים מופע של לקוח, האפליקציה צריכה לבקש הרשאות מהמשתמש. צריך לאפשר למשתמשים להעניק או לדחות הרשאות בכל שלב. כדי לעשות זאת, יוצרים קבוצת הרשאות לסוגי הנתונים הנדרשים. קודם צריך לוודא שההרשאות בקבוצה מוצהרות במניפסט של Android.
val permissions = setOf( HealthPermission.getReadPermission(HeartRateRecord::class), HealthPermission.getWritePermission(HeartRateRecord::class), HealthPermission.getReadPermission(StepsRecord::class), HealthPermission.getWritePermission(StepsRecord::class) )
getGrantedPermissions כדי לבדוק אם האפליקציה כבר קיבלה את ההרשאות הנדרשות. אם לא, משתמשים ב-createRequestPermissionResultContract כדי לבקש את ההרשאות האלה. הפעולה הזו תציג את מסך ההרשאות של 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.") } } }
כתיבת נתונים
אחד מתהליכי העבודה הנפוצים ב-Health Connect הוא כתיבת נתונים. כדי להוסיף רשומות, משתמשים ב-insertRecords.
בדוגמה הבאה אפשר לראות איך כותבים נתונים של מספר הצעדים:
val zoneOffset = ZoneOffset.systemDefault().rules.getOffset(startTime) val stepsRecord = StepsRecord( count = 120, startTime = startTime, endTime = endTime, startZoneOffset = zoneOffset, endZoneOffset = zoneOffset, metadata = Metadata.autoRecorded( device = Device(type = Device.TYPE_WATCH) ) ) healthConnectClient.insertRecords(listOf(stepsRecord))
עדכון נתונים
אם אתם צריכים לשנות רשומה אחת או יותר, במיוחד כשאתם צריכים לסנכרן את מאגר הנתונים של האפליקציה עם נתונים מ-Health Connect, אתם יכולים לעדכן את הנתונים. יש שתי דרכים לעדכן נתונים קיימים, והן תלויות במזהה שמשמש לאיתור רשומות.
מטא-נתונים
כדאי לבדוק קודם את המחלקה Metadata, כי היא נדרשת כשמעדכנים נתונים. בזמן היצירה, לכל Record ב-Health Connect יש שדה metadata. המאפיינים הבאים רלוונטיים לסנכרון:
| מאפיינים | תיאור |
|---|---|
id
|
לכל Record ב-Health Connect יש ערך id ייחודי.Health Connect מאכלס את הערך הזה באופן אוטומטי כשמוסיפים רשומה חדשה. |
lastModifiedTime
|
בכל Record מתבצע גם מעקב אחרי הפעם האחרונה שבה הרשומה שונתה.הנתונים האלה מאוכלסים באופן אוטומטי על ידי Health Connect. |
clientRecordId
|
לכל Record יכול להיות מזהה ייחודי שמשויך אליו, כדי לשמש כהפניה במאגר הנתונים של האפליקציה.
האפליקציה שלך מספקת את הערך הזה. |
clientRecordVersion
|
אם רשומה מכילה clientRecordId, אפשר להשתמש ב-clientRecordVersion כדי שהנתונים יישארו מסונכרנים עם הגרסה במאגר הנתונים של האפליקציה.האפליקציה שלך מספקת את הערך הזה. |
עדכון אחרי קריאה לפי טווח זמן
כדי לעדכן נתונים, קודם צריך להכין את הרשומות הנדרשות. מבצעים שינויים ברשומות לפי הצורך. לאחר מכן, קוראים ל-updateRecords כדי לבצע את השינויים.
בדוגמה הבאה אפשר לראות איך מעדכנים נתונים. לצורך כך, הערכים של כל רשומה של הפרש השעות מהאזור שלה מותאמים ל-PST.
suspend fun updateSteps( healthConnectClient: HealthConnectClient, prevRecordStartTime: Instant, prevRecordEndTime: Instant ) { try { val request = healthConnectClient.readRecords( ReadRecordsRequest( recordType = StepsRecord::class, timeRangeFilter = TimeRangeFilter.between( prevRecordStartTime, prevRecordEndTime ) ) ) val newStepsRecords = arrayListOf<StepsRecord>() for (record in request.records) { // Adjusted both offset values to reflect changes val sr = StepsRecord( count = record.count, startTime = record.startTime, startZoneOffset = record.startTime.atZone(ZoneId.of("PST")).offset, endTime = record.endTime, endZoneOffset = record.endTime.atZone(ZoneId.of("PST")).offset, metadata = record.metadata ) newStepsRecords.add(sr) } healthConnectClient.updateRecords(newStepsRecords) } catch (e: Exception) { // Run error handling here } }
עדכון או הוספה באמצעות מזהה רשומה של לקוח
אם אתם משתמשים בערכים האופציונליים Client Record ID ו-Client Record Version, מומלץ להשתמש ב-insertRecords במקום ב-updateRecords.
הפונקציה insertRecords יכולה לבצע פעולת upsert של נתונים.
אם הנתונים קיימים ב-Health Connect על סמך קבוצת מזהי הרשומות של הלקוח שצוינה, הם יוחלפו. אחרת, הנתונים נכתבים כנתונים חדשים.
התרחיש הזה שימושי בכל פעם שצריך לסנכרן נתונים ממאגר הנתונים של האפליקציה עם Health Connect.
בדוגמה הבאה מוצג איך לבצע פעולת upsert על נתונים שנמשכו ממאגר הנתונים של האפליקציה:
fun pullStepsFromDatastore(startTime: Instant, endTime: Instant) : ArrayList<StepsRecord> { val appStepsRecords = arrayListOf<StepsRecord>() // Pull data from app datastore // ... // Make changes to data if necessary // ... // Store data in appStepsRecords // ... var sr = StepsRecord( metadata = Metadata.activelyRecorded( clientRecordId = "Your client record ID", clientRecordVersion = 0L, device = Device(type = Device.TYPE_WATCH) ), startTime = startTime, startZoneOffset = startTime.atZone(ZoneId.of("PST")).offset, endTime = endTime, endZoneOffset = endTime.atZone(ZoneId.of("PST")).offset, count = 120 ) appStepsRecords.add(sr) // ... return appStepsRecords } suspend fun upsertSteps( healthConnectClient: HealthConnectClient, newStepsRecords: ArrayList<StepsRecord> ) { try { healthConnectClient.insertRecords(newStepsRecords) } catch (e: Exception) { // Run error handling here } }
אחרי זה, תוכלו לקרוא לפונקציות האלה בשרשור הראשי.
upsertSteps(healthConnectClient, pullStepsFromDatastore( startTime = startTime, endTime = endTime ))
בדיקת הערך בגרסה של רשומת הלקוח
אם התהליך שלכם להוספה או לעדכון של נתונים כולל את Client Record Version, Health Connect מבצע בדיקות השוואה בערכים של clientRecordVersion. אם הגרסה מהנתונים שהוסיפו גבוהה מהגרסה מהנתונים הקיימים, מתבצעת פעולת upsert. אחרת, התהליך מתעלם מהשינוי והערך נשאר זהה.
כדי לכלול את ניהול הגרסאות בנתונים, צריך לספק ל-Metadata.clientRecordVersion ערך Long שמבוסס על הלוגיקה של ניהול הגרסאות.
val endTime = Instant.now() val startTime = endTime.minus(Duration.ofMinutes(15)) val stepsRecord = StepsRecord( count = 100L, startTime = startTime, startZoneOffset = ZoneOffset.UTC, endTime = endTime, endZoneOffset = ZoneOffset.UTC, metadata = Metadata.activelyRecorded( clientRecordId = "Your supplied record ID", clientRecordVersion = 0L, // Your supplied record version device = Device(type = Device.TYPE_WATCH) ) )
הפעולה upsert לא מגדילה אוטומטית את הערך של version בכל פעם שיש שינויים, וכך מונעת מקרים לא צפויים של דריסת נתונים. לכן, צריך לספק לו ערך גבוה יותר באופן ידני.
הנחיות כלליות
האפליקציה צריכה לכתוב את כל הנתונים מאינטראקציה ישירה (First-Party) הנתמכים. אופציונלי, אתם יכולים לבחור שהאפליקציה שלכם תכתוב נתונים שהתקבלו ממקורות של צד שלישי. עם זאת, אם האפליקציה קראה נתונים מ-Health Connect, הנתונים האלה לא אמורים להיכתב בחזרה ל-Health Connect.
כשכותבים נתונים שיובאו או נגזרו ממקור אחר, צריך לציין בצורה נכונה את המקור ואת המטא-נתונים של מכשיר המקור. כדי לעשות את זה, צריך לספק את המטא-נתונים הבאים לכל רשומה כתובה:
-
recordingMethod: כשמדובר בנתונים שנרשמו אוטומטית או ידנית, אנחנו מצפים ששיטת הרישום תעודכן כך שתשקף את סוג הפעילות שנרשמה:-
RECORDING_METHOD_AUTOMATICALLY_RECORDED: אם הנתונים נרשמו באופן אוטומטי, למשל אם צמיד כושר זיהה באופן אוטומטי שהמשתמש יצא לריצה. -
RECORDING_METHOD_ACTIVELY_RECORDED: אם המשתמש התחיל פעילות חדשה, כמו רכיבה על אופניים עם מכשיר לביש. -
RECORDING_METHOD_MANUAL_ENTRY: אם המשתמש הזין את הנתונים באופן ידני.
-
-
device.type: צריך לציין סוג מכשיר מתוך אחד מסוגיDeviceהמכשירים הנתמכים. -
device.manufacturer: היצרן של המכשיר, לדוגמה, Fitbit. -
device.model: דגם המכשיר, לדוגמה, Charge 3. -
device.udi: (אופציונלי) החלק של מזהה המכשיר (DI) במזהה המכשיר הייחודי (UDI) של המכשיר הרפואי. פרטים על ההרשאה הנדרשת והנחיות הפרטיות מופיעים במדריך בנושא מטא-נתונים.
הגדרת מטא-נתונים בצורה נכונה היא קריטית לשקיפות הנתונים ועוזרת למשתמשים להבין מאיפה מגיע המידע הרפואי שלהם. פרטים מלאים מופיעים במדריך המטא-נתונים של Health Connect.
אם הנתונים באפליקציה יובאו מאפליקציה אחרת, האחריות לכתיבת הנתונים שלה ב-Health Connect מוטלת על האפליקציה האחרת.
מומלץ גם להטמיע לוגיקה שמטפלת בחריגות של פעולות כתיבה, כמו נתונים שנמצאים מחוץ לגבולות או שגיאה במערכת פנימית. אפשר להחיל את אסטרטגיות ההשהיה והניסיון החוזר על מנגנון לתזמון משימות. אם הכתיבה ל-Health Connect לא מצליחה בסופו של דבר, צריך לוודא שהאפליקציה יכולה להמשיך מעבר לנקודת הייצוא הזו. כדי לאבחן את הבעיה, חשוב לרשום ביומן ולדווח על שגיאות.
כשעוקבים אחרי נתונים, יש כמה הצעות שאפשר לפעול לפיהן, בהתאם לאופן שבו האפליקציה כותבת נתונים.
טיפול באזור זמן
כשכותבים רשומות שמבוססות על זמן, מומלץ להימנע מהגדרת היסטים ל-zoneOffset.UTC
כברירת מחדל, כי זה עלול להוביל לחותמות זמן לא מדויקות כשהמשתמשים נמצאים באזורים אחרים. במקום זאת, צריך לחשב את ההפרש על סמך המיקום בפועל של המכשיר. אפשר לאחזר את אזור הזמן של המכשיר באמצעות ZoneId.systemDefault().
val endTime = Instant.now() val startTime = endTime.minus(Duration.ofDays(1)) val stepsRecords = mutableListOf<StepsRecord>() var sampleTime = startTime val minutesBetweenSamples = 15L while (sampleTime < endTime) { // Get the default ZoneId then convert it to an offset val zoneOffset = ZoneOffset.systemDefault().rules.getOffset(sampleTime) stepsRecords += StepsRecord( startTime = sampleTime.minus(Duration.ofMinutes(minutesBetweenSamples)), startZoneOffset = zoneOffset, endTime = sampleTime, endZoneOffset = zoneOffset, count = Random.nextLong(1, 100), metadata = Metadata.activelyRecorded(device = Device(type = Device.TYPE_WATCH)), ) sampleTime = sampleTime.plus(Duration.ofMinutes(minutesBetweenSamples)) } healthConnectClient.insertRecords( stepsRecords )
פרטים נוספים מופיעים במאמרי העזרה בנושא ZoneId.
כתיבה של נתוני התדירות ורמת הפירוט
כשכותבים נתונים ב-Health Connect, צריך להשתמש ברזולוציה המתאימה. שימוש ברזולוציה המתאימה עוזר להפחית את עומס האחסון, ועדיין לשמור על נתונים עקביים ומדויקים. רזולוציית הנתונים כוללת שני דברים:
- תדירות הכתיבה: באיזו תדירות האפליקציה כותבת נתונים חדשים ב-Health Connect.
- כשיש נתונים חדשים, כדאי לכתוב אותם בתדירות גבוהה ככל האפשר, תוך התחשבות בביצועי המכשיר.
- כדי למנוע פגיעה בחיי הסוללה ובביצועים, מרווח הזמן המקסימלי בין פעולות כתיבה צריך להיות 15 דקות.
- רמת הפירוט של הנתונים שנכתבו: באיזו תדירות נדגמו הנתונים.
- לדוגמה, כתיבה של דגימות של נתוני הדופק כל 5 שניות.
- לא כל סוגי הנתונים דורשים את אותו קצב דגימה. אין הרבה יתרונות בעדכון נתוני מספר הצעדים כל שנייה, לעומת קצב עדכון נמוך יותר, כמו כל 60 שניות.
- שיעורי דגימה גבוהים יותר יכולים לספק למשתמשים תצוגה מפורטת יותר של נתונים של אימוני כושר. תדירויות קצב הדגימה צריכות לאזן בין רמת הפירוט לבין הביצועים.
הנחיות נוספות
כשכותבים נתונים, חשוב להקפיד על ההנחיות הבאות:
- בכל סנכרון, המערכת כותבת רק נתונים חדשים ונתונים מעודכנים שהשתנו מאז הסנכרון האחרון.
- בקשות לחלוקה למקטעים צריכות לכלול לכל היותר 1,000 רשומות לכל בקשת כתיבה.
- הגבלת המשימות כך שיפעלו רק כשהמכשיר לא פעיל ורמת הטעינה של הסוללה לא נמוכה.
- למשימות ברקע, כדאי להשתמש ב-WorkManager כדי לתזמן משימות תקופתיות, עם תקופת זמן מקסימלית של 15 דקות.
הקוד הבא משתמש ב-WorkManager כדי לתזמן משימות תקופתיות ברקע, עם תקופה מקסימלית של 15 דקות ומרווח גמיש של 5 דקות. ההגדרה הזו מוגדרת באמצעות המחלקה PeriodicWorkRequest.Builder.
val constraints = Constraints.Builder()
.requiresBatteryNotLow()
.requiresDeviceIdle(true)
.build()
val writeDataWork = PeriodicWorkRequestBuilder<WriteDataToHealthConnectWorker>(
15,
TimeUnit.MINUTES,
5,
TimeUnit.MINUTES
)
.setConstraints(constraints)
.build()
מעקב פעיל
האיסור כולל אפליקציות שמבצעות מעקב מבוסס-אירועים, כמו פעילות גופנית ושינה, או קלט של משתמשים, כמו תזונה. הרשומות האלה נוצרות כשהאפליקציה פועלת בחזית, או באירועים נדירים שבהם משתמשים באפליקציה כמה פעמים ביום.
מוודאים שהאפליקציה לא מפעילה את Health Connect למשך כל משך האירוע.
הנתונים צריכים להיכתב ב-Health Connect באחת משתי דרכים:
- סנכרון הנתונים עם Health Connect אחרי שהאירוע מסתיים. לדוגמה, סנכרון של נתונים כשמשתמש מסיים סשן של פעילות גופנית במעקב.
- אפשר לתזמן משימה חד-פעמית באמצעות
WorkManagerכדי לסנכרן נתונים במועד מאוחר יותר.
שיטות מומלצות לגרנולריות ולתדירות של פעולות כתיבה
כשכותבים נתונים ב-Health Connect, צריך להשתמש ברזולוציה המתאימה. שימוש ברזולוציה המתאימה עוזר להפחית את עומס האחסון, ועדיין לשמור על נתונים עקביים ומדויקים. המונח 'רזולוציית נתונים' מתייחס לשני דברים:
תדירות הכתיבה: באיזו תדירות האפליקציה דוחפת נתונים חדשים ל-Health Connect. כשיש נתונים חדשים, כדאי לכתוב אותם בתדירות גבוהה ככל האפשר, תוך התחשבות בביצועי המכשיר. כדי למנוע השפעה שלילית על חיי הסוללה ועל היבטים אחרים של הביצועים, מרווח הזמן המקסימלי בין פעולות הכתיבה צריך להיות 15 דקות.
רמת הפירוט של הנתונים שנכתבו: באיזו תדירות נדגמו הנתונים שנדחפו. לדוגמה, כתיבה של דגימות של נתוני הדופק כל 5 שניות. לא כל סוגי הנתונים דורשים את אותו קצב דגימה. אין הרבה יתרונות בעדכון נתוני ספירת הצעדים כל שנייה, לעומת קצב עדכון פחות תדיר, כמו כל 60 שניות. עם זאת, שיעורי דגימה גבוהים יותר עשויים לספק למשתמשים תמונה מפורטת יותר של נתוני הבריאות והכושר שלהם. תדרי קצב הדגימה צריכים להיות מאוזנים בין רמת הפירוט לבין הביצועים.
מבנה רשומות של נתוני סדרות
בסוגי נתונים שמשתמשים בסדרת דוגמאות, כמו HeartRateRecord, חשוב לבנות את הרשומות בצורה נכונה. במקום ליצור רשומה אחת ארוכה שמתעדכנת כל הזמן, כדאי ליצור כמה רשומות קצרות יותר, שכל אחת מהן מייצגת מרווח זמן ספציפי.
לדוגמה, כדי לקבל נתונים של קצב הלב, צריך ליצור HeartRateRecord חדש לכל דקה. כל רשומה תכלול שעת התחלה ושעת סיום שמתפרסות על פני אותה דקה, ותכיל את כל הדגימות של קצב הלב שנאספו במהלך אותה דקה.
במהלך סנכרונים רגילים עם Health Connect (לדוגמה, כל 15 דקות), האפליקציה צריכה לכתוב את כל הרשומות של דקה אחת שנוצרו מאז הסנכרון הקודם. כך אפשר לשמור על גודל סביר של הרשומות ולשפר את הביצועים של שאילתות ועיבוד נתונים.
בדוגמה הבאה אפשר לראות איך יוצרים HeartRateRecord למשך דקה אחת, שמכיל כמה דגימות:
val startTime = Instant.now().truncatedTo(ChronoUnit.MINUTES) val endTime = startTime.plus(Duration.ofMinutes(1)) val heartRateRecord = HeartRateRecord( startTime = startTime, startZoneOffset = ZoneOffset.UTC, endTime = endTime, endZoneOffset = ZoneOffset.UTC, // Create a new record every minute, containing a list of samples. samples = listOf( HeartRateRecord.Sample( time = startTime + Duration.ofSeconds(15), beatsPerMinute = 80, ), HeartRateRecord.Sample( time = startTime + Duration.ofSeconds(30), beatsPerMinute = 82, ), HeartRateRecord.Sample( time = startTime + Duration.ofSeconds(45), beatsPerMinute = 85, ) ), metadata = Metadata.activelyRecorded( device = Device(type = Device.TYPE_WATCH) ))
כתיבת נתונים שנאספים במהלך היום
לגבי נתונים שנאספים באופן שוטף, כמו מספר הצעדים, האפליקציה צריכה לכתוב ל-Health Connect בתדירות הגבוהה ביותר האפשרית כשנתונים חדשים זמינים. כדי למנוע השפעה שלילית על חיי הסוללה ועל היבטים אחרים של הביצועים, מרווח הזמן המקסימלי בין פעולות כתיבה צריך להיות 15 דקות.
סוג הנתונים |
היחידה |
צפוי |
דוגמה |
צעדים |
צעדים |
כל דקה |
23:14 - 23:15 - 5 צעדים 23:16 - 23:17 - 22 צעדים 23:17 - 23:18 - 8 צעדים |
StepsCadence |
צעדים בדקה |
כל דקה |
23:14 - 23:15 - 5 צעדים לדקה 23:16 - 23:17 - 22 צעדים לדקה 23:17 - 23:18 - 8 צעדים לדקה |
דחיפות כיסא גלגלים |
דחיפות |
כל דקה |
23:14 - 23:15 - 5 הודעות פוש 23:16 - 23:17 - 22 הודעות פוש 23:17 עד 23:18 – 8 הודעות פוש |
ActiveCaloriesBurned |
קלוריות |
כל 15 דקות |
23:15 - 23:30 - 2 קלוריות 23:30 - 23:45 - 25 קלוריות 23:45 - 00:00 - 5 קלוריות |
TotalCaloriesBurned |
קלוריות |
כל 15 דקות |
23:15 - 23:30 - 16 קלוריות 23:30 - 23:45 - 16 קלוריות 23:45 - 00:00 - 16 קלוריות |
מרחק |
ק"מ לדקה |
כל דקה |
23:14-23:15 – 0.008 ק"מ 23:16 - 23:16 - 0.021 ק"מ 23:17 - 23:18 - 0.012 ק"מ |
ElevationGained |
m |
כל דקה |
20:36 - 20:37 - 3.048m 20:39 - 20:40 - 3.048m 23:23 - 23:24 - 9.144m |
FloorsClimbed |
קומות |
כל דקה |
23:14 - 23:15 - 5 קומות 23:16 - 23:16 - 22 קומות 23:17 - 23:18 - 8 קומות |
HeartRate |
bpm |
4 פעמים בדקה |
6:11:15 – 55 פעימות לדקה 6:11:30 – 56 פעימות בדקה 6:11:45 - 56 פעימות בדקה 6:12:00 – 55 פעימות לדקה |
HeartRateVariabilityRmssd |
ms |
כל דקה |
6:11am - 23 ms |
RespiratoryRate |
נשימות בדקה |
כל דקה |
23:14 - 23:15 - 60 נשימות בדקה 23:16 - 23:16 - 62 נשימות בדקה 23:17 - 23:18 - 64 נשימות בדקה |
OxygenSaturation |
% |
כל שעה |
6:11 - 95.208% |
הנתונים אמורים להיכתב ב-Health Connect בסוף אימון הכושר או בסוף רשומת השינה. במקרה של מעקב פעיל, כמו פעילות גופנית ושינה, או קלט של משתמשים, כמו תזונה, הרשומות האלה נוצרות כשהאפליקציה פועלת בחזית, או במקרים נדירים שבהם נעשה בה שימוש כמה פעמים ביום.
מוודאים שהאפליקציה לא מפעילה את Health Connect למשך כל משך האירוע.
הנתונים צריכים להיכתב ב-Health Connect באחת משתי דרכים:
- סנכרון הנתונים עם Health Connect אחרי שהאירוע מסתיים. לדוגמה, סנכרון הנתונים כשמשתמש מסיים סשן של פעילות גופנית במעקב.
- אפשר לתזמן משימה חד-פעמית באמצעות WorkManager כדי לסנכרן נתונים מאוחר יותר.
סשנים של פעילות גופנית ושינה
לפחות, האפליקציה צריכה לפעול לפי ההנחיות שבעמודה Expected בטבלה 2. במידת האפשר, פועלים לפי ההנחיות בעמודה הכי טוב.
בטבלה הבאה מוסבר איך לכתוב נתונים במהלך תרגיל:
סוג הנתונים |
היחידה |
צפוי |
המשך יום נעים |
דוגמה |
צעדים |
צעדים |
כל דקה |
כל שנייה |
23:14-23:15 – 5 צעדים 23:16 - 23:17 - 22 צעדים 23:17 - 23:18 - 8 צעדים |
StepsCadence |
צעדים בדקה |
כל דקה |
כל שנייה |
23:14-23:15 – 35 צעדים לדקה 23:16 - 23:17 - 37 צעדים לדקה 23:17 - 23:18 - 40 צעדים לדקה |
דחיפות כיסא גלגלים |
דחיפות |
כל דקה |
כל שנייה |
23:14-23:15 – 5 הודעות פוש 23:16 - 23:17 - 22 הודעות פוש 23:17 עד 23:18 – 8 הודעות פוש |
CyclingPedalingCadence |
RPM |
כל דקה |
כל שנייה |
23:14-23:15 – 65 סל"ד 23:16 - 23:17 - 70 סל"ד 23:17 - 23:18 - 68 סל"ד |
הספק |
ואט |
כל דקה |
כל שנייה |
23:14-23:15 – 250 ואט 23:16 - 23:17 - 255 ואט 23:17 עד 23:18 – 245 ואט |
מהירות |
ק"מ לדקה |
כל דקה |
כל שנייה |
23:14-23:15 - 0.3 km/min 23:16 - 23:17 - 0.4 ק"מ לדקה 23:17 - 23:18 -0.4 km/min |
מרחק |
ק"מ/מ' |
כל דקה |
כל שנייה |
23:14-23:15 – 0.008 ק"מ 23:16 - 23:16 - 0.021 ק"מ 23:17 - 23:18 - 0.012 ק"מ |
ActiveCaloriesBurned |
קלוריות |
כל דקה |
כל שנייה |
23:14-23:15 – 20 קלוריות 23:16 - 23:17 - 20 קלוריות 23:17 - 23:18 - 25 קלוריות |
TotalCaloriesBurned |
קלוריות |
כל דקה |
כל שנייה |
23:14-23:15 – 36 קלוריות 23:16 - 23:17 - 36 קלוריות 23:17 - 23:18 - 41 קלוריות |
ElevationGained |
m |
כל דקה |
כל שנייה |
20:36 - 20:37 - 3.048m 20:39 - 20:40 - 3.048m 23:23 - 23:24 - 9.144m |
ExerciseRoutes |
lat/lng/alt |
כל 3-5 שניות |
כל שנייה |
|
HeartRate |
bpm |
4 פעמים בדקה |
כל שנייה |
23:14-23:15 – 150 פעימות בדקה |
בטבלה 3 מוצגות דוגמאות לכתיבת נתונים במהלך רשומת שינה או אחריו:
סוג הנתונים |
היחידה |
דוגמאות צפויות |
דוגמה |
שלבי שינה |
לאחסן נתונים במחסן ביניים (Stage) |
פרק זמן מפורט לכל שלב שינה |
23:46 עד 23:50 – ערות 23:50 - 23:56 - שינה קלה 23:56 - 00:16 - שינה עמוקה |
RestingHeartRate |
bpm |
ערך יומי יחיד (צפוי בשעות הבוקר המוקדמות) |
6:11 – 60 פעימות לדקה |
OxygenSaturation |
% |
ערך יומי יחיד (צפוי בשעות הבוקר המוקדמות) |
6:11 - 95.208% |
אירועי ספורט רב-ענפיים
הגישה הזו משתמשת בסוגי נתונים ובמבנים קיימים, והיא מאמתת את התאימות להטמעות ולקוראי נתונים נוכחיים של Health Connect. זו גישה נפוצה בפלטפורמות כושר.
בנוסף, סשנים בודדים כמו שחייה, רכיבה על אופניים וריצה לא מקושרים באופן מובנה ב-Health Connect, וקוראי הנתונים צריכים להסיק את הקשר בין הסשנים האלה על סמך הקרבה שלהם בזמן. מעברים בין פלחים, כמו משחייה לרכיבה על אופניים, לא מוצגים באופן מפורש.
בדוגמה הבאה אפשר לראות איך כותבים נתונים של טריאתלון:
val swimStartTime = Instant.parse("2024-08-22T08:00:00Z") val swimEndTime = Instant.parse("2024-08-22T08:30:00Z") val bikeStartTime = Instant.parse("2024-08-22T08:40:00Z") val bikeEndTime = Instant.parse("2024-08-22T09:40:00Z") val runStartTime = Instant.parse("2024-08-22T09:50:00Z") val runEndTime = Instant.parse("2024-08-22T10:20:00Z") val swimSession = ExerciseSessionRecord( startTime = swimStartTime, endTime = swimEndTime, exerciseType = ExerciseSessionRecord.EXERCISE_TYPE_SWIMMING_OPEN_WATER, metadata = Metadata.activelyRecorded( device = Device(type = Device.TYPE_WATCH) ), startZoneOffset = null, endZoneOffset = null, ) val bikeSession = ExerciseSessionRecord( startTime = bikeStartTime, endTime = bikeEndTime, exerciseType = ExerciseSessionRecord.EXERCISE_TYPE_BIKING, metadata = Metadata.activelyRecorded( device = Device(type = Device.TYPE_WATCH) ), startZoneOffset = null, endZoneOffset = null, ) val runSession = ExerciseSessionRecord( startTime = runStartTime, endTime = runEndTime, exerciseType = ExerciseSessionRecord.EXERCISE_TYPE_RUNNING, metadata = Metadata.activelyRecorded( device = Device(type = Device.TYPE_WATCH) ), startZoneOffset = null, endZoneOffset = null, ) healthConnectClient.insertRecords(listOf(swimSession, bikeSession, runSession))
טיפול בחריגים
אפליקציית Health Connect מציגה חריגים סטנדרטיים לפעולות CRUD כשנתקלים בבעיה. האפליקציה צריכה לזהות כל אחד מהחריגים האלה ולטפל בו בצורה המתאימה.
בכל שיטה ב-HealthConnectClient מפורטים החריגים שיכולים להיזרק.
באופן כללי, האפליקציה צריכה לטפל בחריגים הבאים:
| חריג | תיאור | שיטה מומלצת |
|---|---|---|
IllegalStateException
| אחד מהתרחישים הבאים התרחש:
| לפני ששולחים בקשה, כדאי לטפל בבעיות אפשריות בקלט. מומלץ להקצות ערכים למשתנים או להשתמש בהם כפרמטרים בפונקציה מותאמת אישית במקום להשתמש בהם ישירות בבקשות, כדי שתוכלו להחיל אסטרטגיות לטיפול בשגיאות. |
IOException
| יש בעיות שמתרחשות בזמן קריאה וכתיבה של נתונים מהדיסק. | כדי למנוע את הבעיה הזו, אפשר לנסות את הפתרונות הבאים:
|
RemoteException
| אירעו שגיאות בשירות הבסיסי שאליו ה-SDK מתחבר, או בתקשורת איתו. לדוגמה, האפליקציה מנסה למחוק רשומה עם uid מסוים. עם זאת, החריגה מופעלת אחרי שהאפליקציה מגלה, במהלך הצ'ק-אין לשירות הבסיסי, שהרשומה לא קיימת.
| כדי למנוע את הבעיה הזו, אפשר לנסות את הפתרונות הבאים:
|
SecurityException
| נתקלים בבעיות כשהבקשות דורשות הרשאות שלא ניתנו. | כדי למנוע את הבעיה הזו, חשוב לוודא שהצהרתם על השימוש בסוגי הנתונים של Health Connect באפליקציה שפורסמה. בנוסף, עליכם להצהיר על ההרשאות של Health Connect בקובץ המניפסט ובפעילות. |