Health Connect מספקת סוג נתונים של צעדים לתיעוד של מספר הצעדים באמצעות StepsRecord. צעדים הם מדד בסיסי למעקב אחרי הבריאות והכושר.
קריאה של נתוני הצעדים בנייד
ב-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.
בדיקת הזמינות של Health Connect
לפני שמנסים להשתמש ב-Health Connect, האפליקציה צריכה לוודא שהשירות זמין במכשיר של המשתמש. יכול להיות שאפליקציית Health Connect לא מותקנת מראש בחלק מהמכשירים או שהיא מושבתת.
אפשר לבדוק את הזמינות באמצעות ה-method HealthConnectClient.getSdkStatus().
איך בודקים אם אפליקציית Health Connect זמינה
fun checkHealthConnectAvailability(context: Context) { val providerPackageName = "com.google.android.apps.healthdata" // Or get from HealthConnectClient.DEFAULT_PROVIDER_PACKAGE_NAME val availabilityStatus = HealthConnectClient.getSdkStatus(context, providerPackageName) if (availabilityStatus == HealthConnectClient.SDK_UNAVAILABLE) { // Health Connect is not available. Guide the user to install/enable it. // For example, show a dialog. return // early return as there is no viable integration } if (availabilityStatus == HealthConnectClient.SDK_UNAVAILABLE_PROVIDER_UPDATE_REQUIRED) { // Health Connect is available but requires an update. // Optionally redirect to package installer to find a provider, for example: val uriString = "market://details?id=$providerPackageName&url=healthconnect%3A%2F%2Fonboarding" context.startActivity( Intent(Intent.ACTION_VIEW).apply { setPackage("com.android.vending") data = Uri.parse(uriString) putExtra("overlay", true) putExtra("callerId", context.packageName) } ) return } // Health Connect is available, obtain a HealthConnectClient instance val healthConnectClient = HealthConnectClient.getOrCreate(context) // Issue operations with healthConnectClient }
בהתאם לסטטוס שמוחזר על ידי getSdkStatus(), תוכלו להנחות את המשתמש להתקין או לעדכן את Health Connect מחנות Google Play, אם יש צורך בכך.
ההרשאות הנדרשות
הגישה לנתוני הצעדים מוגנת על ידי ההרשאות הבאות:
android.permission.health.READ_STEPSandroid.permission.health.WRITE_STEPS
כדי להוסיף לאפליקציה אפשרות של צעדים, צריך קודם לבקש הרשאות לסוג הנתונים Steps.
זו ההרשאה שצריך להצהיר עליה כדי שיהיה אפשר לכתוב נתונים של צעדים:
<application>
<uses-permission
android:name="android.permission.health.WRITE_STEPS" />
...
</application>
כדי לקרוא את השלבים, צריך לבקש את ההרשאות הבאות:
<application>
<uses-permission
android:name="android.permission.health.READ_STEPS" />
...
</application>
בקשת הרשאות מהמשתמש
אחרי שיוצרים מופע של לקוח, האפליקציה צריכה לבקש הרשאות מהמשתמש. צריך לאפשר למשתמשים להעניק או לדחות הרשאות בכל שלב.
כדי לעשות זאת, יוצרים קבוצת הרשאות לסוגי הנתונים הנדרשים. קודם צריך לוודא שההרשאות בקבוצה מוצהרות במניפסט של Android.
// Create a set of permissions for required data types
val PERMISSIONS =
setOf(
HealthPermission.getReadPermission(StepsRecord::class),
HealthPermission.getWritePermission(StepsRecord::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)
}
}
המשתמשים יכולים לתת או לבטל הרשאות בכל שלב, ולכן האפליקציה צריכה לבדוק אם ההרשאות ניתנו בכל פעם לפני שהיא משתמשת בהן, ולטפל במקרים שבהם הרשאה כלשהי בוטלה.
המידע שכלול ברשומה של שלבים
כל StepsRecord מכיל את הפרטים הבאים:
-
count: מספר הצעדים שנמדדו במרווח הזמן, כערךLong. -
startTime: שעת ההתחלה של מרווח המדידה. -
endTime: שעת הסיום של מרווח המדידה. -
startZoneOffset: ההסטה מאזור הזמן של שעת ההתחלה. -
endZoneOffset: ההפרש מאזור הזמן של שעת הסיום.
צבירות נתמכות
הערכים המצטברים הבאים זמינים עבור StepsRecord:
הערכים המצטברים הבאים זמינים עבור StepsCadenceRecord:
דוגמת שימוש
בקטעים הבאים מוסבר איך לקרוא ולכתוב נתונים של StepsRecord.
כתיבה של נתוני הצעדים
האפליקציה יכולה לכתוב נתונים של מספר הצעדים על ידי הוספה של מופעים של StepsRecord
בדוגמה הבאה אפשר לראות איך מתעדים 1,000 צעדים שמשתמש עשה:
val zoneOffset = ZoneOffset.systemDefault().rules.getOffset(startTime) val stepsRecord = StepsRecord( count = 120, startTime = startTime, endTime = endTime, startZoneOffset = zoneOffset, endZoneOffset = zoneOffset, metadata = Metadata( device = Device(type = Device.TYPE_WATCH), recordingMethod = Metadata.RECORDING_METHOD_AUTOMATICALLY_RECORDED ) ) healthConnectClient.insertRecords(listOf(stepsRecord))
קריאת נתונים נצברים
הדרך הנפוצה ביותר לקרוא נתוני צעדים היא לצבור את סך הצעדים לאורך תקופת זמן מסוימת. בדוגמה הבאה אפשר לראות איך קוראים את מספר הצעדים הכולל של משתמש בטווח תאריכים מסוים:
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 }
קריאת נתונים גולמיים
בדוגמה הבאה אפשר לראות איך קוראים נתוני StepsRecord גולמיים בין שעת התחלה לשעת סיום:
val response = healthConnectClient.readRecords( ReadRecordsRequest( StepsRecord::class, timeRangeFilter = TimeRangeFilter.between(startTime, endTime) ) ) response.records.forEach { record -> /* Process records */ }