همگام‌سازی داده‌ها

این راهنما با نسخه 1.1.0-alpha12 از Health Connect سازگار است.

اکثر برنامه‌هایی که با Health Connect ادغام می‌شوند، فروشگاه داده خودشان را دارند که به‌عنوان منبع حقیقت عمل می‌کند. ‫Health Connect روش‌هایی برای همگام‌سازی برنامه شما ارائه می‌دهد.

بسته به معماری برنامه‌تان، فرایند همگام‌سازی ممکن است شامل برخی یا همه کنش‌های زیر باشد:

  • داده‌های جدید یا به‌روزشده را از مخزن داده برنامه به Health Connect ارسال کنید.
  • تغییرات داده را از Health Connect به مخزن داده برنامه خود بکشید.
  • وقتی داده‌ها در مخزن داده برنامه شما حذف می‌شود، داده‌ها از Health Connect نیز حذف شود.

در هر مورد، مطمئن شوید که فرایند همگام‌سازی باعث می‌شود هم Health Connect و هم مخزن داده برنامه شما هم‌راستا باشند.

ارائه داده‌ها به Health Connect

اولین بخش از فرایند همگام‌سازی، انتقال داده‌ها از مخزن داده برنامه شما به مخزن داده Health Connect است.

آماده‌سازی داده‌ها

معمولاً سوابق موجود در مخزن داده برنامه شما جزئیات زیر را دارد:

  • کلید یکتا، مثل UUID.
  • نسخه یا مُهر زمان.

هنگام همگام‌سازی داده‌ها با Health Connect، فقط داده‌هایی را که از زمان آخرین همگام‌سازی درج، به‌روزرسانی، یا حذف شده‌اند شناسایی و ارائه کنید.

نوشتن داده‌ها در Health Connect

برای وارد کردن داده‌ها در Health Connect، مراحل زیر را انجام دهید:

  1. فهرستی از ورودی‌های جدید، به‌روزرسانی‌شده، یا حذف‌شده از مخزن داده برنامه‌تان دریافت کنید.
  2. برای هر ورودی، یک شیء Record مناسب برای آن نوع داده ایجاد کنید. برای مثال، برای داده‌های مربوط به وزن، شیء WeightRecord ایجاد کنید.
  3. شیء Metadata را با هر Record مشخص کنید. این شامل clientRecordId می‌شود که شناسه‌ای از مخزن داده برنامه شما است که می‌توانید از آن برای شناسایی یکتای سوابق استفاده کنید. می‌توانید از کلید منحصربه‌فرد موجودتان برای این کار استفاده کنید. اگر داده‌هایتان دارای نسخه است، clientRecordVersion را نیز ارائه دهید که با نسخه‌بندی استفاده‌شده در داده‌هایتان مطابقت داشته باشد. اگر نسخه‌بندی نشده است، می‌توانید از مقدار Long مهر زمان کنونی به‌عنوان جایگزین استفاده کنید.

    val recordVersion = 0L
    // Specify as needed
    // The clientRecordId is an ID that you choose for your record. This
    // is often the same ID you use in your app's datastore.
    val clientRecordId = "<your-record-id>"
    
    val record = WeightRecord(
        metadata = Metadata.activelyRecorded(
            clientRecordId = clientRecordId,
            clientRecordVersion = recordVersion,
            device = Device(type = Device.TYPE_SCALE)
        ),
        weight = Mass.kilograms(62.0),
        time = Instant.now(),
        zoneOffset = ZoneOffset.UTC,
    )
    healthConnectClient.insertRecords(listOf(record))

  4. داده‌ها را بااستفاده از insertRecords در Health Connect درج و به‌روزرسانی کنید. «درج و به‌روزرسانی» داده‌ها یعنی هر داده موجود در Health Connect بازنویسی می‌شود، به‌شرطی که مقادیر clientRecordId در مخزن داده Health Connect وجود داشته باشد و clientRecordVersion بالاتر از مقدار موجود باشد. درغیراین‌صورت، داده‌های درج‌شده به‌عنوان داده‌های جدید نوشته می‌شود.

    healthConnectClient.insertRecords(arrayListOf(record))

برای آشنایی با ملاحظات عملی برای وارد کردن داده‌ها، روال‌های مطلوب نوشتن داده‌ها را بررسی کنید.

ذخیره شناسه‌های Health Connect

اگر برنامه شما داده‌ها را از Health Connect نیز می‌خواند، id Health Connect را برای سوابق پس‌از درج و به‌روزرسانی آن‌ها ذخیره کنید. برای پردازش حذف‌ها هنگام کشیدن تغییرات داده از Health Connect به این id نیاز دارید.

تابع insertRecords InsertRecordsResponse را برمی‌گرداند که حاوی فهرست مقادیر id است. از پاسخ برای دریافت «شناسه‌های سوابق» و ذخیره کردن آن‌ها استفاده کنید.

val response = healthConnectClient.insertRecords(listOf(record))
for (recordId in response.recordIdsList) {
    // Store recordId to your app's datastore
}

کشیدن داده‌ها از Health Connect

بخش دوم فرایند همگام‌سازی این است که هرگونه تغییر داده را از Health Connect به مخزن داده برنامه خود بکشید. تغییرات داده می‌تواند شامل به‌روزرسانی‌ها و حذف‌ها باشد.

دریافت کد «تغییرات»

برای دریافت فهرست تغییرات برای کشیدن از Health Connect، برنامه شما باید نشانه‌های تغییرات را پیگیری کند. می‌توانید از آن‌ها هنگام درخواست تغییرات برای برگرداندن هم فهرست تغییرات داده و هم نشان تغییرات جدید برای استفاده در دفعه بعدی استفاده کنید.

برای دریافت نشان تغییرات، با getChangesToken تماس بگیرید و انواع داده‌های موردنیاز را ارائه دهید.

val changesToken = healthConnectClient.getChangesToken(
    ChangesTokenRequest(recordTypes = setOf(WeightRecord::class))
)

بررسی تغییرات داده

اکنون که یک کد تغییرات دریافت کرده‌اید، از آن برای دریافت همه تغییرات استفاده کنید. توصیه می‌کنیم حلقه‌ای ایجاد کنید تا همه تغییرات را بررسی کند و ببیند آیا تغییرات داده دردسترس وجود دارد یا نه. مراحل زیر را دنبال کنید:

  1. بااستفاده از کد، با getChanges تماس بگیرید تا فهرست تغییرات را دریافت کنید.
  2. بررسی کنید که نوع تغییر هریک از آن‌ها UpsertionChange یا DeletionChange است و عملیات لازم را انجام دهید.
    • برای UpsertionChange، فقط تغییراتی را بپذیرید که از برنامه تماس‌گیرنده نیامده است تا مطمئن شوید داده‌ها را دوباره وارد نمی‌کنید.
  3. نشان تغییرات بعدی را به‌عنوان نشان جدیدتان اختصاص دهید.
  4. مراحل ۱ تا ۳ را تکرار کنید تا دیگر تغییری باقی نماند.
  5. نشان بعدی را ذخیره کنید و آن را برای وارد کردن در آینده رزرو کنید.

suspend fun processChanges(context: Context, token: String): String {
    var nextChangesToken = token
    do {
        val response = healthConnectClient.getChanges(nextChangesToken)
        response.changes.forEach { change ->
            when (change) {
                is UpsertionChange ->
                    if (change.record.metadata.dataOrigin.packageName != context.packageName) {
                        processUpsertionChange(change)
                    }
                is DeletionChange -> processDeletionChange(change)
            }
        }
        nextChangesToken = response.nextChangesToken
    } while (response.hasMore)
    // Return and store the changes token for use next time.
    return nextChangesToken
}

برای آشنایی با ملاحظات عملی برای کشیدن داده‌ها، روال‌های مطلوب برای همگام‌سازی داده‌ها را بررسی کنید.

پردازش تغییرات داده

تغییرات را در مخزن داده برنامه اعمال کنید. برای UpsertionChange، از id و lastModifiedTime از metadata آن برای درج یا به‌روزرسانی کردن سابقه استفاده کنید. برای DeletionChange، از id ارائه‌شده برای حذف سابقه استفاده کنید. برای این کار باید سابقه id را همان‌طور که در ذخیره شناسه‌های Health Connect ذکر شده است ذخیره کرده باشید.

حذف داده‌ها از Health Connect

وقتی کاربری داده‌های خود را از برنامه شما حذف می‌کند، مطمئن شوید که داده‌ها از Health Connect نیز برداشته می‌شود. برای انجام این کار، از deleteRecords استفاده کنید. این تابع نوعی گزارش و فهرستی از id و clientRecordId مقادیر را می‌گیرد که باعث می‌شود حذف دسته‌ای داده‌های متعدد آسان شود. یک جایگزین deleteRecords که timeRangeFilter را می‌گیرد نیز دردسترس است.

همگام‌سازی با تأخیر کم از پوشیدنی‌ها

برای همگام‌سازی داده‌ها از دستگاه تناسب اندام پوشیدنی به Health Connect با تأخیر کم، از CompanionDeviceService استفاده کنید. این رویکرد برای دستگاه‌هایی که از «اعلان‌ها یا نشانه‌های GATT با بلوتوث کم‌مصرف» پشتیبانی می‌کنند و Android 8.0 (سطح میانای برنامه‌سازی کاربردی ۲۶) یا بالاتر را هدف قرار می‌دهند کار می‌کند. ‫CompanionDeviceService به برنامه شما اجازه می‌دهد داده‌ها را از وسایل پوشیدنی دریافت کند و آن‌ها را در Health Connect بنویسد، حتی اگر برنامه درحال اجرا نباشد. برای جزئیات بیشتر درباره روال‌های مطلوب BLE، به نمای کلی Bluetooth کم‌مصرف مراجعه کنید.

دستگاه را منسوب کنید

ابتدا برنامه شما باید کاربر را ازطریق فرایندی یک‌باره راهنمایی کند تا بااستفاده از CompanionDeviceManager، پوشیدنی را با برنامه شما مرتبط کند. این کار به برنامه شما اجازه‌های لازم برای تعامل با دستگاه را می‌دهد. برای اطلاعات بیشتر، جفت‌سازی دستگاه همراه را ببینید.

اعلام سرویس در «مانیفست»

سپس، CompanionDeviceService را در فایل مانیفست برنامه‌تان اعلام کنید. مورد زیر را به AndroidManifest.xml خود اضافه کنید:

<manifest ...>
   <application ...>
       <service
           android:name=".MyWearableService"
           android:exported="true"
           android:permission="android.permission.BIND_COMPANION_DEVICE_SERVICE">
           <intent-filter>
               <action android:name="android.companion.CompanionDeviceService" />
           </intent-filter>
       </service>
   </application>
</manifest>

ایجاد CompanionDeviceService

درنهایت، کلاسی ایجاد کنید که CompanionDeviceService را گسترش دهد. این سرویس اتصال به دستگاه پوشیدنی را مدیریت می‌کند و داده‌ها را ازطریق بازخوان‌های GATT بلوتوث کم‌مصرف دریافت می‌کند. وقتی داده‌های جدید دریافت می‌شود، بلافاصله در Health Connect نوشته می‌شود.

private val serviceScope = CoroutineScope(SupervisorJob() + Dispatchers.IO)
private var healthConnectClient: HealthConnectClient? = null
private var bluetoothGatt: BluetoothGatt? = null

override fun onDeviceAppeared(address: String) {
    super.onDeviceAppeared(address)
    healthConnectClient = HealthConnectClient.getOrCreate(this)

    serviceScope.launch {
        val granted = healthConnectClient?.permissionController?.getGrantedPermissions()

        // 1. Check permissions ONCE when the device connects
        if (granted?.contains(HealthPermission.getWritePermission(HeartRateRecord::class)) ?: false) {
            // This is where you'd actually start the Bluetooth connection
            // bluetoothGatt = gattCallback.connect(...)
        }

        // 2. Do your initial database read
        readExerciseSessionAndRoute()
    }
}

private val gattCallback = object : BluetoothGattCallback() {
    override fun onCharacteristicChanged(
        gatt: BluetoothGatt,
        characteristic: BluetoothGattCharacteristic,
        value: ByteArray
    ) {
        super.onCharacteristicChanged(gatt, characteristic, value)

        // 3. ONLY process the incoming data here
        val rawData = value

        serviceScope.launch {
            // parseWearableData(rawData)
            // insertExerciseRoute() or writeToHealthConnect()
        }
    }
}

روال‌های مطلوب برای همگام‌سازی داده‌ها

عوامل زیر بر فرایند همگام‌سازی تأثیر می‌گذارند.

انقضای کد

ازآنجایی‌که نشان تغییرات استفاده‌نشده ظرف ۳۰ روز منقضی می‌شود، باید از استراتژی همگام‌سازی استفاده کنید که در چنین مواردی از ازدست رفتن اطلاعات جلوگیری کند. استراتژی شما می‌تواند شامل رویکردهای زیر باشد:

  • در مخزن داده برنامه خود، جدیدترین سابقه مصرف‌شده‌ای را که id از Health Connect نیز دارد جستجو کنید.
  • سوابقی را از Health Connect درخواست کنید که با مُهر زمان خاصی شروع می‌شوند، و سپس آن‌ها را در مخزن داده برنامه خود درج یا به‌روز کنید.
  • برای رزرو کردن «نشان تغییرات» برای دفعه بعدی که به آن نیاز است، درخواست کنید.

استراتژی‌های مدیریت تغییرات توصیه‌شده

درصورتی‌که برنامه شما نشانه‌های تغییرات نامعتبر یا منقضی دریافت می‌کند، بسته به کاربرد آن در منطق شما، استراتژی‌های مدیریت زیر را توصیه می‌کنیم:

  • خواندن و حذف کردن داده‌های تکراری. این ایده‌آل‌ترین استراتژی است.
    • برچسب زمان آخرین باری که داده‌ها را از Health Connect خوانده است ذخیره می‌شود.
    • پس‌از منقضی شدن رمز، همه داده‌ها را از جدیدترین مُهر زمان یا برای ۳۰ روز گذشته دوباره بخوانید. سپس، آن را با داده‌های قبلاً خوانده‌شده بااستفاده از شناسه‌ها حذف کنید.
    • بهتر است «شناسه‌های کارخواه» را پیاده‌سازی کنید زیرا برای به‌روزرسانی داده‌ها لازم هستند.
  • فقط داده‌های پس‌از مُهر زمان آخرین خواندن را بخواند. این امر منجر به برخی تناقضات داده‌ای در زمان انقضای «نشان تغییرات» می‌شود، اما دوره زمانی کوتاه‌تر است و ممکن است چند ساعت تا چند روز طول بکشد.
    • برچسب زمان آخرین باری که داده‌ها را از Health Connect خوانده است ذخیره می‌شود.
    • پس‌از منقضی شدن رمز، همه داده‌ها از این مُهر زمان به بعد خوانده می‌شود.
  • حذف کردن و سپس خواندن داده‌های ۳۰ روز گذشته. این کار با آنچه در اولین یکپارچه‌سازی اتفاق می‌افتد هم‌راستاتر است.
    • همه داده‌هایی را که برنامه در ۳۰ روز گذشته از Health Connect خوانده است حذف کنید.
    • پس‌از حذف، همه این داده‌ها را دوباره بخوانید.
  • خواندن داده‌های ۳۰ روز گذشته بدون حذف موارد تکراری. این استراتژی کمترین میزان ایده‌آل بودن را دارد و منجر به نمایش داده‌های تکراری به کاربران می‌شود.
    • همه داده‌هایی را که برنامه در ۳۰ روز گذشته از Health Connect خوانده است حذف کنید.
    • اجازه دادن به ورودی‌های تکراری.

نوع داده تغییرات نشانه‌ها

اگر برنامه شما بیش‌از یک نوع داده را به‌طور مستقل مصرف می‌کند، برای هر نوع داده از Tokens جداگانه Changes استفاده کنید. فقط درصورتی از فهرست انواع داده‌های متعدد با Changes Sync API استفاده کنید که این انواع داده یا با هم مصرف شوند یا اصلاً مصرف نشوند.

خواندن پیش‌زمینه

برنامه‌ها فقط زمانی که در پیش‌زمینه هستند می‌توانند داده‌ها را از Health Connect بخوانند. هنگام همگام‌سازی داده‌ها از Health Connect، دسترسی به Health Connect ممکن است در هر زمانی قطع شود. برای مثال، برنامه شما باید درحین همگام‌سازی و خواندن حجم زیادی از داده‌ها از Health Connect، وقفه‌هایی را مدیریت کند و دفعه بعدی که برنامه باز می‌شود، همگام‌سازی را ادامه دهد.

خواندن در پس‌زمینه

می‌توانید درخواست کنید برنامه‌تان در پس‌زمینه اجرا شود و داده‌ها را از Health Connect بخواند. اگر اجازه Background Read را درخواست کنید، کاربرتان می‌تواند به برنامه شما اجازه دهد در پس‌زمینه به داده‌ها دسترسی داشته باشد.

وارد کردن زمان‌بندی‌ها

ازآنجایی‌که برنامه شما نمی‌تواند از داده‌های جدید مطلع شود، داده‌های جدید را در دو نقطه بررسی کنید:

  • هر بار که برنامه شما در پیش‌زمینه فعال می‌شود. در این مورد، از رویدادهای چرخه حیات استفاده کنید.
  • به‌صورت دوره‌ای، درحالی‌که برنامه شما در پیش‌زمینه است. وقتی داده‌های جدید دردسترس قرار می‌گیرد به کاربران اطلاع داده می‌شود و به آن‌ها اجازه داده می‌شود صفحه‌نمایش خود را به‌روز کنند تا تغییرات را منعکس کند.