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

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

    healthConnectClient.insertRecords(arrayListOf(record))

ডেটা ইনপুট করার সময় যেসব বিষয় বিবেচনা করতে হবে, সেই সম্পর্কে জানতে, ডেটা লেখার পেশাদার পদ্ধতি দেখুন।

Health Connect আইডি সেভ করা

আপনার অ্যাপ Health Connect থেকে ডেটা রিড করলে, Health Connect id আপসার্ট করার পরে রেকর্ড স্টোর করুন। Health Connect থেকে ডেটা পরিবর্তন পুল করার সময় মুছে দেওয়ার প্রসেস সম্পূর্ণ করতে আপনার এই id প্রয়োজন।

insertRecords ফাংশন একটি InsertRecordsResponse রিটার্ন করে যার মধ্যে id ভ্যালুর তালিকা থাকে। Record 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-এর জন্য, এর metadata থেকে রেকর্ড আপসার্ট করতে id এবং lastModifiedTime ব্যবহার করুন। DeletionChange-এর জন্য, রেকর্ড মুছে দিতে id ব্যবহার করুন। এর জন্য, আপনাকে id রেকর্ড সেভ করতে হবে, যেমনটি Health Connect আইডি সেভ করুন নিবন্ধে উল্লেখ করা হয়েছে।

Health Connect থেকে ডেটা মুছে দেওয়া

কোনও ব্যবহারকারী আপনার অ্যাপ থেকে নিজের ডেটা মুছে দিলে, Health Connect থেকেও সেই ডেটা সরানো হয়েছে কিনা তা নিশ্চিত করুন। এটি করতে deleteRecords ব্যবহার করুন। এটি একটি রেকর্ড টাইপ এবং id ও clientRecordId ভ্যালুর তালিকা নেয়, যার ফলে একসাথে একাধিক ডেটা মোছা সহজ হয়। timeRangeFilter ইনপুট নেয় এমন একটি deleteRecords বিকল্পও উপলভ্য।

ওয়্যারেবল থেকে কম লেটেন্সি সহ সিঙ্ক্রোনাইজেশন

কম লেটেন্সি সহ পরে থাকা যায় এমন ফিটনেস ডিভাইস থেকে 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()
        }
    }
}

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

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

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

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

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

পরিবর্তন ম্যানেজমেন্টের কৌশল সংক্রান্ত সাজেশন

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

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

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

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

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

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

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

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

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

আপনার অ্যাপ নতুন ডেটা সম্পর্কে বিজ্ঞপ্তি না পাওয়ার কারণে, দুটি জায়গায় নতুন ডেটা চেক করুন:

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