בדוגמה הבאה אפשר לראות איך קוראים נתונים גולמיים כחלק מתהליך העבודה הנפוץ.
קריאת נתונים
Health Connect מאפשר לאפליקציות לקרוא נתונים ממאגר הנתונים כשהאפליקציה פועלת בחזית וברקע:
קריאות של נתונים כשהאפליקציה פועלת בחזית: בדרך כלל אפשר לקרוא נתונים מ-Health Connect כשהאפליקציה פועלת בחזית. במקרים כאלה, כדאי להשתמש בשירות שפועל בחזית כדי להריץ את הפעולה הזו, למקרה שהמשתמש או המערכת ימקמו את האפליקציה ברקע במהלך פעולת קריאה.
קריאות ברקע: אם תבקשו מהמשתמש הרשאה נוספת, תוכלו לקרוא נתונים אחרי שהמשתמש או המערכת יעבירו את האפליקציה שלכם לרקע. דוגמה מלאה לקריאה ברקע
סוג הנתונים 'צעדים' ב-Health Connect מתעד את מספר הצעדים שהמשתמש עשה בין הקריאות. מספר הצעדים הוא מדד נפוץ בפלטפורמות של בריאות, כושר ורווחה. אפליקציית Health Connect מאפשרת לקרוא ולכתוב נתונים של מספר הצעדים.
כדי לקרוא רשומות, צריך ליצור ReadRecordsRequest ולספק אותו כשמתקשרים אל readRecords.
בדוגמה הבאה אפשר לראות איך קוראים נתונים של מספר צעדים של משתמש בפרק זמן מסוים. דוגמה מורחבת עם SensorManager מופיעה במדריך בנושא נתונים של ספירת צעדים.
val response = healthConnectClient.readRecords( ReadRecordsRequest( HeartRateRecord::class, timeRangeFilter = TimeRangeFilter.between(startTime, endTime) ) ) response.records.forEach { record -> /* Process records */ }
אפשר גם לקרוא את הנתונים בצורה מצטברת באמצעות aggregate.
suspend fun readStepsAggregate(startTime: Instant, endTime: Instant): Long { val response = healthConnectClient.aggregate( AggregateRequest( metrics = setOf(StepsRecord.COUNT_TOTAL), timeRangeFilter = TimeRangeFilter.between(startTime, endTime) ) ) return response[StepsRecord.COUNT_TOTAL] ?: 0L }
קריאה של נתוני הצעדים בנייד
ב-Android 14 (רמת API 34) ובגרסה 20 ומעלה של SDK Extension, Health Connect מספק ספירת צעדים במכשיר. אם אפליקציה כלשהי קיבלה את ההרשאה READ_STEPS, Health Connect מתחיל לתעד את הצעדים מהמכשיר עם Android, והמשתמשים רואים את נתוני הצעדים שנוספו אוטומטית לרשומות צעדים ב-Health Connect.
כדי לבדוק אם יש במכשיר אפשרות לספירת צעדים, צריך לוודא שפועלת בו מערכת Android 14 (רמת API 34) ושיש בו לפחות SDK extension גרסה 20:
val isStepTrackingAvailable =
Build.VERSION.SDK_INT >= Build.VERSION_CODES.UPSIDE_DOWN_CAKE &&
SdkExtensions.getExtensionVersion(Build.VERSION_CODES.UPSIDE_DOWN_CAKE) >= 20
אם האפליקציה קוראת את מספר הצעדים המצטבר באמצעות aggregate ולא מסננת לפי DataOrigin, מספר הצעדים במכשיר נכלל אוטומטית בסך הכול, ולא נדרשים שינויים לעדכון מיוני 2026.
שינוי השיוך (Attribution) של שלבים במכשיר
החל מהעדכון של יוני 2026, הצעדים שמערכת Health Connect עוקבת אחריהם באופן מקורי משויכים לשם חבילה סינתטי (SPN), כמו com.android.healthconnect.phone.jd5bdd37e1a8d3667a05d0abebfc4a89e.
בעבר, שלבים מובנים שויכו לשם החבילה android.
נתונים היסטוריים של שלבים שנרשמו לפני יוני 2026 ישמרו את android שם החבילה.
מספרי ה-SPN הם ספציפיים למכשיר ומוגבלים לכל אפליקציה כדי להגן על פרטיות המשתמשים:
- יציב: ה-SPN של המכשיר הנוכחי יציב עבור האפליקציה שלכם.
- ברמת האפליקציה: אפליקציות שונות באותו מכשיר רואות מספרי SPN שונים עבור נתוני השלבים במכשיר.
שאילתה לגבי שלבים במכשיר
מכיוון ש-SPN הם ספציפיים למכשיר ומוגבלים להיקף מסוים, אסור להגדיר ערכי SPN בהגדרות קשיחות. במקום זאת, משתמשים ב-getCurrentDeviceDataSource() API כדי לאחזר את ה-SPN של המכשיר הנוכחי.
ספירת צעדים במכשיר דורשת גרסת SDK 20 ומעלה, אבל API getCurrentDeviceDataSource() זמין ב-Android 14 (רמת API 34) עם גרסת SDK 11 ומעלה.
ממשק ה-API של getCurrentDeviceDataSource() עדיין לא זמין בספריית Health
Connect Jetpack. בדוגמאות הבאות נעשה שימוש ב-API של Android framework במקום זאת:
import android.content.Context
import android.health.connect.HealthConnectManager
val healthConnectManager = context.getSystemService(HealthConnectManager::class.java)
val deviceDataSource = healthConnectManager?.getCurrentDeviceDataSource()
val currentDeviceSpn = deviceDataSource?.deviceDataOrigin?.packageName
אם האפליקציה צריכה לקרוא את הנתונים של הצעדים שנמדדו במכשיר, או אם היא מציגה נתוני צעדים שמפורטים לפי אפליקציית המקור או המכשיר, צריך לשלוח שאילתה לגבי רשומות שבהן DataOrigin הוא android או תואם ל-SPN של המכשיר. אם האפליקציה מציגה שיוך לנתוני צעדים, צריך להשתמש ב-metadata.device כדי לזהות את מכשיר המקור של רשומות נפרדות. לשלבים במכשיר שמזוהים על ידי SPN בנתונים מצטברים, אפשר להשתמש במטא-נתונים של המכשיר, כמו model או manufacturer מ-DeviceDataSource, לצורך שיוך, או להשתמש בתווית כללית כמו 'הטלפון שלך' לשלבים במכשיר.
בדוגמה הבאה אפשר לראות איך קוראים נתונים מצטברים של ספירת הצעדים במכשיר על ידי סינון לפי android וגם לפי SPN של המכשיר הנוכחי:
import android.content.Context
import android.health.connect.HealthConnectManager
import android.os.Build
import android.os.ext.SdkExtensions
import androidx.health.connect.client.HealthConnectClient
import androidx.health.connect.client.records.StepsRecord
import androidx.health.connect.client.records.metadata.DataOrigin
import androidx.health.connect.client.request.AggregateRequest
import androidx.health.connect.client.time.TimeRangeFilter
import java.time.Instant
suspend fun readDeviceStepsByTimeRange(
healthConnectClient: HealthConnectClient,
context: Context,
startTime: Instant,
endTime: Instant
) {
// 1. Check if SDK Extension 11+ is available for getCurrentDeviceDataSource()
val isDataSourceApiAvailable = Build.VERSION.SDK_INT >= Build.VERSION_CODES.U &&
SdkExtensions.getExtensionVersion(Build.VERSION_CODES.U) >= 11
try {
val healthConnectManager = context.getSystemService(HealthConnectManager::class.java)
// 2. Safely fetch the package name only if API is available and data exists
val currentDeviceSpn = if (isDataSourceApiAvailable) {
healthConnectManager?.getCurrentDeviceDataSource()?.deviceDataOrigin?.packageName
} else {
null
}
val dataOriginFilters = mutableSetOf(DataOrigin("android"))
// 3. Explicit null-safety check using .let
currentDeviceSpn?.let {
dataOriginFilters.add(DataOrigin(it))
}
val response = healthConnectClient.aggregate(
AggregateRequest(
metrics = setOf(StepsRecord.COUNT_TOTAL),
timeRangeFilter = TimeRangeFilter.between(startTime, endTime),
dataOriginFilter = dataOriginFilters
)
)
val stepCount = response[StepsRecord.COUNT_TOTAL]
} catch (e: Exception) {
// Now this catch block only handles actual runtime exceptions,
// rather than Errors from missing methods.
}
}
ספירת צעדים במכשיר
- שימוש בחיישנים: אפליקציית Health Connect משתמשת בחיישן
TYPE_STEP_COUNTERשלSensorManager. החיישן הזה מותאם לצריכת חשמל נמוכה, ולכן הוא אידיאלי למעקב רציף אחרי צעדים ברקע. - גרנולריות הנתונים: כדי לחסוך בחיי הסוללה, נתוני הצעדים בדרך כלל נכתבים בקבוצות למסד הנתונים של Health Connect בתדירות של פעם בדקה לכל היותר.
- שיוך (Attribution): שלבים שתועדו על ידי התכונה הזו לפני יוני 2026 משויכים לשם החבילה
androidב-DataOrigin. אחרי התאריך הזה, הם משויכים למספר SPN ספציפי למכשיר. שינוי השיוך לשלבים במכשיר - הפעלה: מנגנון ספירת הצעדים במכשיר פעיל רק אם לפחות אפליקציה אחת במכשיר קיבלה את ההרשאה
READ_STEPSב-Health Connect.
דוגמה לקריאה ברקע
כדי לקרוא נתונים ברקע, צריך להצהיר על ההרשאה הבאה בקובץ המניפסט:
<application>
<uses-permission android:name="android.permission.health.READ_HEALTH_DATA_IN_BACKGROUND" />
...
</application>
בדוגמה הבאה אפשר לראות איך קוראים נתונים של מספר הצעדים ברקע של משתמש בפרק זמן מסוים באמצעות WorkManager:
class ScheduleWorker(appContext: Context, workerParams: WorkerParameters) : CoroutineWorker(appContext, workerParams) { override suspend fun doWork(): Result { val healthConnectClient = HealthConnectClient.getOrCreate(applicationContext) // Perform background read logic here return Result.success() } }
@OptIn(ExperimentalFeatureAvailabilityApi::class) fun enqueueBackgroundReadWorker(context: Context, healthConnectClient: HealthConnectClient) { if (healthConnectClient .features .getFeatureStatus( HealthConnectFeatures.FEATURE_READ_HEALTH_DATA_IN_BACKGROUND ) == HealthConnectFeatures.FEATURE_STATUS_AVAILABLE ) { val periodicWorkRequest = PeriodicWorkRequestBuilder<ScheduleWorker>(1, TimeUnit.HOURS) .build() WorkManager.getInstance(context).enqueueUniquePeriodicWork( "read_health_connect", ExistingPeriodicWorkPolicy.KEEP, periodicWorkRequest ) } }
ערך ברירת המחדל של הפרמטר ReadRecordsRequest הוא pageSize (1,000).
אם מספר הרשומות בבקשה אחת מסוג readResponse חורג מהערך pageSize של הבקשה, צריך לחזור על כל הדפים של התשובה כדי לאחזר את כל הרשומות באמצעות pageToken.
עם זאת, חשוב להיזהר כדי לא לחרוג ממגבלות הקצב.
דוגמה לקריאה של pageToken
מומלץ להשתמש ב-pageToken לקריאת רשומות כדי לאחזר את כל הנתונים שזמינים מהתקופה המבוקשת.
בדוגמה הבאה אפשר לראות איך קוראים את כל הרשומות עד שכל אסימוני הדף מוצו:
val type = HeartRateRecord::class val endTime = Instant.now() val startTime = endTime.minus(Duration.ofDays(7)) try { var pageToken: String? = null do { val readResponse = healthConnectClient.readRecords( ReadRecordsRequest( recordType = type, timeRangeFilter = TimeRangeFilter.between( startTime, endTime ), pageToken = pageToken ) ) val records = readResponse.records // Do something with records pageToken = readResponse.pageToken } while (pageToken != null) } catch (quotaError: IllegalStateException) { // Backoff }
קריאת נתונים שנכתבו בעבר
אם אפליקציה כתבה רשומות ב-Health Connect בעבר, יכול להיות שהיא תוכל לקרוא נתונים היסטוריים. זה רלוונטי לתרחישים שבהם האפליקציה צריכה לבצע סנכרון מחדש עם Health Connect אחרי שהמשתמש התקין אותה מחדש.
חלות הגבלות מסוימות על קריאה:
ב-Android מגרסה 14 ואילך
- אין מגבלה היסטורית על אפליקציה שקוראת את הנתונים שלה.
- מגבלה של 30 יום על אפליקציה שקוראת נתונים אחרים.
ב-Android מגרסה 13 ומטה
- מגבלה של 30 יום על קריאת נתונים על ידי אפליקציה.
כדי להסיר את ההגבלות, צריך לבקש הרשאת קריאה.
כדי לקרוא נתונים היסטוריים, צריך לציין את שם החבילה כאובייקט DataOrigin בפרמטר dataOriginFilter של ReadRecordsRequest.
בדוגמה הבאה אפשר לראות איך מציינים שם חבילה כשקוראים רשומות של קצב הלב:
try { val response = healthConnectClient.readRecords( ReadRecordsRequest( recordType = HeartRateRecord::class, timeRangeFilter = TimeRangeFilter.between(startTime, endTime), dataOriginFilter = setOf(DataOrigin("com.my.package.name")) ) ) for (record in response.records) { // Process each record } } catch (e: Exception) { // Run error handling here }
קריאת נתונים מלפני יותר מ-30 יום
כברירת מחדל, כל האפליקציות יכולות לקרוא נתונים מ-Health Connect עד 30 ימים לפני מועד מתן ההרשאה הראשונה.
אם אתם צריכים להרחיב את הרשאות הקריאה מעבר להגבלות ברירת המחדל, אתם יכולים לבקש את PERMISSION_READ_HEALTH_DATA_HISTORY.
אחרת, ללא ההרשאה הזו, ניסיון לקרוא רשומות מלפני יותר מ-30 יום יגרום לשגיאה.
היסטוריית ההרשאות של אפליקציה שנמחקה
אם משתמש מוחק את האפליקציה שלכם, כל ההרשאות, כולל הרשאת הגישה להיסטוריה, מבוטלות. אם המשתמש מתקין מחדש את האפליקציה שלכם ומעניק לה הרשאה שוב, חלות עליה ההגבלות שמוגדרות כברירת מחדל, והאפליקציה יכולה לקרוא נתונים מ-Health Connect עד 30 ימים לפני התאריך החדש.
לדוגמה, נניח שהמשתמש מוחק את האפליקציה שלכם ב-10 במאי 2023, ואז מתקין אותה מחדש ב-15 במאי 2023 ומעניק לה הרשאות קריאה. התאריך המוקדם ביותר שממנו האפליקציה יכולה לקרוא נתונים כברירת מחדל הוא 15 באפריל 2023.
טיפול בחריגים
אפליקציית Health Connect יוצרת חריגים סטנדרטיים לפעולות CRUD כשמתגלה בעיה. האפליקציה צריכה לזהות ולטפל בכל אחד מהחריגים האלה בצורה המתאימה.
בכל שיטה ב-HealthConnectClient מפורטים החריגים שיכולים להיות מושלכים.
באופן כללי, האפליקציה צריכה לטפל בחריגים הבאים:
| חריג | תיאור | שיטה מומלצת |
|---|---|---|
IllegalStateException
| אחד מהתרחישים הבאים התרחש:
| לפני ששולחים בקשה, צריך לטפל בבעיות אפשריות בקלט. מומלץ להקצות ערכים למשתנים או להשתמש בהם כפרמטרים בפונקציה מותאמת אישית במקום להשתמש בהם ישירות בבקשות, כדי שתוכלו להחיל אסטרטגיות לטיפול בשגיאות. |
IOException
| זוהו בעיות בקריאה ובכתיבה של נתונים מהדיסק. | כדי למנוע את הבעיה הזו, אפשר לנסות את הפתרונות הבאים:
|
RemoteException
| אירעו שגיאות בשירות הבסיסי שאליו ה-SDK מתחבר, או בתקשורת איתו. לדוגמה, האפליקציה מנסה למחוק רשומה עם uid נתון. עם זאת, החריגה מופעלת אחרי שהאפליקציה מגלה במהלך הצ'ק-אין לשירות הבסיסי שהרשומה לא קיימת.
| כדי למנוע את הבעיה הזו, אפשר לנסות את הפתרונות הבאים:
|
SecurityException
| הבעיות מתרחשות כשהבקשות דורשות הרשאות שלא ניתנו. | כדי למנוע את זה, חשוב לוודא שהצהרתם על השימוש בסוגי הנתונים של Health Connect באפליקציה שפרסמתם. בנוסף, עליכם להצהיר על ההרשאות של Health Connect בקובץ המניפסט ובפעילות. |