Health Services ExerciseClient এর মাধ্যমে ওয়ার্কআউট অ্যাপগুলির জন্য সহায়তা প্রদান করে। ExerciseClient এর মাধ্যমে, আপনার অ্যাপটি কখন কোনও ব্যায়াম চলছে তা নিয়ন্ত্রণ করতে পারে, ব্যায়ামের লক্ষ্য যোগ করতে পারে এবং ব্যায়ামের অবস্থা, ব্যায়ামের ইভেন্ট বা অন্যান্য মেট্রিক্স সম্পর্কে আপডেট পেতে পারে। আরও তথ্যের জন্য, Health Services দ্বারা সমর্থিত ব্যায়ামের ধরণের সম্পূর্ণ তালিকা দেখুন।
GitHub-এ ব্যায়ামের নমুনা দেখুন।
নির্ভরতা যোগ করুন
স্বাস্থ্য পরিষেবার উপর নির্ভরতা যোগ করতে, আপনার প্রকল্পে Google Maven সংগ্রহস্থল যোগ করতে হবে। আরও তথ্যের জন্য, Google এর Maven সংগ্রহস্থল দেখুন।
তারপর, আপনার মডিউল-স্তরের build.gradle ফাইলে, নিম্নলিখিত নির্ভরতা যোগ করুন:
গ্রোভি
dependencies { implementation "androidx.health:health-services-client:1.1.0-alpha05" }
কোটলিন
dependencies { implementation("androidx.health:health-services-client:1.1.0-alpha05") }
অ্যাপের কাঠামো
স্বাস্থ্য পরিষেবার সাথে একটি ব্যায়াম অ্যাপ তৈরি করার সময় নিম্নলিখিত অ্যাপ কাঠামো ব্যবহার করুন:
- আপনার স্ক্রিন এবং নেভিগেশনকে একটি প্রধান কার্যকলাপের মধ্যে রাখুন।
- একটি ফোরগ্রাউন্ড পরিষেবার মাধ্যমে ওয়ার্কআউট অবস্থা, সেন্সর ডেটা, চলমান কার্যকলাপ এবং ডেটা পরিচালনা করুন।
- Room দিয়ে ডেটা সংরক্ষণ করুন এবং ডেটা আপলোড করতে WorkManager ব্যবহার করুন।
ওয়ার্কআউটের প্রস্তুতি নেওয়ার সময় এবং ওয়ার্কআউট চলাকালীন, বিভিন্ন কারণে আপনার কার্যকলাপ বন্ধ হয়ে যেতে পারে। ব্যবহারকারী অন্য অ্যাপে স্যুইচ করতে পারেন অথবা ওয়াচফেসে ফিরে যেতে পারেন। সিস্টেমটি আপনার কার্যকলাপের উপরে কিছু প্রদর্শন করতে পারে, অথবা কিছুক্ষণ নিষ্ক্রিয় থাকার পরে স্ক্রিনটি বন্ধ হয়ে যেতে পারে। পুরো ওয়ার্কআউটের সঠিক ক্রিয়াকলাপ নিশ্চিত করতে ExerciseClient এর সাথে একটি ক্রমাগত চলমান ForegroundService ব্যবহার করুন।
ForegroundService ব্যবহার করলে আপনি Ongoing Activity 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() কল থাকে এবং আপনার ওয়ার্কআউট কার্যকলাপের জন্য। তবে, অ্যাম্বিয়েন্ট মোডের সময় ওয়ার্কআউটের সময় ডিসপ্লে আপডেট করবেন না: কারণ Health Services ডিভাইসের স্ক্রিন অ্যাম্বিয়েন্ট মোডে থাকাকালীন ওয়ার্কআউট ডেটা ব্যাচ করে বিদ্যুৎ সাশ্রয় করে, তাই প্রদর্শিত তথ্য সাম্প্রতিক নাও হতে পারে। ওয়ার্কআউটের সময়, ব্যবহারকারীর কাছে অর্থপূর্ণ ডেটা দেখান, হয় আপ-টু-ডেট তথ্য প্রদর্শন করে অথবা একটি ফাঁকা স্ক্রিন প্রদর্শন করে।
ক্ষমতা পরীক্ষা করুন
প্রতিটি 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)
ব্যায়ামের জীবনকাল পরিচালনা করুন
হেলথ সার্ভিসেস ডিভাইসের সমস্ত অ্যাপে একবারে সর্বাধিক একটি অনুশীলন সমর্থন করে। যদি একটি অনুশীলন ট্র্যাক করা হয় এবং একটি ভিন্ন অ্যাপ একটি নতুন অনুশীলন ট্র্যাক করা শুরু করে, তাহলে প্রথম অনুশীলনটি বন্ধ হয়ে যায়।
আপনার ব্যায়াম শুরু করার আগে, নিম্নলিখিতগুলি করুন:
- কোনও অনুশীলন ইতিমধ্যেই ট্র্যাক করা হচ্ছে কিনা তা পরীক্ষা করে দেখুন এবং সেই অনুযায়ী প্রতিক্রিয়া জানান। উদাহরণস্বরূপ, পূর্ববর্তী অনুশীলনকে অগ্রাহ্য করে নতুন একটি অনুশীলন শুরু করার আগে ব্যবহারকারীর কাছ থেকে নিশ্চিতকরণের জন্য জিজ্ঞাসা করুন।
নিম্নলিখিত উদাহরণে 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)ব্যবহার করে ডিভাইসে GPS সক্রিয় আছে কিনা তা পরীক্ষা করুন। প্রয়োজনে ব্যবহারকারীকে অবস্থান সেটিংস খুলতে বলুন। - নিশ্চিত করুন যে পুরো ওয়ার্কআউট জুড়ে উপযুক্ত
foregroundServiceTypeসহ একটিForegroundServiceবজায় রাখা হয়েছে।
ওয়ার্কআউটের জন্য প্রস্তুত হোন
কিছু সেন্সর, যেমন GPS বা হৃদস্পন্দন, গরম হতে অল্প সময় নিতে পারে, অথবা ব্যবহারকারী তাদের ওয়ার্কআউট শুরু করার আগে তাদের ডেটা দেখতে চাইতে পারেন। ঐচ্ছিক prepareExerciseAsync() পদ্ধতি এই সেন্সরগুলিকে গরম করতে দেয় এবং ওয়ার্কআউটের টাইমার শুরু না করেই ডেটা গ্রহণ করতে দেয়। এই প্রস্তুতির সময় দ্বারা activeDuration প্রভাবিত হয় না।
prepareExerciseAsync() কল করার আগে, নিম্নলিখিতগুলি পরীক্ষা করুন:
প্ল্যাটফর্ম-ব্যাপী অবস্থান সেটিং পরীক্ষা করুন। ব্যবহারকারী প্রধান সেটিংস মেনুতে এই সেটিংটি নিয়ন্ত্রণ করেন; এটি অ্যাপ-স্তরের অনুমতি চেক থেকে আলাদা।
যদি সেটিংটি বন্ধ থাকে, তাহলে ব্যবহারকারীকে জানান যে তারা লোকেশন অ্যাক্সেস করতে অস্বীকৃতি জানিয়েছেন, এবং যদি আপনার অ্যাপের লোকেশনের প্রয়োজন হয় তবে এটি সক্ষম করতে তাদের অনুরোধ করুন।
নিশ্চিত করুন যে আপনার অ্যাপে বডি সেন্সর (API লেভেল ৩৫ বা তার কম) অথবা হার্ট রেট (API লেভেল ৩৬+), অ্যাক্টিভিটি রিকগনিশন এবং সূক্ষ্ম অবস্থানের জন্য রানটাইম অনুমতি আছে। অনুপস্থিত অনুমতির জন্য, পর্যাপ্ত প্রেক্ষাপট প্রদান করে ব্যবহারকারীকে রানটাইম অনুমতির জন্য অনুরোধ করুন। যদি ব্যবহারকারী নির্দিষ্ট অনুমতি না দেন, তাহলে
prepareExerciseAsync()কল থেকে সেই অনুমতির সাথে সম্পর্কিত ডেটা টাইপগুলি সরিয়ে ফেলুন। যদি বডি সেন্সর (API লেভেল ৩৬+ এ হার্ট রেট) বা অবস্থানের অনুমতি না দেওয়া হয়, তাহলেprepareExerciseAsync()কল করবেন না, কারণ প্রস্তুতি কলটি বিশেষভাবে একটি স্থিতিশীল হার্ট রেট বা GPS ফিক্স অর্জনের জন্য একটি অনুশীলন শুরু করার আগে করা হয়। অ্যাপটি এখনও ধাপ-ভিত্তিক দূরত্ব, গতি, গতি এবং অন্যান্য মেট্রিক্স পেতে পারে যার জন্য এই অনুমতিগুলির প্রয়োজন হয় না।
আপনার 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 অবস্থায় আসার পর, onAvailabilityChanged() এর মাধ্যমে ExerciseUpdateCallback এ সেন্সরের উপলব্ধতার আপডেটগুলি সরবরাহ করা হয়। এই তথ্যটি ব্যবহারকারীর কাছে উপস্থাপন করা যেতে পারে যাতে তারা তাদের ওয়ার্কআউট শুরু করবেন কিনা তা সিদ্ধান্ত নিতে পারেন।
ওয়ার্কআউট শুরু করুন
যখন আপনি একটি ব্যায়াম শুরু করতে চান, তখন ব্যায়ামের ধরণ, আপনি যে ডেটা টাইপগুলির জন্য মেট্রিক্স পেতে চান এবং যেকোনো ব্যায়ামের লক্ষ্য বা মাইলফলক কনফিগার করার জন্য একটি 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 ব্যবহার দেখানো হয়েছে, যা অবস্থানের ডেটা অনুরোধ করার সময় সত্য হতে হবে। তবে, GPS ব্যবহার অন্যান্য মেট্রিক্সেও সহায়তা করতে পারে। যদি ExerciseConfig দূরত্বকে DataType হিসাবে নির্দিষ্ট করে, তাহলে এটি দূরত্ব অনুমান করার জন্য ধাপগুলি ব্যবহার করার জন্য ডিফল্ট। ঐচ্ছিকভাবে GPS সক্ষম করে, দূরত্ব অনুমান করার পরিবর্তে অবস্থানের তথ্য ব্যবহার করা যেতে পারে।
ওয়ার্কআউট থামান, পুনরায় শুরু করুন এবং শেষ করুন
আপনি উপযুক্ত পদ্ধতি ব্যবহার করে ওয়ার্কআউট থামাতে, পুনরায় শুরু করতে এবং শেষ করতে পারেন, যেমন pauseExerciseAsync() অথবা endExerciseAsync() ।
ExerciseUpdate থেকে প্রাপ্ত অবস্থাকে সত্যের উৎস হিসেবে ব্যবহার করুন। pauseExerciseAsync() কলটি ফিরে এলে ওয়ার্কআউটটি বিরতিপ্রাপ্ত বলে বিবেচিত হয় না, বরং যখন সেই অবস্থাটি ExerciseUpdate বার্তায় প্রতিফলিত হয় তখন তা বিবেচনা করা হয়। UI অবস্থার ক্ষেত্রে এটি বিশেষভাবে বিবেচনা করা গুরুত্বপূর্ণ। যদি ব্যবহারকারী বিরতি চাপেন, তাহলে pause বোতামটি নিষ্ক্রিয় করুন এবং Health Services-এ pauseExerciseAsync() কল করুন। ExerciseUpdate.exerciseStateInfo.state ব্যবহার করে Health Services বিরতিপ্রাপ্ত অবস্থায় পৌঁছানোর জন্য অপেক্ষা করুন, এবং তারপর বোতামটি পুনরায় শুরু করুন। কারণ Health Services স্টেট আপডেটগুলি বোতাম টিপানোর চেয়ে বেশি সময় নিতে পারে, তাই আপনি যদি সমস্ত UI পরিবর্তনগুলিকে বোতাম টিপে সংযুক্ত করেন, তাহলে UI স্বাস্থ্য পরিষেবা অবস্থার সাথে সিঙ্কের বাইরে চলে যেতে পারে।
নিম্নলিখিত পরিস্থিতিতে এটি মনে রাখবেন:
- অটো-পজ সক্ষম করা হয়েছে: ব্যবহারকারীর মিথস্ক্রিয়া ছাড়াই ওয়ার্কআউটটি বিরতি বা শুরু হতে পারে।
- অন্য একটি অ্যাপ একটি ওয়ার্কআউট শুরু করে: ব্যবহারকারীর ইন্টারঅ্যাকশন ছাড়াই আপনার ওয়ার্কআউট বন্ধ হয়ে যেতে পারে।
যদি আপনার অ্যাপের ওয়ার্কআউট অন্য কোনও অ্যাপ দ্বারা বন্ধ করা হয়, তাহলে আপনার অ্যাপটিকে অবশ্যই সুন্দরভাবে সমাপ্তিটি পরিচালনা করতে হবে:
- আংশিক ওয়ার্কআউট অবস্থা সংরক্ষণ করুন যাতে ব্যবহারকারীর অগ্রগতি মুছে না যায়।
- চলমান কার্যকলাপ আইকনটি সরিয়ে ফেলুন এবং ব্যবহারকারীকে একটি বিজ্ঞপ্তি পাঠান যাতে তারা জানতে পারে যে তাদের ওয়ার্কআউট অন্য একটি অ্যাপের মাধ্যমে শেষ হয়েছে।
এছাড়াও, চলমান অনুশীলনের সময় অনুমতি বাতিল করা হলে সেই ক্ষেত্রেও ব্যবস্থা নিন। এটি isEnded অবস্থা ব্যবহার করে পাঠানো হয়, যার একটি ExerciseEndReason AUTO_END_PERMISSION_LOST থাকে। এই ক্ষেত্রেও সমাপ্তির ক্ষেত্রের মতোই ব্যবস্থা নিন: আংশিক অবস্থা সংরক্ষণ করুন, Ongoing Activity আইকনটি সরিয়ে ফেলুন এবং ব্যবহারকারীর সাথে কী ঘটেছে সে সম্পর্কে একটি বিজ্ঞপ্তি পাঠান।
নিচের উদাহরণটি দেখায় কিভাবে সঠিকভাবে সমাপ্তি পরীক্ষা করতে হয়:
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 থেকে একটি অনুশীলনের সক্রিয় সময়কাল গণনা করা যেতে পারে:
(এখন() - চেকপয়েন্ট.টাইম) + চেকপয়েন্ট.অ্যাক্টিভড্যুরেশন
এটি MCU-তে সক্রিয় সময়কাল গণনা করা এবং অ্যাপে পৌঁছানোর মধ্যে ছোট ডেল্টার জন্য দায়ী। এটি অ্যাপে একটি ক্রোনোমিটার সিড করতে এবং অ্যাপের টাইমারটি স্বাস্থ্য পরিষেবা এবং MCU-তে সময়ের সাথে পুরোপুরি সামঞ্জস্যপূর্ণ কিনা তা নিশ্চিত করতে ব্যবহার করা যেতে পারে।
যদি অনুশীলনটি বিরতি দেওয়া হয়, তাহলে অ্যাপটি UI-তে টাইমারটি পুনরায় চালু করার জন্য অপেক্ষা করে যতক্ষণ না গণনা করা সময় UI-তে প্রদর্শিত সময়ের চেয়ে বেশি সময় অতিক্রান্ত হয়। এর কারণ হল বিরতি সংকেতটি স্বাস্থ্য পরিষেবা এবং MCU-তে সামান্য বিলম্বের সাথে পৌঁছায়। উদাহরণস্বরূপ, যদি অ্যাপটি t=10 সেকেন্ডে বিরতি দেওয়া হয়, তাহলে স্বাস্থ্য পরিষেবাগুলি t=10.2 সেকেন্ড পর্যন্ত অ্যাপটিতে PAUSED আপডেট সরবরাহ নাও করতে পারে।
ExerciseClient থেকে ডেটা নিয়ে কাজ করুন
আপনার অ্যাপ যে ধরণের ডেটার জন্য নিবন্ধিত হয়েছে তার মেট্রিক্স ExerciseUpdate বার্তাগুলিতে সরবরাহ করা হয়।
প্রসেসর কেবল তখনই বার্তা সরবরাহ করে যখন ঘুম থেকে ওঠে অথবা যখন সর্বোচ্চ রিপোর্টিং সময়কাল পৌঁছে যায়, যেমন প্রতি ১৫০ সেকেন্ডে। activeDuration দিয়ে একটি ক্রোনোমিটার এগিয়ে নিতে ExerciseUpdate ফ্রিকোয়েন্সির উপর নির্ভর করবেন না। একটি স্বাধীন ক্রোনোমিটার কীভাবে বাস্তবায়ন করতে হয় তার উদাহরণের জন্য GitHub-এ Exercise নমুনাটি দেখুন।
যখন একজন ব্যবহারকারী ওয়ার্কআউট শুরু করেন, তখন 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' ExerciseClient ব্যবহার করে প্রকাশ করার আগে, আপনার ব্যবহারকারীর অভিজ্ঞতা কিছু সাধারণ সমস্যা এড়ায় কিনা তা যাচাই করার জন্য নিম্নলিখিত চেকলিস্টটি দেখুন। নিশ্চিত করুন যে:
- আপনার অ্যাপটি প্রতিবার অ্যাপটি চালানোর সময় ব্যায়ামের ধরণের ক্ষমতা এবং ডিভাইসের ক্ষমতা পরীক্ষা করে । এইভাবে, আপনি সনাক্ত করতে পারবেন কখন কোনও নির্দিষ্ট ডিভাইস বা ব্যায়াম আপনার অ্যাপের প্রয়োজনীয় ডেটা টাইপগুলির একটিকে সমর্থন করে না।
- আপনি প্রয়োজনীয় অনুমতিগুলির অনুরোধ এবং রক্ষণাবেক্ষণ করেন এবং আপনার ম্যানিফেস্ট ফাইলে এগুলি নির্দিষ্ট করেন।
prepareExerciseAsync()কল করার আগে, আপনার অ্যাপ রানটাইম অনুমতিগুলি মঞ্জুর করা হয়েছে তা নিশ্চিত করে। - আপনার অ্যাপটি
getCurrentExerciseInfoAsync()ব্যবহার করে এমন ক্ষেত্রে পরিচালনা করে যেখানে :- একটি অনুশীলন ইতিমধ্যেই ট্র্যাক করা হচ্ছে, এবং আপনার অ্যাপটি পূর্ববর্তী অনুশীলনকে ওভাররাইড করে।
- অন্য একটি অ্যাপ আপনার অ্যাপটি বন্ধ করে দিয়েছে। এটি ঘটতে পারে যখন ব্যবহারকারী অ্যাপটি পুনরায় খোলেন, তখন তাদের কাছে একটি বার্তা আসবে যে অন্য একটি অ্যাপ আপনার অ্যাপটি দখল করার কারণে অ্যাপটি বন্ধ হয়ে গেছে।
- যদি আপনি
LOCATIONডেটা ব্যবহার করেন:- আপনার অ্যাপটি অনুশীলনের পুরো সময়কাল জুড়ে (প্রস্তুতি কল সহ) সংশ্লিষ্ট
foregroundServiceTypeসহ একটিForegroundServiceবজায় রাখে। -
isProviderEnabled(LocationManager.GPS_PROVIDER)ব্যবহার করে ডিভাইসে GPS সক্রিয় আছে কিনা তা পরীক্ষা করুন এবং প্রয়োজনে ব্যবহারকারীকে অবস্থান সেটিংস খুলতে অনুরোধ করুন। - জটিল ব্যবহারের ক্ষেত্রে, যেখানে কম ল্যাটেন্সিতে লোকেশন ডেটা গ্রহণ করা অত্যন্ত গুরুত্বপূর্ণ, সেখানে ফিউজড লোকেশন প্রোভাইডার (FLP) একীভূত করার এবং এর ডেটা প্রাথমিক লোকেশন ফিক্স হিসাবে ব্যবহার করার কথা বিবেচনা করুন। যখন স্বাস্থ্য পরিষেবা থেকে আরও স্থিতিশীল লোকেশন তথ্য পাওয়া যায়, তখন FLP এর পরিবর্তে এটি ব্যবহার করুন।
- আপনার অ্যাপটি অনুশীলনের পুরো সময়কাল জুড়ে (প্রস্তুতি কল সহ) সংশ্লিষ্ট
- যদি আপনার অ্যাপের ডেটা আপলোডের প্রয়োজন হয়, তাহলে ডেটা আপলোড করার জন্য যেকোনো নেটওয়ার্ক কল অনুশীলন শেষ না হওয়া পর্যন্ত স্থগিত রাখা হবে। অন্যথায়, অনুশীলনের সময়, আপনার অ্যাপ যেকোনো প্রয়োজনীয় নেটওয়ার্ক কল খুব কমই করে।
আপনার জন্য প্রস্তাবিত
- দ্রষ্টব্য: জাভাস্ক্রিপ্ট বন্ধ থাকলে লিঙ্ক টেক্সট প্রদর্শিত হয়।
- প্যাসিভ ডেটা আপডেট
- Wear OS-এ স্বাস্থ্য পরিষেবা
- টাইলস দিয়ে শুরু করুন