يوفّر Health Connect نوع بيانات الخطوات لتسجيل عدد الخطوات باستخدام
StepsRecord. الخطوات هي مقياس أساسي لتتبُّع الصحة واللياقة البدنية.
قراءة بيانات خطوات الجوّال
في نظام التشغيل Android 14 (المستوى 34 لواجهة برمجة التطبيقات) والإصدار 20 أو الإصدارات الأحدث من حزمة SDK Extension، يوفّر تطبيق 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
يتم ضبط قيمة DataOrigin للخطوات على الأجهزة الجوّالة التي يسجّلها Health Connect على اسم الحزمة android. إذا كان تطبيقك يقرأ ببساطة عدد الخطوات المجمّع باستخدام aggregate ولا يفلتر حسب DataOrigin، سيتم تلقائيًا تضمين الخطوات المسجّلة على الجهاز في الإجمالي.
إذا كان تطبيقك يحتاج إلى قراءة الخطوات المسجّلة على الجهاز، أو إذا كان يعرض بيانات الخطوات مصنّفة حسب التطبيق أو الجهاز المصدر، يمكنك طلب البحث عن السجلات التي تكون فيها DataOrigin هي android. إذا كان تطبيقك يعرض تحديد المصدر لبيانات الخطوات، يجب تحديد مصدر البيانات من حزمة Android إلى الجهاز الحالي.
يمكنك إجراء ذلك باستخدام تصنيف مثل "هاتفك"، أو استرداد اسم الجهاز باستخدام Settings.Global.getString(resolver, Settings.Global.DEVICE_NAME)، أو فحص الحقل Device في البيانات الوصفية للسجلّ.
يوضّح المثال التالي كيفية قراءة بيانات عدد الخطوات المجمّعة على الأجهزة الجوّالة من خلال فلترة مصدر البيانات android:
suspend fun readStepsByTimeRange(
healthConnectClient: HealthConnectClient,
startTime: Instant,
endTime: Instant
) {
try {
val response = healthConnectClient.aggregate(
AggregateRequest(
metrics = setOf(StepsRecord.COUNT_TOTAL),
timeRangeFilter = TimeRangeFilter.between(startTime, endTime),
dataOriginFilter = setOf(DataOrigin("android"))
)
)
// The result may be null if no data is available in the time range
val stepCount = response[StepsRecord.COUNT_TOTAL]
} catch (e: Exception) {
// Run error handling here
}
}
احتساب عدد الخطوات على الجهاز فقط
نظرة معمّقة على ميزة "احتساب الخطوات" على الجهاز:
- استخدام أداة الاستشعار: يستخدم تطبيق Health Connect أداة الاستشعار
TYPE_STEP_COUNTERمنSensorManager. تم تحسين هذا المستشعر لتقليل استهلاك الطاقة، ما يجعله مثاليًا لتتبُّع الخطوات بشكل مستمر في الخلفية. - دقة البيانات: للحفاظ على عمر البطارية، يتم عادةً تجميع بيانات الخطوات وكتابتها في قاعدة بيانات Health Connect بمعدّل لا يزيد عن مرة واحدة في الدقيقة.
- تحديد المصدر: كما ذكرنا سابقًا، يتم تحديد مصدر جميع الخطوات التي تسجّلها هذه الميزة على الجهاز على أنّه اسم حزمة
androidفيDataOrigin. - التفعيل: لا تكون آلية احتساب الخطوات على الجهاز نشطة إلا عندما يمنح تطبيق واحد على الأقل على الجهاز إذن
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" // 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 خطوة اتّخذها أحد المستخدمين:
suspend fun writeStepsData(
healthConnectClient: HealthConnectClient,
startTime: Instant,
endTime: Instant,
startZoneOffset: ZoneOffset,
endZoneOffset: ZoneOffset
) {
try {
val stepsRecord = StepsRecord(
startTime = startTime,
startZoneOffset = startZoneOffset,
endTime = endTime,
endZoneOffset = endZoneOffset,
count = 1000
)
healthConnectClient.insertRecords(listOf(stepsRecord))
} catch (e: Exception) {
// Run error handling
}
}
قراءة البيانات المجمّعة
الطريقة الأكثر شيوعًا لقراءة بيانات الخطوات هي تجميع إجمالي الخطوات خلال فترة زمنية معيّنة. يوضّح المثال التالي كيفية قراءة إجمالي عدد الخطوات لمستخدم ضمن نطاق زمني معيّن:
suspend fun readStepsAggregate(
healthConnectClient: HealthConnectClient,
startTime: Instant,
endTime: Instant
) {
try {
val response = healthConnectClient.aggregate(
AggregateRequest(
metrics = setOf(StepsRecord.COUNT_TOTAL),
timeRangeFilter = TimeRangeFilter.between(startTime, endTime)
)
)
// The result may be null if no data is available in the time range
val stepCount = response[StepsRecord.COUNT_TOTAL]
} catch (e: Exception) {
// Run error handling here
}
}
قراءة البيانات الأولية
يوضّح المثال التالي كيفية قراءة بيانات StepsRecord الأولية
بين وقتَي البدء والانتهاء:
suspend fun readStepsRaw(
healthConnectClient: HealthConnectClient,
startTime: Instant,
endTime: Instant
) {
try {
val response = healthConnectClient.readRecords(
ReadRecordsRequest(
recordType = StepsRecord::class,
timeRangeFilter = TimeRangeFilter.between(startTime, endTime)
)
)
for (record in response.records) {
// Process each record
}
} catch (e: Exception) {
// Run error handling here
}
}