ডেটা সিঙ্ক্রোনাইজ করা

এই গাইড Health Connect ভার্সন ১.১.০-alpha১২ বা তার পরবর্তী ভার্সনের সাথে মানানসই।

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. প্রতিটি Record-এর সাথে একটি Metadata অবজেক্ট নির্দিষ্ট করুন। এর মধ্যে 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-এ আগে থেকে থাকা যেকোনও ডেটা ওভাররাইট করা হয়, যতক্ষণ না Health Connect ডেটাস্টোরে clientRecordId ভ্যালু থাকে এবং 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 থেকে আপনার অ্যাপের ডেটাস্টোরে ডেটার যেকোনও পরিবর্তন পুল করা। ডেটা পরিবর্তনের মধ্যে আপডেট ও মুছে ফেলা অন্তর্ভুক্ত থাকতে পারে।

পরিবর্তন টোকেন পান

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 (API লেভেল 26) বা তার পরবর্তী ভার্সনকে টার্গেট করে এমন ডিভাইসের জন্য কাজ করে। 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()
        }
    }
}

ডেটা সিঙ্ক করার পেশাদার পদ্ধতি

নিম্নলিখিত বিষয়গুলি সিঙ্ক করার প্রসেসকে প্রভাবিত করে।

টোকেনের মেয়াদ শেষ হওয়া

যেহেতু অব্যবহৃত Changes টোকেন ৩০ দিনের মধ্যে শেষ হয়ে যায়, তাই আপনাকে অবশ্যই এমন একটি সিঙ্ক কৌশল ব্যবহার করতে হবে যা এই ধরনের ক্ষেত্রে তথ্য হারানো এড়ায়। আপনার কৌশলে নিম্নলিখিত পদ্ধতি অন্তর্ভুক্ত থাকতে পারে:

  • আপনার অ্যাপ ডেটাস্টোরে সবচেয়ে সম্প্রতি ব্যবহার করা রেকর্ড খুঁজুন, যেটিতে Health Connect থেকে পাওয়া id-ও আছে।
  • Health Connect থেকে নির্দিষ্ট টাইমস্ট্যাম্প দিয়ে শুরু হওয়া রেকর্ড অনুরোধ করুন এবং তারপর আপনার অ্যাপের ডেটাস্টোরে সেগুলি যোগ বা আপডেট করুন।
  • পরের বার প্রয়োজন হলে ব্যবহার করার জন্য Changes টোকেন রিজার্ভ করার অনুরোধ করুন।

সাজেস্ট করা পরিবর্তন ম্যানেজমেন্ট স্ট্র্যাটেজি

আপনার অ্যাপ যদি ভুল বা মেয়াদ শেষ হয়ে যাওয়া পরিবর্তন টোকেন পায়, তাহলে আপনার লজিকে এর প্রয়োগের উপর নির্ভর করে আমরা নিম্নলিখিত ম্যানেজমেন্ট স্ট্র্যাটেজি সাজেস্ট করি:

  • সব ডেটা পড়া ও ডুপ্লিকেট ডেটা মুছে ফেলা। এটিই সবচেয়ে আদর্শ স্ট্র্যাটেজি।
    • Health Connect থেকে শেষবার ডেটা পড়ার টাইমস্ট্যাম্প স্টোর করা।
    • টোকেনের মেয়াদ শেষ হয়ে গেলে, সবচেয়ে সাম্প্রতিক টাইমস্ট্যাম্প বা গত ৩০ দিনের সব ডেটা আবার পড়ুন। তারপর, শনাক্তকারী ব্যবহার করে আগে পড়া ডেটার সাথে এটি ডিডুপ করুন।
    • ডেটা আপডেট করার জন্য ক্লায়েন্ট আইডি প্রয়োজন, তাই ক্লায়েন্ট আইডি প্রয়োগ করলে ভালো হয়।
  • শেষবার পড়ার টাইমস্ট্যাম্পের পর থেকে শুধু ডেটা পড়া। এর ফলে, পরিবর্তন টোকেনের মেয়াদ শেষ হওয়ার সময় ডেটায় কিছু অসঙ্গতি দেখা যায়, তবে এই সময়সীমা খুবই কম, কয়েক ঘণ্টা থেকে কয়েক দিন পর্যন্ত হতে পারে।
    • Health Connect থেকে শেষবার ডেটা পড়ার টাইমস্ট্যাম্প স্টোর করা।
    • টোকেনের মেয়াদ শেষ হয়ে গেলে, এই টাইমস্ট্যাম্প থেকে শুরু করে সব ডেটা পড়ুন।
  • তারপর শেষ ৩০ দিনের রিডার ডেটা মুছে দিন। এটি প্রথম ইন্টিগ্রেশনের সময় যা ঘটে তার সাথে আরও ঘনিষ্ঠভাবে মেলে।
    • গত ৩০ দিনে Health Connect থেকে অ্যাপের রিড করা সব ডেটা মুছে দিন।
    • মুছে দেওয়ার পরে, এই সব ডেটা আবার পড়ুন।
  • ডুপ্লিকেট না সরিয়ে শেষ ৩০ দিনের ডেটা পড়ুন। এটি সবচেয়ে কম আদর্শ কৌশল এবং এর ফলে ব্যবহারকারীদের ডুপ্লিকেট ডেটা দেখানো হয়।
    • গত ৩০ দিনে Health Connect থেকে অ্যাপের রিড করা সব ডেটা মুছে দিন।
    • ডুপ্লিকেট এন্ট্রির অনুমতি দিন।

ডেটার ধরন পরিবর্তন সংক্রান্ত টোকেন

আপনার অ্যাপ যদি একাধিক ডেটার ধরন স্বাধীনভাবে ব্যবহার করে, তাহলে প্রতিটি ডেটার ধরনের জন্য আলাদা আলাদা Changes টোকেন ব্যবহার করুন। Changes Sync API-এর সাথে একাধিক ডেটা টাইপের তালিকা তখনই ব্যবহার করুন যদি এই ডেটা টাইপগুলি একসাথে ব্যবহার করা হয় বা একেবারেই ব্যবহার করা না হয়।

ফোরগ্রাউন্ড রিড

অ্যাপগুলি শুধুমাত্র ফোরগ্রাউন্ডে থাকাকালীন Health Connect থেকে ডেটা পড়তে পারে। Health Connect থেকে ডেটা সিঙ্ক করার সময়, Health Connect-এ অ্যাক্সেস যেকোনও সময় বাধাগ্রস্ত হতে পারে। যেমন, Health Connect থেকে প্রচুর পরিমাণে ডেটা পড়ার সময় সিঙ্ক করার মাঝপথে কোনও বাধা এলে আপনার অ্যাপকে তা ম্যানেজ করতে হবে এবং পরের বার অ্যাপ খোলার সময় তা চালিয়ে যেতে হবে।

ব্যাকগ্রাউন্ড রিডিং

আপনি ব্যাকগ্রাউন্ডে অ্যাপ্লিকেশন চালানোর এবং Health Connect থেকে ডেটা পড়ার অনুরোধ করতে পারেন। আপনি Background Read অনুমতির জন্য অনুরোধ করলে, আপনার ব্যবহারকারী ব্যাকগ্রাউন্ডে ডেটা পড়ার জন্য আপনার অ্যাপকে অ্যাক্সেস দিতে পারবেন।

ইমপোর্ট করার সময়

আপনার অ্যাপ নতুন ডেটার বিজ্ঞপ্তি পেতে পারে না বলে, দুটি পয়েন্টে নতুন ডেটা চেক করুন:

  • প্রতিবার আপনার অ্যাপ ফোরগ্রাউন্ডে অ্যাক্টিভ হয়ে যায়। এই ক্ষেত্রে, লাইফসাইকেল ইভেন্ট ব্যবহার করুন।
  • আপনার অ্যাপ ফোরগ্রাউন্ডে থাকাকালীন, নির্দিষ্ট সময় অন্তর। নতুন ডেটা উপলভ্য হলে ব্যবহারকারীদের বিজ্ঞপ্তি দিন, যাতে তারা পরিবর্তনগুলি প্রতিফলিত করার জন্য তাদের স্ক্রিন আপডেট করতে পারে।