يوضّح المثال التالي كيفية قراءة البيانات الأولية كجزء من سير العمل الشائع.
قراءة البيانات
يتيح 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 (المستوى 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.
تكون أسماء الحزم الاصطناعية خاصة بالجهاز ومحدّدة على أساس كل تطبيق لحماية خصوصية المستخدم:
- ثابتة: يكون اسم الحزمة الاصطناعي للجهاز الحالي ثابتًا لتطبيقك.
- محدّدة على مستوى التطبيق: ترى التطبيقات المختلفة على الجهاز نفسه أسماء حزم اصطناعية مختلفة لبيانات الخطوات على الجهاز فقط.
طلب الخطوات على الجهاز فقط
بما أنّ أسماء الحزم الاصطناعية محدّدة على مستوى الجهاز، يجب عدم استخدام ترميز ثابت لقيم أسماء الحزم الاصطناعية. بدلاً من ذلك، استخدِم واجهة برمجة التطبيقات getCurrentDeviceDataSource() لاسترداد اسم الحزمة الاصطناعي للجهاز الحالي.
في حين أنّ عدّ الخطوات على الجهاز فقط يتطلّب الإصدار 20 أو إصدارًا أحدث من حزمة تطوير البرامج (SDK)، تتوفّر واجهة برمجة التطبيقات getCurrentDeviceDataSource() على Android 14 (المستوى 34 من واجهة برمجة التطبيقات) مع الإصدار 11 أو إصدار أحدث من حزمة تطوير البرامج (SDK).
لا تتوفّر واجهة برمجة التطبيقات getCurrentDeviceDataSource() بعد في مكتبة Health Connect Jetpack. تستخدِم الأمثلة التالية واجهة برمجة التطبيقات لإطار عمل Android بدلاً من ذلك:
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 أو يتطابق مع اسم الحزمة الاصطناعي للجهاز. إذا كان تطبيقك يعرض تحديد المصدر لبيانات الخطوات، استخدِم metadata.device
لتحديد الجهاز المصدر للسجلات الفردية. بالنسبة إلى الخطوات على الجهاز فقط التي تم تحديدها من خلال اسم حزمة اصطناعي في البيانات المجمّعة، يمكنك استخدام بيانات الجهاز الوصفية، مثل model أو manufacturer من DeviceDataSource لتحديد المصدر، أو استخدام تصنيف عام، مثل "هاتفك" للخطوات على الجهاز فقط.
يوضّح المثال التالي كيفية قراءة بيانات عدد الخطوات المجمّعة على الجهاز فقط من خلال الفلترة حسب كل من android واسم الحزمة الاصطناعي للجهاز الحالي:
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 مرة واحدة في الدقيقة على الأكثر.
- تحديد المصدر: يتم تحديد مصدر الخطوات التي تسجِّلها هذه الميزة قبل يونيو 2026 على أنّه اسم الحزمة
androidفيDataOrigin. بعد هذا التاريخ، يتم تحديد مصدرها على أنّه اسم حزمة اصطناعي خاص بالجهاز. يمكنك الاطّلاع على تغيير تحديد المصدر للخطوات على الجهاز فقط. - التفعيل: لا تكون آلية عدّ الخطوات على الجهاز نشطة إلا عندما يتم منح إذن
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 تبلغ 1000.
إذا كان عدد السجلات في 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 في ملف البيان وفي نشاطك. |