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

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

اکثر برنامه‌هایی که با 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. درج/ به‌روزرسانی داده‌ها در Health Connect بااستفاده از insertRecords. به‌روزرسانی داده‌ها به این معنی است که هر داده موجودی در Health Connect تا زمانی که مقادیر clientRecordId در پایگاه داده Health Connect وجود داشته باشد و clientRecordVersion بالاتر از مقدار موجود باشد، رونویسی می‌شود. درغیراین‌صورت، داده‌های به‌روزرسانی‌شده به‌عنوان داده‌های جدید نوشته می‌شود.

    healthConnectClient.insertRecords(arrayListOf(record))

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

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

اگر برنامه‌تان داده‌ها را از Health Connect نیز می‌خواند، Health Connect id را برای سوابق پس‌از به‌روزرسانی آن‌ها ذخیره کنید. وقتی تغییرات داده‌ها را از 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 به پایگاه داده برنامه شما است. تغییرات داده‌ها می‌تواند شامل به‌روزرسانی و حذف باشد.

دریافت کد Changes

برای دریافت فهرست تغییرات برای استخراج از 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 استفاده کنید. این رویکرد برای دستگاه‌هایی کار می‌کند که از «اعلان‌ها» یا «نشانه‌های» BLE GATT پشتیبانی می‌کنند و Android 8.0 (سطح میانای برنامه‌سازی کاربردی ۲۶) یا بالاتر را هدف قرار می‌دهند. CompanionDeviceService به برنامه شما اجازه می‌دهد داده‌ها را از پوشیدنی‌ها دریافت کند و آن‌ها را در Health Connect بنویسد، حتی وقتی برنامه درحال اجرا نباشد. برای جزئیات بیشتر درباره روال‌های مطلوب BLE، به نمای کلی بلوتوث کم‌مصرف مراجعه کنید.

مرتبط کردن دستگاه

ابتدا، برنامه‌تان باید کاربر را در فرایندی یک‌باره راهنمایی کند تا پوشیدنی را بااستفاده از 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 را گسترش دهد. این سرویس اتصال به دستگاه پوشیدنی را مدیریت می‌کند و داده‌ها را ازطریق فراخوان‌های BLE 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 را برای ۳۰ روز گذشته حذف کنید.
    • ورودی‌های تکراری مجاز است.

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

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

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

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

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

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

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

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

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