يوفّر Health Connect نوع بيانات الخطوات لتسجيل عدد الخطوات باستخدام
StepsRecord. الخطوات هي مقياس أساسي في تتبُّع الصحة واللياقة البدنية.
يتوافق هذا الدليل مع الإصدار 1.1.0-alpha12 من Health Connect أو الإصدارات الأحدث.
قراءة بيانات الخطوات على الأجهزة الجوّالة
في الإصدار Android 14 (المستوى 34 لواجهة برمجة التطبيقات) والإصدار 20 أو الإصدارات الأحدث من إضافة حزمة تطوير البرامج (SDK)، يوفّر تطبيق Health Connect ميزة احتساب الخطوات على الجهاز فقط. إذا تم منح أي تطبيق إذن READ_STEPS، سيبدأ Health Connect في تسجيل الخطوات من الجهاز الذي يعمل بنظام التشغيل Android، وستظهر للمستخدمين بيانات الخطوات التي تمت إضافتها تلقائيًا إلى إدخالات الخطوات في Health Connect.
للتحقّق من توفّر ميزة احتساب الخطوات على الجهاز فقط، تأكَّد من أنّ الجهاز يعمل بنظام التشغيل Android 14 (مستوى واجهة برمجة التطبيقات 34) وأنّه يتضمّن الإصدار 20 على الأقل من إضافة حزمة تطوير البرامج (SDK):
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 لاسترداد
شبكة شركاء البحث (SPN) للجهاز الحالي.
يتطلّب احتساب الخطوات على الجهاز فقط الإصدار 20 أو إصدار أحدث من إضافة حزمة تطوير البرامج (SDK)،
بينما تتوفّر واجهة برمجة التطبيقات getCurrentDeviceDataSource() على الإصدار 14 من نظام التشغيل Android (المستوى 34 من واجهة برمجة التطبيقات)
مع الإصدار 22 أو إصدار أحدث من إضافة حزمة تطوير البرامج (SDK). لاستخدام واجهة برمجة التطبيقات هذه، اضبط
compileSdkExtension على 22 أو قيمة أعلى في ملف build.gradle.kts
أو build.gradle على مستوى الوحدة:
Kotlin
android { compileSdk = 35 compileSdkExtension = 22 }
أنيق
android { compileSdk 35 compileSdkExtension 22 }
لا تتوفّر واجهة برمجة التطبيقات getCurrentDeviceDataSource() API بعد في مكتبة Health Connect Jetpack. تستخدم الأمثلة التالية واجهة برمجة تطبيقات إطار عمل Android،
والتي تتطلّب دالة ردّ اتصال Executor وOutcomeReceiver:
import android.content.Context
import android.health.connect.DeviceDataSource
import android.health.connect.HealthConnectException
import android.health.connect.HealthConnectManager
import android.os.OutcomeReceiver
val healthConnectManager = context.getSystemService(HealthConnectManager::class.java)
healthConnectManager?.getCurrentDeviceDataSource(
context.mainExecutor,
object : OutcomeReceiver<DeviceDataSource, HealthConnectException> {
override fun onResult(result: DeviceDataSource) {
val currentDeviceSpn = result.deviceDataOrigin.packageName
}
override fun onError(error: HealthConnectException) {
// Handle error
}
}
)
إذا كان تطبيقك بحاجة إلى قراءة الخطوات على الجهاز فقط، أو إذا كان يعرض بيانات الخطوات مُقسَّمة حسب التطبيق أو الجهاز المصدر، يجب البحث عن السجلّات التي يكون فيها DataOrigin هو android أو يتطابق مع اسم مقدّم الخدمة (SPN) للجهاز. إذا كان تطبيقك يعرض مصدر بيانات الخطوات، استخدِم metadata.device لتحديد الجهاز المصدر للسجلات الفردية. بالنسبة إلى الخطوات التي يتم تنفيذها على الجهاز فقط ويتم تحديدها من خلال رقم SPN في البيانات المجمّعة، يمكنك استخدام البيانات الوصفية للجهاز، مثل model أو manufacturer من DeviceDataSource لتحديد المصدر، أو استخدام تصنيف عام مثل "هاتفك" للخطوات التي يتم تنفيذها على الجهاز فقط.
يوضّح المثال التالي كيفية قراءة بيانات عدد الخطوات المجمّعة على الجهاز فقط
من خلال الفلترة حسب كل من android ورقم SPN للجهاز الحالي:
import android.content.Context
import android.health.connect.DeviceDataSource
import android.health.connect.HealthConnectException
import android.health.connect.HealthConnectManager
import android.os.Build
import android.os.OutcomeReceiver
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
import kotlin.coroutines.resume
import kotlin.coroutines.resumeWithException
import kotlinx.coroutines.suspendCancellableCoroutine
suspend fun readDeviceStepsByTimeRange(
healthConnectClient: HealthConnectClient,
context: Context,
startTime: Instant,
endTime: Instant
) {
// 1. Check if SDK Extension 22+ is available for getCurrentDeviceDataSource()
val isDataSourceApiAvailable =
Build.VERSION.SDK_INT >= Build.VERSION_CODES.UPSIDE_DOWN_CAKE &&
SdkExtensions.getExtensionVersion(Build.VERSION_CODES.UPSIDE_DOWN_CAKE) >= 22
try {
val healthConnectManager = context.getSystemService(HealthConnectManager::class.java)
// 2. Safely fetch the package name only if the API is available
val currentDeviceSpn = if (isDataSourceApiAvailable && healthConnectManager != null) {
suspendCancellableCoroutine { continuation ->
healthConnectManager.getCurrentDeviceDataSource(
context.mainExecutor,
object : OutcomeReceiver<DeviceDataSource, HealthConnectException> {
override fun onResult(result: DeviceDataSource) {
continuation.resume(result.deviceDataOrigin.packageName)
}
override fun onError(error: HealthConnectException) {
continuation.resumeWithException(error)
}
}
)
}
} 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 بمعدّل لا يزيد عن مرة واحدة في الدقيقة.
- تحديد المصدر: يتم تحديد مصدر الخطوات التي تسجّلها هذه الميزة قبل يونيو 2026 على أنّه اسم الحزمة
androidفيDataOrigin. وبعد هذا التاريخ، يتم ربطها برقم SPN خاص بالجهاز. يُرجى الاطّلاع على تغيير في تحديد المصدر للخطوات التي يتم تتبُّعها على الجهاز فقط. - التفعيل: لا يتم تفعيل آلية احتساب الخطوات على الجهاز إلا إذا تم منح تطبيق واحد على الأقل على الجهاز إذن
READ_STEPSضمن Health Connect.
التحقّق من توفّر Health Connect
قبل محاولة استخدام Health Connect، يجب أن يتأكّد تطبيقك من توفُّر Health Connect على جهاز المستخدم. قد لا يكون تطبيق Health Connect مثبَّتًا مسبقًا على جميع الأجهزة أو قد يكون غير مفعَّل.
يمكنك التحقّق من توفّره باستخدام طريقة HealthConnectClient.getSdkStatus().
كيفية التحقّق من توفّر Health Connect
fun checkHealthConnectAvailability(context: Context) { val providerPackageName = "com.google.android.apps.healthdata" 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 أولاً.
val permissions = setOf( 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.") } } }
المعلومات المضمّنة في سجلّ الخطوات
يحتوي كل StepsRecord على المعلومات التالية:
count: عدد الخطوات التي تم قطعها خلال الفترة الزمنية، كقيمةLong.startTime: وقت بدء الفاصل الزمني للقياس.-
endTime: وقت انتهاء الفاصل الزمني للقياس -
startZoneOffset: يشير إلى معادلة المنطقة الزمنية لوقت البدء. -
endZoneOffset: يمثّل هذا الحقل معادلة المنطقة الزمنية لوقت الانتهاء.
عمليات التجميع المتوافقة
تتوفّر القيم المجمّعة التالية لـ StepsRecord:
تتوفّر القيم المجمّعة التالية لـ StepsCadenceRecord:
مثال للاستخدام
توضّح الأقسام التالية كيفية قراءة بيانات StepsRecord وكتابتها.
كتابة بيانات الخطوات
يمكن لتطبيقك كتابة بيانات عدد الخطوات من خلال إدراج نُسخ StepsRecord. يوضّح المثال التالي كيفية تسجيل 1000 خطوة اتّخذها المستخدم:
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))
قراءة البيانات المجمّعة
الطريقة الأكثر شيوعًا لقراءة بيانات الخطوات هي تجميع إجمالي الخطوات على مدار فترة زمنية. يوضّح المثال التالي كيفية قراءة إجمالي عدد الخطوات لمستخدم ضمن نطاق زمني معيّن:
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 */ }