בדוגמה הבאה אפשר לראות איך לקרוא נתונים גולמיים כחלק מתהליך העבודה הנפוץ.
קריאת נתונים
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.
שינוי השיוך לשלבים במכשיר
החל מהעדכון של יוני 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() } }
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 יום על אפליקציה שקוראת נתונים אחרים.
בגרסה 13 של Android ובגרסאות קודמות
- מגבלה של 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 בקובץ המניפסט ובפעילות. |