স্বাস্থ্য পরিষেবা
ExerciseClient-এর মাধ্যমে ওয়ার্কআউট অ্যাপের জন্য সহায়তা প্রদান করে।
ExerciseClient-এর মাধ্যমে, আপনার অ্যাপ, কোনও এক্সারসাইজ প্রোগ্রেসে থাকলে তা কন্ট্রোল করতে, এক্সারসাইজের লক্ষ্য যোগ করতে এবং এক্সারসাইজের অবস্থা, এক্সারসাইজ ইভেন্ট বা অন্যান্য মেট্রিক সম্পর্কে আপডেট পেতে পারে। আরও তথ্যের জন্য, Health Services-এ কাজ করে এমন
ব্যায়ামের ধরন
সম্পর্কিত সম্পূর্ণ তালিকা দেখুন।
GitHub-এ ব্যায়ামের স্যাম্পেল দেখুন।
ডিপেন্ডেন্সি যোগ করুন
স্বাস্থ্য পরিষেবার উপর নির্ভরতা যোগ করতে, আপনার প্রোজেক্টে Google Maven রিপোজিটরি যোগ করতে হবে। আরও তথ্যের জন্য, Google-এর Maven রিপোজিটরি দেখুন।
তারপর, আপনার মডিউল-লেভেল build.gradle ফাইলে, নিম্নলিখিত ডিপেন্ডেন্সি যোগ করুন:
গ্রোভি
dependencies { implementation "androidx.health:health-services-client:1.1.0" }
কোটলিন
dependencies { implementation("androidx.health:health-services-client:1.1.0") }
অ্যাপের স্ট্রাকচার
স্বাস্থ্য পরিষেবা ব্যবহার করে কোনও এক্সারসাইজ অ্যাপ তৈরি করার সময় নিম্নলিখিত অ্যাপ স্ট্রাকচার ব্যবহার করুন:
- আপনার স্ক্রিন ও নেভিগেশন মূল অ্যাক্টিভিটির মধ্যে রাখুন।
- ফোরগ্রাউন্ড সার্ভিস-এর মাধ্যমে ওয়ার্কআউট স্ট্যাটাস, সেন্সর ডেটা, অনগোইং অ্যাক্টিভিটি ও ডেটা ম্যানেজ করুন।
- Room-এর মাধ্যমে ডেটা স্টোর করুন এবং ডেটা আপলোড করতে WorkManager ব্যবহার করুন।
ওয়ার্ক-আউটের জন্য প্রস্তুতি নেওয়ার সময় এবং ওয়ার্ক-আউট চলাকালীন, বিভিন্ন কারণে আপনার অ্যাক্টিভিটি
বন্ধ হয়ে যেতে পারে। ব্যবহারকারী অন্য অ্যাপে সুইচ করতে পারেন
অথবা ওয়াচফেসে ফিরে যেতে পারেন। সিস্টেম আপনার অ্যাক্টিভিটির উপরে কিছু দেখাতে পারে অথবা
কিছুক্ষণ কোনও অ্যাক্টিভিটি না থাকলে স্ক্রিন বন্ধ হয়ে যেতে পারে।
পুরো ওয়ার্ক-আউট সেশন জুড়ে সঠিক অপারেশন নিশ্চিত করতে ExerciseClient-এর সাথে
একটানা চলা ForegroundService
ব্যবহার করুন।
ForegroundService ব্যবহার করলে, আপনি
অনগোইং অ্যাক্টিভিটি API ব্যবহার করে
আপনার ওয়াচ সারফেসে একটি ইন্ডিকেটর দেখাতে পারবেন, যার সাহায্যে ব্যবহারকারী দ্রুত
ওয়ার্কআউটে ফিরে যেতে পারবেন।
আপনার ফোরগ্রাউন্ড সার্ভিসে লোকেশন ডেটার জন্য যথাযথভাবে অনুরোধ করা প্রয়োজন। আপনার ম্যানিফেস্ট ফাইলে, প্রয়োজনীয় ফোরগ্রাউন্ড পরিষেবার ধরন এবং অনুমতি উল্লেখ করুন:
<manifest ...> <uses-permission android:name="android.permission.FOREGROUND_SERVICE" /> <application ...> <!-- If your app is designed only for devices that run Wear OS 4 or lower, use android:foregroundServiceType="location" instead. --> <service android:name=".MyExerciseSessionRecorder" android:foregroundServiceType="health|location"> </service> </application> </manifest>
আপনার ওয়ার্ক-আউট অ্যাক্টিভিটির জন্য
AmbientLifecycleObserver
ব্যবহার করুন, যার মধ্যে prepareExercise() কল এবং
আপনার ওয়ার্ক-আউট অ্যাক্টিভিটি অন্তর্ভুক্ত। তবে, অ্যাম্বিয়েন্ট মোডে ওয়ার্কআউট চলাকালীন ডিসপ্লে আপডেট করবেন না: কারণ, ডিভাইস স্ক্রিন অ্যাম্বিয়েন্ট মোডে থাকলে, পাওয়ার সাশ্রয় করতে, স্বাস্থ্য পরিষেবা ওয়ার্কআউট ডেটা ব্যাচ করে,
তাই ডিসপ্লে করা তথ্য সাম্প্রতিক নাও হতে পারে। ওয়ার্কআউট চলাকালীন, ব্যবহারকারীর কাছে অর্থপূর্ণ ডেটা দেখান, আপ-টু-ডেট তথ্য বা ফাঁকা স্ক্রিন দেখান।
ক্ষমতা চেক করুন
প্রতিটি ExerciseType মেট্রিক এবং ব্যায়ামের লক্ষ্যের জন্য নির্দিষ্ট ডেটার ধরনকে সমর্থন করে।
স্টার্টআপে এই ক্ষমতাগুলি পরীক্ষা করুন, কারণ এগুলি ডিভাইসের উপর নির্ভর করে পরিবর্তিত হতে পারে। কোনও ডিভাইসে নির্দিষ্ট কোনও ধরনের এক্সারসাইজ কাজ নাও করতে পারে অথবা
অটো-পজের মতো নির্দিষ্ট কোনও ফাংশন কাজ নাও করতে পারে। এছাড়াও, সময়ের সাথে সাথে ডিভাইসের ক্ষমতা পরিবর্তিত হতে পারে, যেমন সফ্টওয়্যার আপডেটের পরে।
অ্যাপ চালু করার সময়, ডিভাইসের ক্ষমতা সম্পর্কে কোয়েরি করুন এবং নিম্নলিখিতগুলি স্টোর ও প্রসেস করুন:
- প্ল্যাটফর্মে কাজ করে এমন এক্সারসাইজ।
- প্রতিটি ব্যায়ামের জন্য কাজ করে এমন ফিচার।
- প্রতিটি ব্যায়ামের জন্য কাজ করে এমন ডেটার ধরন।
- এই ধরনের প্রতিটি ডেটার জন্য প্রয়োজনীয় অনুমতি।
আপনি কী ধরনের মেট্রিকের জন্য অনুরোধ করতে পারেন, কী ধরনের ব্যায়ামের লক্ষ্য কনফিগার করতে পারেন এবং সেই ধরনের জন্য অন্য কী কী ফিচার উপলভ্য আছে তা দেখতে, আপনার বেছে নেওয়া ব্যায়ামের ধরনের সাথে ExerciseCapabilities.getExerciseTypeCapabilities() ব্যবহার করুন। এটি নিম্নলিখিত উদাহরণে দেখানো হয়েছে:
val healthClient = HealthServices.getClient(this /*context*/)
val exerciseClient = healthClient.exerciseClient
lifecycleScope.launch {
val capabilities = exerciseClient.getCapabilitiesAsync().await()
if (ExerciseType.RUNNING in capabilities.supportedExerciseTypes) {
runningCapabilities =
capabilities.getExerciseTypeCapabilities(ExerciseType.RUNNING)
}
}
ফেরত পাঠানো ExerciseTypeCapabilities-এর মধ্যে,
supportedDataTypes
আপনি যেসব ডেটার ধরন অনুরোধ করতে পারবেন তার তালিকা দেওয়া আছে। এটি ডিভাইস অনুযায়ী আলাদা হয়, তাই
এমন DataType-এর জন্য অনুরোধ করবেন না যা কাজ করে না, অথবা আপনার অনুরোধ
ব্যর্থ হতে পারে।
আপনি যে ব্যায়ামের লক্ষ্য তৈরি করতে চান, ব্যায়ামটি সেই লক্ষ্য পূরণ করতে পারবে কিনা তা নির্ধারণ করতে
supportedGoals
এবং
supportedMilestones
ফিল্ড ব্যবহার করুন।
আপনার অ্যাপ ব্যবহারকারীকে অটো-পজ ব্যবহার করার অনুমতি দিলে, আপনাকে অবশ্যই চেক করতে হবে যে এই কার্যকারিতাটি supportsAutoPauseAndResume ব্যবহার করে
ডিভাইস দ্বারা সমর্থিত কিনা।
ExerciseClient ডিভাইসে কাজ করে না এমন অনুরোধ বাতিল করে দেয়।
নিম্নলিখিত উদাহরণটি HEART_RATE_BPM ডেটার ধরন,
STEPS_TOTAL লক্ষ্যের ক্ষমতা এবং অটোমেটিক পজ করার কার্যকারিতার জন্য সহায়তা চেক করে:
// Whether we can request heart rate metrics.
supportsHeartRate = DataType.HEART_RATE_BPM in runningCapabilities.supportedDataTypes
// Whether we can make a one-time goal for aggregate steps.
val stepGoals = runningCapabilities.supportedGoals[DataType.STEPS_TOTAL]
supportsStepGoals =
(stepGoals != null && ComparisonType.GREATER_THAN_OR_EQUAL in stepGoals)
// Whether auto-pause is supported.
val supportsAutoPause = runningCapabilities.supportsAutoPauseAndResume
ব্যায়ামের স্ট্যাটাস সংক্রান্ত আপডেট পেতে রেজিস্টার করুন
শ্রোতাকে এক্সারসাইজ সংক্রান্ত আপডেট ডেলিভার করা হয়। আপনার অ্যাপ একবারে শুধুমাত্র একজন শ্রোতাকে রেজিস্টার করতে পারে। ওয়ার্কআউট শুরু করার আগে আপনার লিসেনার সেট-আপ করুন, যেমনটি নিম্নলিখিত উদাহরণে দেখানো হয়েছে। আপনার অ্যাপের মালিকানাধীন এক্সারসাইজ সম্পর্কেই শুধু আপনার লিসেনার আপডেট পায়।
val callback = object : ExerciseUpdateCallback {
override fun onExerciseUpdateReceived(update: ExerciseUpdate) {
val exerciseStateInfo = update.exerciseStateInfo
val activeDuration = update.activeDurationCheckpoint
val latestMetrics = update.latestMetrics
val latestGoals = update.latestAchievedGoals
}
override fun onLapSummaryReceived(lapSummary: ExerciseLapSummary) {
// For ExerciseTypes that support laps, this is called when a lap is marked.
}
override fun onAvailabilityChanged(
dataType: DataType<*, *>,
availability: Availability
) {
// Called when the availability of a particular DataType changes.
when {
availability is LocationAvailability -> // Relates to Location/GPS.
availability is DataTypeAvailability -> // Relates to another DataType.
}
}
}
exerciseClient.setUpdateCallback(callback)
ব্যায়ামের লাইফটাইম ম্যানেজ করুন
Health Services, ডিভাইসের সব অ্যাপ জুড়ে, একবারে সর্বাধিক একটি এক্সারসাইজ সাপোর্ট করে। কোনও ব্যায়াম ট্র্যাক করা হলে এবং অন্য কোনও অ্যাপ নতুন ব্যায়াম ট্র্যাক করা শুরু করলে, প্রথম ব্যায়ামটি বন্ধ হয়ে যায়।
ব্যায়াম শুরু করার আগে, নিম্নলিখিত কাজগুলি করুন:
- কোনও ব্যায়াম আগে থেকেই ট্র্যাক করা হচ্ছে কিনা তা চেক করুন, এবং সেই অনুযায়ী প্রতিক্রিয়া জানান। যেমন, আগের কোনও এক্সারসাইজ ওভাররাইড করে নতুন কোনও এক্সারসাইজ ট্র্যাক করা শুরু করার আগে ব্যবহারকারীর থেকে কনফার্মেশন নিন।
getCurrentExerciseInfoAsync-এর মাধ্যমে আগে থেকে থাকা কোনও এক্সারসাইজ কীভাবে চেক করতে হয় তা নিম্নলিখিত উদাহরণ থেকে দেখুন:
lifecycleScope.launch {
val exerciseInfo = exerciseClient.getCurrentExerciseInfoAsync().await()
when (exerciseInfo.exerciseTrackedStatus) {
OTHER_APP_IN_PROGRESS -> // Warn user before continuing, will stop the existing workout.
OWNED_EXERCISE_IN_PROGRESS -> // This app has an existing workout.
NO_EXERCISE_IN_PROGRESS -> // Start a fresh workout.
}
}
অনুমতি
ExerciseClient ব্যবহার করার সময়, আপনার অ্যাপ যাতে প্রয়োজনীয় অনুমতির জন্য অনুরোধ করে এবং তা বজায় রাখে, তা নিশ্চিত করুন।
আপনার অ্যাপ LOCATION ডেটা ব্যবহার করলে, আপনার অ্যাপ যাতে সেই ডেটার জন্য উপযুক্ত অনুমতির অনুরোধ করে এবং তা বজায় রাখে তা নিশ্চিত করুন।
সব ধরনের ডেটার জন্য, prepareExercise() বা startExercise() কল করার আগে,
নিম্নলিখিত ধাপগুলি অনুসরণ করুন:
- আপনার
AndroidManifest.xmlফাইলে অনুরোধ করা ডেটা টাইপের জন্য উপযুক্ত অনুমতি নির্দিষ্ট করুন। - ব্যবহারকারী প্রয়োজনীয় অনুমতি দিয়েছেন কিনা তা যাচাই করুন। আরও তথ্যের জন্য, অ্যাপকে দেওয়া অনুমতি সংক্রান্ত অনুরোধ দেখুন। প্রয়োজনীয় অনুমতি আগে থেকে দেওয়া না থাকলে, স্বাস্থ্য পরিষেবা অনুরোধ বাতিল করে দেয়।
লোকেশন ডেটার জন্য, নিম্নলিখিত অতিরিক্ত ধাপগুলি অনুসরণ করুন:
isProviderEnabled(LocationManager.GPS_PROVIDER)ব্যবহার করে ডিভাইসে জিপিএস চালু করা আছে কিনা তা চেক করুন। প্রয়োজন হলে, ব্যবহারকারীকে লোকেশন সেটিংস খোলার জন্য প্রম্পট করুন।- ওয়ার্ক-আউট চলাকালীন উপযুক্ত
foregroundServiceTypeসহForegroundServiceবজায় রাখা হয়েছে কিনা তা নিশ্চিত করুন।
ওয়ার্ক-আউটের জন্য প্রস্তুতি নিন
জিপিএস বা হার্ট রেটের মতো কিছু সেন্সর চালু হতে কিছুটা সময় লাগতে পারে অথবা
ব্যবহারকারী ওয়ার্ক-আউট শুরু করার আগে তার ডেটা দেখতে চাইতে পারেন। ঐচ্ছিক
prepareExerciseAsync()
পদ্ধতিটি এইসব সেন্সরকে ওয়ার্ম আপ করতে এবং ওয়ার্কআউটের জন্য টাইমার শুরু না করেই
ডেটা গ্রহণ করতে দেয়। এই প্রস্তুতির সময় activeDuration-এর উপর কোনও প্রভাব ফেলে না।
prepareExerciseAsync()-এ কল করার আগে, নিম্নলিখিত বিষয়গুলি চেক করুন:
প্ল্যাটফর্ম-জুড়ে লোকেশন সেটিং চেক করুন। ব্যবহারকারী মূল সেটিংস মেনু থেকে এই সেটিং নিয়ন্ত্রণ করেন; এটি অ্যাপ-লেভেল অনুমতি চেক করার থেকে আলাদা।
সেটিং বন্ধ থাকলে, ব্যবহারকারীকে জানান যে তিনি লোকেশন অ্যাক্সেস করার অনুমতি দেননি এবং আপনার অ্যাপের জন্য লোকেশন প্রয়োজন হলে তাকে এটি চালু করতে প্রম্পট করুন।
আপনার অ্যাপে বডি সেন্সর (API লেভেল ৩৫ বা তার কম) বা হার্ট রেট (API লেভেল ৩৬+), অ্যাক্টিভিটি শনাক্তকরণ এবং সঠিক লোকেশনের জন্য রানটাইম অনুমতি আছে কিনা তা কনফার্ম করুন। অনুমতি না থাকলে, রানটাইম অনুমতির জন্য ব্যবহারকারীকে প্রম্পট করুন, যাতে পর্যাপ্ত প্রসঙ্গ প্রদান করা যায়। ব্যবহারকারী নির্দিষ্ট কোনও অনুমতি না দিলে,
prepareExerciseAsync()-এ কল থেকে সেই অনুমতির সাথে সম্পর্কিত ডেটার ধরন সরিয়ে দিন। বডি সেন্সর (API লেভেল ৩৬+-এ হার্ট রেট) বা লোকেশন সংক্রান্ত অনুমতি না দেওয়া হলে,prepareExerciseAsync()কল করবেন না, কারণ ব্যায়াম শুরু করার আগে স্থিতিশীল হার্ট রেট বা জিপিএস ফিক্স পাওয়ার জন্য প্রিপেয়ার কল বিশেষভাবে করা হয়। অ্যাপটি এখনও স্টেপ-ভিত্তিক দূরত্ব, গতি, স্পিড এবং অন্যান্য মেট্রিক পেতে পারে যার জন্য সেইসব অনুমতির প্রয়োজন হয় না।
prepareExerciseAsync()-এ আপনার কল সফল হতে পারে কিনা তা যাচাই করতে নিম্নলিখিতগুলি করুন:
- প্রি-ওয়ার্কআউট অ্যাক্টিভিটির জন্য
AmbientLifecycleObserverব্যবহার করুন যাতে প্রস্তুতি নেওয়ার কল অন্তর্ভুক্ত থাকে। - আপনার ফোরগ্রাউন্ড পরিষেবা থেকে
prepareExerciseAsync()-এ কল করুন। এটি কোনও পরিষেবায় না থাকলে এবং অ্যাক্টিভিটি লাইফসাইকেলের সাথে যুক্ত থাকলে, সেন্সর প্রস্তুতি অপ্রয়োজনীয়ভাবে বন্ধ হয়ে যেতে পারে। - ব্যবহারকারী প্রি-ওয়ার্কআউট অ্যাক্টিভিটি থেকে নেভিগেট করে বেরিয়ে গেলে, সেন্সর বন্ধ করতে এবং পাওয়ারের ব্যবহার কমাতে
endExercise()-এ কল করুন।
prepareExerciseAsync()-কে কীভাবে কল করতে হয় তা নিম্নলিখিত উদাহরণ থেকে দেখুন:
val warmUpConfig = WarmUpConfig(
ExerciseType.RUNNING,
setOf(
DataType.HEART_RATE_BPM,
DataType.LOCATION
)
)
// Only necessary to call prepareExerciseAsync if body sensor (API level 35
// or lower), heart rate (API level 36+), or location permissions are given.
exerciseClient.prepareExerciseAsync(warmUpConfig).await()
// Data and availability updates are delivered to the registered listener.
অ্যাপ PREPARING অবস্থায় থাকলে, সেন্সর উপলভ্যতা সংক্রান্ত আপডেট
ExerciseUpdateCallback-এ onAvailabilityChanged()-এর মাধ্যমে ডেলিভার করা হয়।
এই তথ্য ব্যবহারকারীকে দেখানো হতে পারে যাতে তিনি সিদ্ধান্ত নিতে পারেন যে
ওয়ার্ক-আউট শুরু করবেন কিনা।
ওয়ার্ক-আউট শুরু করুন
আপনি কোনও এক্সারসাইজ শুরু করতে চাইলে, এক্সারসাইজের ধরন, যে ডেটার ধরনের জন্য আপনি মেট্রিক পেতে চান এবং যেকোনও এক্সারসাইজের লক্ষ্য বা মাইলস্টোন কনফিগার করতে ExerciseConfig তৈরি করুন।
ব্যায়ামের লক্ষ্যে DataType ও একটি
শর্ত থাকে। ব্যায়ামের লক্ষ্য হল এককালীন লক্ষ্য যা কোনও শর্ত পূরণ হলে ট্রিগার হয়, যেমন ব্যবহারকারী নির্দিষ্ট দূরত্ব দৌড়ালে। এছাড়াও, ব্যায়ামের
মাইলস্টোন সেট করা যেতে পারে। ব্যায়ামের মাইলস্টোন একাধিকবার ট্রিগার করা যেতে পারে,
যেমন, ব্যবহারকারী প্রতিবার
তার সেট করা দূরত্বের বাইরে একটি নির্দিষ্ট পয়েন্টে দৌড়ান।
নিম্নলিখিত স্যাম্পেল থেকে প্রতিটি ধরনের একটি করে লক্ষ্য কীভাবে তৈরি করতে হয় তা দেখানো হয়েছে:
const val CALORIES_THRESHOLD = 250.0
const val DISTANCE_THRESHOLD = 1_000.0 // meters
suspend fun startExercise() {
// Types for which we want to receive metrics.
val dataTypes = setOf(
DataType.HEART_RATE_BPM,
DataType.CALORIES_TOTAL,
DataType.DISTANCE
)
// Create a one-time goal.
val calorieGoal = ExerciseGoal.createOneTimeGoal(
DataTypeCondition(
dataType = DataType.CALORIES_TOTAL,
threshold = CALORIES_THRESHOLD,
comparisonType = ComparisonType.GREATER_THAN_OR_EQUAL
)
)
// Create a milestone goal. To make a milestone for every kilometer, set the initial
// threshold to 1km and the period to 1km.
val distanceGoal = ExerciseGoal.createMilestone(
condition = DataTypeCondition(
dataType = DataType.DISTANCE_TOTAL,
threshold = DISTANCE_THRESHOLD,
comparisonType = ComparisonType.GREATER_THAN_OR_EQUAL
),
period = DISTANCE_THRESHOLD
)
val config = ExerciseConfig(
exerciseType = ExerciseType.RUNNING,
dataTypes = dataTypes,
isAutoPauseAndResumeEnabled = false,
isGpsEnabled = true,
exerciseGoals = mutableListOf<ExerciseGoal<Double>>(calorieGoal, distanceGoal)
)
exerciseClient.startExerciseAsync(config).await()
}
এছাড়াও, আপনি সব এক্সারসাইজের জন্য ল্যাপ চিহ্নিত করতে পারবেন। স্বাস্থ্য পরিষেবা ল্যাপ পিরিয়ড জুড়ে
অ্যাগ্রিগেট করা মেট্রিক্স সহ
ExerciseLapSummary প্রদান করে।
আগের উদাহরণে isGpsEnabled-এর ব্যবহার দেখানো হয়েছে, লোকেশন ডেটার জন্য অনুরোধ করার সময়
এটি অবশ্যই সত্য হতে হবে। তবে, জিপিএস ব্যবহার করলে অন্যান্য মেট্রিকও
সহজে পাওয়া যায়। ExerciseConfig যদি DataType হিসেবে দূরত্ব উল্লেখ করে,
তাহলে এটি ডিফল্ট হিসেবে দূরত্ব অনুমান করার জন্য স্টেপ ব্যবহার করে। বিকল্প হিসেবে জিপিএস চালু করে,
দূরত্ব অনুমান করার জন্য লোকেশন তথ্য ব্যবহার করা যেতে পারে।
ওয়ার্ক-আউট পজ, আবার চালু ও শেষ করা
আপনি উপযুক্ত পদ্ধতি ব্যবহার করে ওয়ার্কআউট পজ, আবার চালু ও শেষ করতে পারবেন, যেমন
pauseExerciseAsync()
বা
endExerciseAsync()।
ExerciseUpdate থেকে পাওয়া স্টেটকে সোর্স অফ ট্রুথ হিসেবে ব্যবহার করুন। pauseExerciseAsync()-এ কল ফিরে এলে ওয়ার্কআউট পজ করা হয়েছে বলে
বিবেচনা করা হয় না, বরং
ExerciseUpdate মেসেজে সেই স্ট্যাটাস প্রতিফলিত হলে তবেই তা বিবেচনা করা হয়। UI স্টেটসের ক্ষেত্রে এটি
বিবেচনা করা বিশেষভাবে গুরুত্বপূর্ণ। ব্যবহারকারী পজ বোতাম প্রেস করলে,
পজ বোতাম বন্ধ করে দিন এবং স্বাস্থ্য পরিষেবায়
pauseExerciseAsync() কল করুন। ExerciseUpdate.exerciseStateInfo.state ব্যবহার করে স্বাস্থ্য পরিষেবা পজ করা
অবস্থায় পৌঁছানো পর্যন্ত অপেক্ষা করুন এবং তারপর আবার চালু করতে
বোতামটি পাল্টান। এর কারণ হল, বোতাম প্রেস করার চেয়ে Health Services-এর স্ট্যাটাস আপডেট হতে বেশি সময় লাগতে পারে, তাই আপনি যদি UI-এর সব পরিবর্তন বোতাম প্রেস করার সাথে যুক্ত করেন, তাহলে UI, Health Services-এর স্ট্যাটাসের সাথে সিঙ্ক নাও হতে পারে।
নিম্নলিখিত পরিস্থিতিতে এটি মনে রাখবেন:
- অটো-পজ চালু করা আছে: ব্যবহারকারীর ইন্টার্যাকশন ছাড়াই ওয়ার্ক-আউট পজ বা শুরু করা যেতে পারে।
- অন্য অ্যাপ ওয়ার্ক-আউট শুরু করলে: ব্যবহারকারীর ইন্টার্যাকশন ছাড়াই আপনার ওয়ার্ক-আউট বন্ধ হয়ে যেতে পারে।
অন্য কোনও অ্যাপ আপনার অ্যাপের ওয়ার্ক-আউট বন্ধ করে দিলে, আপনার অ্যাপকে অবশ্যই বন্ধ করার বিষয়টি সুন্দরভাবে ম্যানেজ করতে হবে:
- আংশিক ওয়ার্কআউট স্ট্যাটাস সেভ করুন যাতে ব্যবহারকারীর প্রোগ্রেস মুছে না যায়।
- অনগোইং অ্যাক্টিভিটি আইকন সরিয়ে দিন এবং ব্যবহারকারীকে বিজ্ঞপ্তি পাঠিয়ে জানান যে অন্য কোনও অ্যাপ তার ওয়ার্কআউট শেষ করে দিয়েছে।
এছাড়াও, চলমান ব্যায়ামের সময় অনুমতি প্রত্যাহার করা হলে
কেসটি হ্যান্ডেল করুন। এটি isEnded স্টেট ব্যবহার করে পাঠানো হয়, যার সাথে
ExerciseEndReason
AUTO_END_PERMISSION_LOST থাকে। এই কেসটি টার্মিনেশন কেসের মতোই
হ্যান্ডেল করুন: আংশিক স্ট্যাটাস সেভ করুন, অনগোইং অ্যাক্টিভিটি
আইকন সরিয়ে দিন এবং ব্যবহারকারীর সাথে কী ঘটেছে সেই সম্পর্কে বিজ্ঞপ্তি পাঠান।
কীভাবে সঠিকভাবে সমাপ্তি চেক করতে হয় তা নিম্নলিখিত উদাহরণ থেকে দেখুন:
val callback = object : ExerciseUpdateCallback {
override fun onExerciseUpdateReceived(update: ExerciseUpdate) {
if (update.exerciseStateInfo.state.isEnded) {
// Workout has either been ended by the user, or otherwise terminated
}
...
}
...
}
অ্যাক্টিভ থাকার সময়সীমা ম্যানেজ করুন
ব্যায়াম করার সময়, কোনও অ্যাপ ওয়ার্ক-আউটের অ্যাক্টিভ সময়কাল
দেখাতে পারে। অ্যাপ, স্বাস্থ্য পরিষেবা এবং ডিভাইসের মাইক্রো কন্ট্রোলার ইউনিট
(MCU)—ব্যায়াম ট্র্যাক করার জন্য
কম-পাওয়ারের প্রসেসর—সবকিছুকে একই বর্তমান অ্যাক্টিভ সময়সীমার সাথে
সিঙ্ক করতে হবে। এটি ম্যানেজ করতে সাহায্য করার জন্য, স্বাস্থ্য পরিষেবা একটি
ActiveDurationCheckpoint পাঠায় যা একটি অ্যাঙ্কর পয়েন্ট প্রদান করে যেখান থেকে অ্যাপটি
তার টাইমার শুরু করতে পারে।
MCU থেকে অ্যাক্টিভ থাকার সময়সীমা পাঠানো হয় এবং অ্যাপে পৌঁছাতে কিছুটা সময় লাগতে পারে, তাই ActiveDurationCheckpoint-এ দুটি প্রপার্টি থাকে:
activeDuration: কতক্ষণ ধরে এক্সারসাইজ অ্যাক্টিভ আছেtime: যখন অ্যাক্টিভ থাকার সময়সীমা হিসেব করা হয়েছিল
তাই, অ্যাপে কোনও এক্সারসাইজের অ্যাক্টিভ সময়কাল
নিম্নলিখিত সমীকরণ ব্যবহার করে ActiveDurationCheckpoint থেকে গণনা করা যেতে পারে:
(now() - checkpoint.time) + checkpoint.activeDuration
MCU-তে গণনা করা অ্যাক্টিভ সময়কাল এবং অ্যাপে পৌঁছানোর মধ্যে ছোট ডেল্টার জন্য এটি দায়ী। এটি অ্যাপে ক্রোনোমিটার সিড করতে ব্যবহার করা যেতে পারে এবং অ্যাপের টাইমারটি স্বাস্থ্য পরিষেবা এবং MCU-তে সময়ের সাথে পুরোপুরি অ্যালাইন করা আছে কিনা তা নিশ্চিত করতে সাহায্য করে।
ব্যায়াম পজ করা হলে, UI-তে দেখানো সময়ের থেকে গণনা করা সময় বেশি না হওয়া পর্যন্ত
UI-তে টাইমার রিস্টার্ট করার জন্য অ্যাপ অপেক্ষা করে।
কারণ, পজ করার সিগন্যাল স্বাস্থ্য পরিষেবা ও MCU-তে পৌঁছাতে
সামান্য দেরি হয়। যেমন, t=10 সেকেন্ডে অ্যাপ পজ করা হলে, t=10.2 সেকেন্ড পর্যন্ত Health
Services অ্যাপে PAUSED আপডেট নাও পাঠাতে পারে।
ExerciseClient থেকে পাওয়া ডেটা নিয়ে কাজ করা
আপনার অ্যাপ যে ধরনের ডেটার জন্য রেজিস্টার করেছে তার মেট্রিক
ExerciseUpdate
মেসেজে ডেলিভার করা হয়।
প্রসেসর শুধুমাত্র জেগে থাকলে বা সর্বাধিক রিপোর্টিংয়ের সময়সীমা, যেমন প্রতি ১৫০ সেকেন্ডে,
পৌঁছে গেলে মেসেজ পাঠায়। activeDuration-এর সাথে ক্রোনোমিটারকে এগিয়ে নিয়ে যাওয়ার জন্য
ExerciseUpdate ফ্রিকোয়েন্সির উপর নির্ভর করবেন না। কীভাবে একটি স্বাধীন ক্রোনোমিটার প্রয়োগ করতে হয় তার উদাহরণের জন্য GitHub-এ ব্যায়ামের নমুনা
দেখুন।
কোনও ব্যবহারকারী ওয়ার্কআউট শুরু করলে, ExerciseUpdate মেসেজ ঘনঘন ডেলিভার করা হতে পারে,
যেমন, প্রতি সেকেন্ডে। ব্যবহারকারী ওয়ার্কআউট শুরু করলে, স্ক্রিন
বন্ধ হয়ে যেতে পারে। সেক্ষেত্রে, স্বাস্থ্য পরিষেবা কম ঘন ঘন ডেটা ডেলিভার করতে পারে, তবে এখনও
একই ফ্রিকোয়েন্সিতে স্যাম্পেল করা হয়, যাতে মূল প্রসেসরকে জাগাতে না হয়। ব্যবহারকারী স্ক্রিনের দিকে তাকালে, ব্যাচিং প্রসেসে থাকা যেকোনও ডেটা অবিলম্বে
আপনার অ্যাপে ডেলিভার করা হয়।
ব্যাচিং রেট কন্ট্রোল করুন
কিছু ক্ষেত্রে, স্ক্রিন বন্ধ থাকাকালীন আপনার অ্যাপ যাতে নির্দিষ্ট ডেটার ধরন
ঘন ঘন পায়, তা আপনি নিয়ন্ত্রণ করতে চাইতে পারেন।
BatchingMode
অবজেক্ট আপনার অ্যাপকে ডিফল্ট ব্যাচিং আচরণ ওভাররাইড করার অনুমতি দেয়, যাতে আরও ঘন ঘন ডেটা
ডেলিভারি পাওয়া যায়।
ব্যাচিং রেট কনফিগার করতে, নিম্নলিখিত ধাপগুলি সম্পূর্ণ করুন:
ডিভাইসে নির্দিষ্ট
BatchingModeডেফিনেশন কাজ করে কিনা তা চেক করুন:// Confirm BatchingMode support to control heart rate stream to phone. suspend fun supportsHrWorkoutCompanionMode(): Boolean { val capabilities = exerciseClient.getCapabilities() return BatchingMode.HEART_RATE_5_SECONDS in capabilities.supportedBatchingModeOverrides }ExerciseConfigঅবজেক্টের জন্য নির্দিষ্টBatchingModeব্যবহার করতে হবে, যেমনটি নিম্নলিখিত কোড স্নিপেটে দেখানো হয়েছে।val config = ExerciseConfig( exerciseType = ExerciseType.WORKOUT, dataTypes = setOf( DataType.HEART_RATE_BPM, DataType.TOTAL_CALORIES ), // ... batchingModeOverrides = setOf(BatchingMode.HEART_RATE_5_SECONDS) )বিকল্প হিসেবে, আপনি ওয়ার্ক-আউট চলাকালীন ডায়নামিকভাবে
BatchingModeকনফিগার করতে পারেন, ওয়ার্ক-আউট চলাকালীন নির্দিষ্ট ব্যাচিং আচরণ বজায় রাখার পরিবর্তে:val desiredModes = setOf(BatchingMode.HEART_RATE_5_SECONDS) exerciseClient.overrideBatchingModesForActiveExercise(desiredModes)কাস্টমাইজ করা
BatchingModeমুছে দিতে এবং ডিফল্ট অ্যাকশনে ফিরে যেতে,exerciseClient.overrideBatchingModesForActiveExercise()-এ একটি খালি সেট পাস করুন।
টাইমস্ট্যাম্প
প্রতিটি ডেটা পয়েন্টের পয়েন্ট-ইন-টাইম ডিভাইস বুট হওয়ার পর থেকে সময়কালকে উপস্থাপন করে। এটি টাইমস্ট্যাম্পে পরিবর্তন করতে, নিম্নলিখিত ধাপগুলি অনুসরণ করুন:
val bootInstant =
Instant.ofEpochMilli(System.currentTimeMillis() - SystemClock.elapsedRealtime())
এই ভ্যালু প্রতিটি ডেটা পয়েন্টের জন্য getStartInstant()
বা getEndInstant()-এর
সাথে ব্যবহার করা যেতে পারে।
ডেটার নির্ভুলতা
কিছু ডেটার ধরন প্রতিটি ডেটা পয়েন্টের সাথে সম্পর্কিত নির্ভুল তথ্য থাকতে পারে।
এটি accuracy প্রপার্টিতে দেখানো হয়।
HEART_RATE_BPM এবং LOCATION ডেটার ধরনের জন্য যথাক্রমে
HrAccuracy এবং LocationAccuracy ক্লাস পপুলেট করা যেতে পারে। যেখানে আছে, সেখানে
accuracy প্রপার্টি ব্যবহার করে নির্ধারণ করুন যে প্রতিটি ডেটা পয়েন্ট আপনার অ্যাপ্লিকেশনের জন্য যথেষ্ট
সঠিক কিনা।
ডেটা স্টোর ও আপলোড করা
Health Services থেকে পাওয়া ডেটা সেভ করে রাখতে Room ব্যবহার করুন। অনুশীলন শেষ হওয়ার পরে Work Manager-এর মতো কোনও মেকানিজম ব্যবহার করে ডেটা আপলোড করা হয়। এটি যাচাই করতে সাহায্য করে যে এক্সারসাইজ শেষ না হওয়া পর্যন্ত ডেটা আপলোড করার জন্য নেটওয়ার্ক কলগুলি স্থগিত করা হয়েছে, এক্সারসাইজের সময় বিদ্যুৎ খরচ কমিয়ে দেয় এবং কাজকে সহজ করে তোলে।
ইন্টিগ্রেশন চেকলিস্ট
Health Services' ExerciseClient ব্যবহার করে এমন আপনার অ্যাপ প্রকাশ করার আগে, ব্যবহারকারীর অভিজ্ঞতা যাতে কিছু সাধারণ সমস্যা এড়িয়ে যায় তা যাচাই করতে নিম্নলিখিত চেকলিস্ট
পরামর্শ করুন। কনফার্ম করুন যে:
- প্রতিবার অ্যাপ রান করার সময় আপনার অ্যাপ এক্সারসাইজের ধরন ও ডিভাইসের ক্ষমতা চেক করে। এইভাবে, আপনি শনাক্ত করতে পারবেন যে কোনও নির্দিষ্ট ডিভাইস বা এক্সারসাইজ আপনার অ্যাপের জন্য প্রয়োজনীয় ডেটার ধরনগুলির মধ্যে একটিকে সমর্থন করে না।
- আপনি প্রয়োজনীয় অনুমতির জন্য অনুরোধ করেন ও তা বজায় রাখেন এবং আপনার ম্যানিফেস্ট ফাইলে
এগুলি উল্লেখ করেন।
prepareExerciseAsync()কল করার আগে, আপনার অ্যাপ রানটাইম অনুমতি দেওয়া হয়েছে কিনা তা কনফার্ম করে। - আপনার অ্যাপ
getCurrentExerciseInfoAsync()ব্যবহার করে সেইসব পরিস্থিতি ম্যানেজ করে যেখানে:- একটি এক্সারসাইজ আগে থেকেই ট্র্যাক করা হচ্ছে এবং আপনার অ্যাপ আগের এক্সারসাইজ ওভাররাইড করে।
- অন্য একটি অ্যাপ আপনার এক্সারসাইজ বন্ধ করে দিয়েছে। ব্যবহারকারী অ্যাপটি আবার খুললে এটি হতে পারে, তাদের একটি মেসেজ দেখানো হয় যাতে ব্যাখ্যা করা হয় যে ব্যায়াম বন্ধ হয়ে গেছে কারণ অন্য একটি অ্যাপ দখল করেছে।
- আপনি
LOCATIONডেটা ব্যবহার করলে:- আপনার অ্যাপ, এক্সারসাইজের পুরো সময় জুড়ে (প্রস্তুতি কল সহ)
সংশ্লিষ্ট
foregroundServiceType-এর সাথেForegroundServiceবজায় রাখে। isProviderEnabled(LocationManager.GPS_PROVIDER)ব্যবহার করে ডিভাইসে জিপিএস চালু আছে কিনা তা চেক করুন এবং প্রয়োজন হলে ব্যবহারকারীকে লোকেশন সেটিংস খোলার জন্য প্রম্পট করুন।- যেসব ক্ষেত্রে কম লেটেন্সি সহ লোকেশন ডেটা পাওয়া অত্যন্ত গুরুত্বপূর্ণ, সেখানে ফিউজড লোকেশন প্রোভাইডার (FLP) ইন্টিগ্রেট করার কথা বিবেচনা করুন এবং প্রাথমিক লোকেশন ফিক্স হিসেবে এর ডেটা ব্যবহার করুন। Health Services থেকে আরও স্থিতিশীল লোকেশন তথ্য উপলভ্য হলে, FLP-এর পরিবর্তে সেটি ব্যবহার করুন।
- আপনার অ্যাপ, এক্সারসাইজের পুরো সময় জুড়ে (প্রস্তুতি কল সহ)
সংশ্লিষ্ট
- আপনার অ্যাপে ডেটা আপলোড করার প্রয়োজন হলে, ডেটা আপলোড করার জন্য যেকোনও নেটওয়ার্ক কল ব্যায়াম শেষ না হওয়া পর্যন্ত স্থগিত রাখা হয়। অন্যথায়, পুরো এক্সারসাইজ চলাকালীন, আপনার অ্যাপ প্রয়োজনীয় নেটওয়ার্ক কল খুব কম করে।
আপনার জন্য সাজেস্ট করা হয়েছে
- মনে রাখবেন: জাভাস্ক্রিপ্ট বন্ধ থাকলে লিঙ্ক টেক্সট দেখানো হয়
- প্যাসিভ ডেটা আপডেট
- Wear OS-এ স্বাস্থ্য পরিষেবা
- টাইল ব্যবহার করা শুরু করুন