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

এই নির্দেশিকাটি হেলথ কানেক্ট সংস্করণ 1.1.0-alpha12 এর সাথে সামঞ্জস্যপূর্ণ।

হেলথ কানেক্ট-এর সাথে সংযুক্ত বেশিরভাগ অ্যাপের নিজস্ব ডেটাস্টোর থাকে, যা তথ্যের নির্ভরযোগ্য উৎস হিসেবে কাজ করে। হেলথ কানেক্ট আপনার অ্যাপকে সিঙ্ক করে রাখার বিভিন্ন উপায় প্রদান করে।

আপনার অ্যাপের গঠনের ওপর নির্ভর করে, সিঙ্ক প্রক্রিয়ায় নিম্নলিখিত পদক্ষেপগুলোর কয়েকটি বা সবগুলো অন্তর্ভুক্ত থাকতে পারে:

  • আপনার অ্যাপের ডেটাস্টোর থেকে নতুন বা হালনাগাদ করা ডেটা হেলথ কানেক্ট-এ পাঠান।
  • হেলথ কানেক্ট থেকে ডেটার পরিবর্তনগুলো আপনার অ্যাপের ডেটাস্টোরে নিয়ে আসুন।
  • আপনার অ্যাপের ডেটাস্টোর থেকে ডেটা মুছে ফেলা হলে, হেলথ কানেক্ট থেকেও তা মুছে ফেলুন।

প্রতিটি ক্ষেত্রে, নিশ্চিত করুন যে সিঙ্কিং প্রক্রিয়াটি হেলথ কানেক্ট এবং আপনার অ্যাপের ডেটাস্টোর উভয়কেই সামঞ্জস্যপূর্ণ রাখে।

হেলথ কানেক্ট-এ ডেটা পাঠান

সিঙ্কিং প্রক্রিয়ার প্রথম অংশ হলো আপনার অ্যাপের ডেটাস্টোর থেকে হেলথ কানেক্ট ডেটাস্টোরে ডেটা পাঠানো।

আপনার ডেটা প্রস্তুত করুন

সাধারণত, আপনার অ্যাপের ডেটাস্টোরের রেকর্ডগুলিতে নিম্নলিখিত বিবরণ থাকে:

  • একটি অনন্য কী, যেমন একটি UUID
  • একটি সংস্করণ বা সময়চিহ্ন।

হেলথ কানেক্ট-এ ডেটা সিঙ্ক করার সময়, শেষ সিঙ্কের পর থেকে যে ডেটা যোগ করা, আপডেট করা বা মুছে ফেলা হয়েছে, শুধু সেই ডেটাগুলোই শনাক্ত করে সরবরাহ করুন।

হেলথ কানেক্ট-এ ডেটা লিখুন

হেলথ কানেক্ট-এ ডেটা প্রবেশ করাতে, নিম্নলিখিত ধাপগুলি অনুসরণ করুন:

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

    healthConnectClient.insertRecords(arrayListOf(record))

ডেটা ফিড করার ব্যবহারিক দিকগুলো সম্পর্কে জানতে, 'রাইট ডেটা' (Write data) -এর সেরা অনুশীলনগুলো দেখুন।

স্টোর হেলথ কানেক্ট আইডি

আপনার অ্যাপ যদি হেলথ কানেক্ট থেকেও ডেটা পড়ে, তাহলে রেকর্ড আপসার্ট করার পর সেগুলোর হেলথ কানেক্ট id সংরক্ষণ করুন। হেলথ কানেক্ট থেকে ডেটার পরিবর্তনগুলো নেওয়ার সময় ডিলিট প্রক্রিয়া সম্পন্ন করতে আপনার এই id প্রয়োজন হবে।

insertRecords ফাংশনটি একটি InsertRecordsResponse রিটার্ন করে, যাতে id ভ্যালুগুলোর একটি তালিকা থাকে। এই রেসপন্সটি ব্যবহার করে Record ID-গুলো সংগ্রহ করুন এবং সংরক্ষণ করুন।

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

হেলথ কানেক্ট থেকে ডেটা সংগ্রহ করুন

সিঙ্কিং প্রক্রিয়ার দ্বিতীয় অংশ হলো হেলথ কানেক্ট থেকে আপনার অ্যাপের ডেটাস্টোরে ডেটার যেকোনো পরিবর্তন নিয়ে আসা। এই ডেটা পরিবর্তনগুলোর মধ্যে আপডেট এবং ডিলিট অন্তর্ভুক্ত থাকতে পারে।

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

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

একটি Changes টোকেন পেতে, getChangesToken কল করুন এবং প্রয়োজনীয় ডেটা টাইপগুলো সরবরাহ করুন।

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

ডেটা পরিবর্তনের জন্য পরীক্ষা করুন

এখন যেহেতু আপনি একটি Changes টোকেন পেয়েছেন, সেটি ব্যবহার করে সমস্ত Changes সংগ্রহ করুন। আমরা একটি লুপ তৈরি করার পরামর্শ দিচ্ছি, যা সমস্ত Changes-এর মধ্যে দিয়ে গিয়ে পরীক্ষা করবে যে কোনো ডেটা পরিবর্তন উপলব্ধ আছে কিনা। নিচের ধাপগুলো অনুসরণ করুন:

  1. পরিবর্তনসমূহের তালিকা পেতে টোকেনটি ব্যবহার করে getChanges কল করুন।
  2. প্রতিটি পরিবর্তন UpsertionChange নাকি DeletionChange , তা যাচাই করুন এবং প্রয়োজনীয় কার্যক্রম সম্পাদন করুন।
    • UpsertionChange এর ক্ষেত্রে, শুধুমাত্র সেই পরিবর্তনগুলো গ্রহণ করুন যেগুলো কলিং অ্যাপ থেকে আসেনি, যাতে আপনি ডেটা পুনরায় ইম্পোর্ট না করেন।
  3. পরবর্তী Changes টোকেনটিকে আপনার নতুন টোকেন হিসেবে নির্ধারণ করুন।
  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 ব্যবহার করুন। এর জন্য প্রয়োজন যে আপনি Store Health Connect IDs- এ উল্লিখিত অনুযায়ী রেকর্ড id সংরক্ষণ করেছেন।

হেলথ কানেক্ট থেকে ডেটা মুছে ফেলুন

যখন কোনো ব্যবহারকারী আপনার অ্যাপ থেকে নিজের ডেটা মুছে ফেলেন, তখন নিশ্চিত করুন যেন হেলথ কানেক্ট থেকেও ডেটাটি মুছে যায় । এটি করার জন্য deleteRecords ব্যবহার করুন। এটি একটি রেকর্ড টাইপ এবং idclientRecordId ভ্যালুর একটি তালিকা গ্রহণ করে, যা একসাথে একাধিক ডেটা মুছে ফেলার জন্য সুবিধাজনক। একটি বিকল্প deleteRecords রয়েছে যা একটি timeRangeFilter গ্রহণ করে।

পরিধানযোগ্য ডিভাইস থেকে স্বল্প-বিলম্বের সিঙ্ক্রোনাইজেশন

কম ল্যাটেন্সিতে একটি পরিধানযোগ্য ফিটনেস ডিভাইস থেকে হেলথ কানেক্ট-এ ডেটা সিঙ্ক করতে, CompanionDeviceService ব্যবহার করুন। এই পদ্ধতিটি সেইসব ডিভাইসের জন্য কাজ করে যেগুলো BLE GATT নোটিফিকেশন বা ইন্ডিকেশন সমর্থন করে এবং অ্যান্ড্রয়েড ৮.০ (API লেভেল ২৬) বা তার উচ্চতর সংস্করণকে টার্গেট করে। CompanionDeviceService আপনার অ্যাপকে পরিধানযোগ্য ডিভাইস থেকে ডেটা গ্রহণ করতে এবং হেলথ কানেক্ট-এ তা লিখতে সাহায্য করে, এমনকি যখন অ্যাপটি চালু না-ও থাকে। BLE-এর সেরা অনুশীলন সম্পর্কে আরও বিস্তারিত জানতে, ব্লুটুথ লো এনার্জি ওভারভিউ দেখুন।

ডিভাইসটি সংযুক্ত করুন

প্রথমে, আপনার অ্যাপকে অবশ্যই CompanionDeviceManager ব্যবহার করে পরিধানযোগ্য ডিভাইসটিকে আপনার অ্যাপের সাথে যুক্ত করার জন্য ব্যবহারকারীকে একটি এককালীন প্রক্রিয়ার মাধ্যমে নির্দেশনা দিতে হবে। এটি আপনার অ্যাপকে ডিভাইসটির সাথে ইন্টারঅ্যাক্ট করার জন্য প্রয়োজনীয় অনুমতি প্রদান করে। আরও তথ্যের জন্য, Companion ডিভাইস পেয়ারিং দেখুন।

ম্যানিফেস্টে পরিষেবাটি ঘোষণা করুন

এরপর, আপনার অ্যাপের ম্যানিফেস্ট ফাইলে 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 এক্সটেন্ড করে এমন একটি ক্লাস তৈরি করুন। এই সার্ভিসটি ওয়্যারেবল ডিভাইসের সাথে সংযোগ স্থাপন করে এবং BLE GATT কলব্যাকের মাধ্যমে ডেটা গ্রহণ করে। নতুন ডেটা পাওয়া গেলে, তা সাথে সাথে হেলথ কানেক্ট-এ লিখে দেওয়া হয়।

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 টোকেন ৩০ দিনের মধ্যে মেয়াদোত্তীর্ণ হয়ে যায়, তাই আপনাকে এমন একটি সিঙ্ক কৌশল ব্যবহার করতে হবে যা এই ধরনের ক্ষেত্রে তথ্য হারানোর ঝুঁকি এড়ায়। আপনার কৌশলে নিম্নলিখিত পদ্ধতিগুলো অন্তর্ভুক্ত থাকতে পারে:

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

প্রস্তাবিত পরিবর্তন ব্যবস্থাপনা কৌশল

যদি আপনার অ্যাপে অবৈধ বা মেয়াদোত্তীর্ণ Changes টোকেন আসে, তবে আপনার লজিকে এর প্রয়োগের উপর নির্ভর করে আমরা নিম্নলিখিত ব্যবস্থাপনা কৌশলগুলো সুপারিশ করি:

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

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

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

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

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

পটভূমি পাঠ

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

আমদানির সময়সূচী

যেহেতু আপনার অ্যাপ নতুন ডেটার বিজ্ঞপ্তি পেতে পারে না, তাই দুটি পর্যায়ে নতুন ডেটা পরীক্ষা করুন:

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