המדריך הזה תואם לגרסה 1.1.0-alpha12 של Health Connect ואילך.
המדריך הזה עוסק בתהליך של כתיבה או עדכון של נתונים ב-Health Connect.
טיפול בערכי אפס
יכול להיות שסוגי נתונים מסוימים, כמו צעדים, מרחק או קלוריות, יקבלו את הערך 0.
צריך לכתוב ערכי אפס רק כשהם משקפים חוסר פעילות אמיתי בזמן שהמשתמש ענד את המכשיר. אל תכתבו ערכי אפס אם המשתמש לא ענד את המכשיר, אם חסרים נתונים או אם הסוללה התרוקנה. במקרים כאלה, צריך להשמיט את הרשומה כדי למנוע נתונים מטעים.
הגדרת מבנה הנתונים
לפני שכותבים נתונים, צריך להגדיר את הרשומות. יש יותר מ-50 סוגי נתונים, ולכל אחד מהם יש מבנה משלו. בחומר העזר של Jetpack מפורטים סוגי הנתונים הזמינים.
רשומות בסיסיות
סוג הנתונים צעדים ב-Health Connect מתעד את מספר הצעדים שהמשתמש ביצע בין קריאות. ספירת הצעדים היא מדד נפוץ בפלטפורמות של בריאות, כושר ו-wellness.
בדוגמה הבאה אפשר לראות איך מגדירים נתונים של ספירת צעדים:
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 יכול לאחסן ערכים יחד עם יחידות המידה שלהם. דוגמה אחת היא סוג הנתונים תזונה, שהוא נרחב ומקיף. הוא כולל מגוון רחב של שדות אופציונליים של רכיבים תזונתיים, החל מסך הפחמימות ועד לוויטמינים. כל נקודה על הגרף מייצגת את החומרים המזינים שייתכן שנצרכו כחלק מארוחה או מפריט מזון.
בסוג הנתונים הזה, כל החומרים המזינים מיוצגים ביחידות של מסה, ו-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 יכולה לאחסן רשימה של נתונים בסדרות. דוגמה אחת היא סוג הנתונים דופק, שמתעד סדרה של דגימות דופק שזוהו בין קריאות.
בסוג הנתונים הזה, הפרמטר 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 } }
עדכון או הוספה (upsert) באמצעות מזהה רשומת הלקוח
אם אתם משתמשים בערכים האופציונליים "מזהה רשומת לקוח" ו"גרסת רשומת לקוח", מומלץ להשתמש ב-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 } }
לאחר מכן, אפשר לקרוא לפונקציות האלה ב-main thread.
upsertSteps(healthConnectClient, pullStepsFromDatastore( startTime = startTime, endTime = endTime ))
בדיקת ערך בגרסת רשומת הלקוח
אם תהליך העדכון או ההוספה של הנתונים כולל את גרסת רשומת הלקוח, פלטפורמת Health Connect מבצעת בדיקות השוואה בערכי clientRecordVersion. אם מספר הגרסה של הנתונים שנוספו גבוה יותר ממספר הגרסה של הנתונים הקיימים, מתבצעת פעולת העדכון או ההוספה. אחרת, התהליך מתעלם מהשינוי והערך נשאר ללא שינוי.
כדי לכלול ניהול גרסאות בנתונים, צריך לספק ל-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) ) )
פעולות של עדכון או הוספה לא מגדילות באופן אוטומטי את הערך של version בכל פעם שיש שינויים, כדי למנוע מקרים בלתי צפויים של החלפת נתונים. לכן, צריך להזין ערך גבוה יותר באופן ידני.
הנחיות כלליות
האפליקציה צריכה לכתוב את כל הנתונים הנתמכים מאינטראקציה ישירה. אתם יכולים גם לבחור שהאפליקציה תכתוב נתונים שהתקבלו ממקורות של צד שלישי. עם זאת, אם האפליקציה קראה נתונים מ-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,048 מטרים 20:39 עד 20:40 – 3.048 מטרים 23:23 - 23:24 - 9,144 מ' |
FloorsClimbed |
קומות |
כל דקה |
23:14 עד 23:15 – 5 קומות 23:16 - 23:16 - 22 קומות 23:17 עד 23:18 – 8 קומות |
HeartRate |
bpm |
4 פעמים בדקה |
06:11:15 – 55 פעימות לדקה 06:11:30 – 56 פעימות לדקה 06:11:45 – 56 פעימות לדקה 06:12:00 – 55 פעימות לדקה |
HeartRateVariabilityRmssd |
ms |
כל דקה |
06:11 – 23 אלפיות השנייה |
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 |
סיבובים לדקה |
כל דקה |
כל שנייה |
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 ק"מ/דקה 23:16 עד 23:17 – 0.4 ק"מ לדקה 23:17 עד 23:18, 0.4- ק"מ/דקה |
מרחק |
ק"מ/מטר |
כל דקה |
כל שנייה |
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,048 מטרים 20:39 עד 20:40 – 3.048 מטרים 23:23 - 23:24 - 9,144 מ' |
ExerciseRoutes |
קו רוחב/קו אורך/גובה |
כל 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 |
ערך יומי יחיד (צפוי דבר ראשון בבוקר) |
06: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 בקובץ המניפסט ובפעילות שלכם. |