यह गाइड, Health Connect के वर्शन 1.1.0-alpha11 के साथ काम करती है.
Health Connect, प्लान की गई कसरत डेटा टाइप उपलब्ध कराता है. इससे ट्रेनिंग ऐप्लिकेशन, ट्रेनिंग प्लान बना सकते हैं. साथ ही, कसरत वाले ऐप्लिकेशन, ट्रेनिंग प्लान पढ़ सकते हैं. रिकॉर्ड की गई कसरतों (वर्कआउट) को फिर से पढ़ा जा सकता है, ताकि लोगों को उनकी परफ़ॉर्मेंस का विश्लेषण करके बताया जा सके. इससे लोगों को ट्रेनिंग के लक्ष्यों को हासिल करने में मदद मिलती है.
सुविधा की उपलब्धता
यह पता लगाने के लिए कि उपयोगकर्ता के डिवाइस पर Health Connect के ट्रेनिंग प्लान काम करते हैं या नहीं, क्लाइंट परFEATURE_PLANNED_EXERCISE
की उपलब्धता देखें:
if (healthConnectClient
.features
.getFeatureStatus(
HealthConnectFeatures.FEATURE_PLANNED_EXERCISE
) == HealthConnectFeatures.FEATURE_STATUS_AVAILABLE) {
// Feature is available
} else {
// Feature isn't available
}
ज़्यादा जानने के लिए, सुविधा की उपलब्धता की जांच करना लेख पढ़ें.
ज़रूरी अनुमतियां
एक्सरसाइज़ के प्लान का ऐक्सेस, इन अनुमतियों से सुरक्षित होता है:
android.permission.health.READ_PLANNED_EXERCISE
android.permission.health.WRITE_PLANNED_EXERCISE
अपने ऐप्लिकेशन में प्लान की गई कसरत की सुविधा जोड़ने के लिए, PlannedExerciseSession
डेटा टाइप के लिए लिखने की अनुमतियों का अनुरोध करें.
यहाँ दी गई अनुमति का एलान करना ज़रूरी है, ताकि प्लान की गई कसरत की जानकारी लिखी जा सके:
<application>
<uses-permission
android:name="android.permission.health.WRITE_PLANNED_EXERCISE" />
...
</application>
प्लान की गई कसरत की जानकारी पढ़ने के लिए, आपको ये अनुमतियां मांगनी होंगी:
<application>
<uses-permission
android:name="android.permission.health.READ_PLANNED_EXERCISE" />
...
</application>
उपयोगकर्ता से अनुमतियों का अनुरोध करना
क्लाइंट इंस्टेंस बनाने के बाद, आपके ऐप्लिकेशन को उपयोगकर्ता से अनुमतियों का अनुरोध करना होगा. उपयोगकर्ताओं को किसी भी समय अनुमतियां देने या अस्वीकार करने की अनुमति होनी चाहिए.
इसके लिए, ज़रूरी डेटा टाइप के लिए अनुमतियों का सेट बनाएं. पक्का करें कि सेट में मौजूद अनुमतियों का एलान, सबसे पहले आपके Android मेनिफ़ेस्ट में किया गया हो.
// Create a set of permissions for required data types
val PERMISSIONS =
setOf(
HealthPermission.getReadPermission(HeartRateRecord::class),
HealthPermission.getWritePermission(HeartRateRecord::class),
HealthPermission.getReadPermission(PlannedExerciseSessionRecord::class),
HealthPermission.getWritePermission(PlannedExerciseSessionRecord::class),
HealthPermission.getReadPermission(ExerciseSessionRecord::class),
HealthPermission.getWritePermission(ExerciseSessionRecord::class)
)
getGrantedPermissions
का इस्तेमाल करके देखें कि आपके ऐप्लिकेशन को ज़रूरी अनुमतियां पहले से मिली हुई हैं या नहीं. अगर ऐसा नहीं है, तो उन अनुमतियों का अनुरोध करने के लिए createRequestPermissionResultContract
का इस्तेमाल करें. इससे Health Connect की अनुमतियों वाली स्क्रीन दिखती है.
// Create the permissions launcher
val requestPermissionActivityContract = PermissionController.createRequestPermissionResultContract()
val requestPermissions = registerForActivityResult(requestPermissionActivityContract) { granted ->
if (granted.containsAll(PERMISSIONS)) {
// Permissions successfully granted
} else {
// Lack of required permissions
}
}
suspend fun checkPermissionsAndRun(healthConnectClient: HealthConnectClient) {
val granted = healthConnectClient.permissionController.getGrantedPermissions()
if (granted.containsAll(PERMISSIONS)) {
// Permissions already granted; proceed with inserting or reading data
} else {
requestPermissions.launch(PERMISSIONS)
}
}
उपयोगकर्ता किसी भी समय अनुमतियां दे सकते हैं या उन्हें रद्द कर सकते हैं. इसलिए, आपके ऐप्लिकेशन को समय-समय पर यह जांच करनी चाहिए कि कौनसी अनुमतियां दी गई हैं. साथ ही, उन स्थितियों को मैनेज करना चाहिए जिनमें अनुमति नहीं दी गई है.
मिलती-जुलती अनुमतियां
ट्रेनिंग प्लान, एक्सरसाइज़ सेशन से लिंक होते हैं. इसलिए, उपयोगकर्ता को ट्रेनिंग प्लान से जुड़े हर रिकॉर्ड टाइप का इस्तेमाल करने की अनुमति देनी होगी, ताकि Health Connect की इस सुविधा का पूरा फ़ायदा उठाया जा सके.
उदाहरण के लिए, अगर ट्रेनिंग प्लान में कई बार दौड़ने के दौरान किसी व्यक्ति की दिल की धड़कन को मापा जाता है, तो डेवलपर को ये अनुमतियां देनी पड़ सकती हैं. साथ ही, उपयोगकर्ता को ये अनुमतियां देनी पड़ सकती हैं, ताकि कसरत के सेशन को लिखा जा सके और बाद में आकलन करने के लिए नतीजे पढ़े जा सकें:
android.permission.health.READ_EXERCISE
android.permission.health.READ_EXERCISE_ROUTES
android.permission.health.READ_HEART_RATE
android.permission.health.WRITE_EXERCISE
android.permission.health.WRITE_EXERCISE_ROUTE
android.permission.health.WRITE_HEART_RATE
हालांकि, अक्सर ऐसा होता है कि ट्रेनिंग प्लान बनाने और प्लान के हिसाब से परफ़ॉर्मेंस का आकलन करने वाला ऐप्लिकेशन, ट्रेनिंग प्लान का इस्तेमाल करने और कसरत का असल डेटा लिखने वाले ऐप्लिकेशन से अलग होता है. ऐप्लिकेशन के टाइप के हिसाब से, पढ़ने और लिखने की सभी अनुमतियों की ज़रूरत नहीं होती. उदाहरण के लिए, आपको हर तरह के ऐप्लिकेशन के लिए सिर्फ़ इन अनुमतियों की ज़रूरत पड़ सकती है:
ट्रेनिंग प्लान ऐप्लिकेशन | वर्कआउट ऐप्लिकेशन |
---|---|
WRITE_PLANNED_EXERCISE |
READ_PLANNED_EXERCISE |
READ_EXERCISE |
WRITE_EXERCISE |
READ_EXERCISE_ROUTES |
WRITE_EXERCISE_ROUTE |
READ_HEART_RATE |
WRITE_HEART_RATE |
कसरत के प्लान किए गए सेशन के रिकॉर्ड में शामिल जानकारी
- सेशन का टाइटल.
- एक्सरसाइज़ के प्लान किए गए ब्लॉक की सूची.
- सेशन के शुरू और खत्म होने का समय.
- कसरत का टाइप.
- गतिविधि के लिए नोट.
- मेटाडेटा.
- एक्सरसाइज़ सेशन का आईडी — यह आईडी, प्लान किए गए एक्सरसाइज़ सेशन से जुड़े किसी एक्सरसाइज़ सेशन के पूरा होने के बाद अपने-आप लिखा जाता है.
प्लान की गई कसरत के ब्लॉक के रिकॉर्ड में शामिल जानकारी
प्लान किए गए वर्कआउट ब्लॉक में, वर्कआउट के चरणों की सूची होती है. इससे चरणों के अलग-अलग ग्रुप को दोहराने में मदद मिलती है. उदाहरण के लिए, आर्म कर्ल, बर्पी, और क्रंच को पांच बार दोहराएं.
- ब्लॉक के बारे में जानकारी.
- एक्सरसाइज़ के प्लान किए गए चरणों की सूची.
- दोहराव की संख्या.
कसरत के प्लान किए गए किसी चरण के रिकॉर्ड में शामिल जानकारी
- चरण के बारे में जानकारी.
- कसरत की कैटगरी.
- कसरत का टाइप.
- परफ़ॉर्मेंस के लक्ष्यों की सूची.
- पूरा होने का लक्ष्य.
इस्तेमाल किए जा सकने वाले एग्रीगेशन
इस डेटा टाइप के लिए, एग्रीगेशन की सुविधा काम नहीं करती.
इस्तेमाल का उदाहरण
मान लें कि किसी उपयोगकर्ता को दो दिन बाद 90 मिनट तक दौड़ लगानी है. इस रन में, झील के चारों ओर तीन लैप होंगे. साथ ही, धड़कन की दर 90 से 110 बीपीएम के बीच होनी चाहिए.
- उपयोगकर्ता ने ट्रेनिंग प्लान वाले ऐप्लिकेशन में, कसरत के लिए एक प्लान बनाया है. इसमें ये चीज़ें शामिल हैं:
- रन के शुरू और खत्म होने का प्लान किया गया समय
- कसरत का टाइप (दौड़ना)
- लैप की संख्या (दोहराव)
- धड़कन की दर के लिए परफ़ॉर्मेंस टारगेट (90 से 110 बीपीएम के बीच)
- इस जानकारी को कसरत के ब्लॉक और चरणों में ग्रुप किया जाता है. साथ ही, ट्रेनिंग प्लान ऐप्लिकेशन इसे Health Connect में
PlannedExerciseSessionRecord
के तौर पर सेव करता है. - उपयोगकर्ता प्लान किया गया सेशन (चालू है) पूरा करता है.
- सेशन से जुड़ा कसरत का डेटा इनमें से किसी एक तरीके से रिकॉर्ड किया जाता है:
- सेशन के दौरान, पहने जाने वाले डिवाइस से. उदाहरण के लिए, धड़कन की दर.
इस डेटा को Health Connect में, गतिविधि के रिकॉर्ड टाइप के तौर पर सेव किया जाता है. इस मामले में,
HeartRateRecord
. - उपयोगकर्ता, सेशन के बाद इसे मैन्युअल तरीके से सेट करता है. उदाहरण के लिए, दौड़ शुरू और खत्म होने का समय बताना. इस डेटा को Health Connect में
ExerciseSessionRecord
के तौर पर सेव किया जाता है.
- सेशन के दौरान, पहने जाने वाले डिवाइस से. उदाहरण के लिए, धड़कन की दर.
इस डेटा को Health Connect में, गतिविधि के रिकॉर्ड टाइप के तौर पर सेव किया जाता है. इस मामले में,
- बाद में, ट्रेनिंग प्लान ऐप्लिकेशन, Health Connect से डेटा पढ़ता है. इससे यह पता चलता है कि उपयोगकर्ता ने प्लान किए गए कसरत सेशन में जो टारगेट सेट किए थे उनके हिसाब से उसकी परफ़ॉर्मेंस कैसी रही.
एक्सरसाइज़ प्लान करना और टारगेट सेट करना
कोई उपयोगकर्ता आने वाले समय में की जाने वाली कसरत का प्लान बना सकता है और उसके लिए टारगेट सेट कर सकता है. इसे Health Connect में कसरत के प्लान किए गए सेशन के तौर पर लिखो.
इस्तेमाल का उदाहरण में बताए गए उदाहरण में, उपयोगकर्ता को दो दिन बाद 90 मिनट तक दौड़ लगानी है. इस रन में, झील के चारों ओर तीन लैप शामिल होंगे. इसमें धड़कन की दर 90 से 110 बीपीएम के बीच होनी चाहिए.
इस तरह का स्निपेट, किसी ऐसे ऐप्लिकेशन के फ़ॉर्म हैंडलर में मिल सकता है जो प्लान किए गए कसरत सेशन को Health Connect में लॉग करता है. इसे इंटिग्रेशन के लिए डेटा सोर्स में भी देखा जा सकता है. जैसे, ट्रेनिंग देने वाली किसी सेवा के साथ इंटिग्रेशन के लिए डेटा सोर्स.
// Verify the user has granted all necessary permissions for this task
val grantedPermissions =
healthConnectClient.permissionController.getGrantedPermissions()
if (!grantedPermissions.contains(
HealthPermission.getWritePermission(PlannedExerciseSessionRecord::class))) {
// The user hasn't granted the app permission to write planned exercise session data.
return
}
val plannedDuration = Duration.ofMinutes(90)
val plannedStartDate = LocalDate.now().plusDays(2)
val plannedExerciseSessionRecord = PlannedExerciseSessionRecord(
startDate = plannedStartDate,
duration = plannedDuration,
exerciseType = ExerciseSessionRecord.EXERCISE_TYPE_RUNNING,
blocks = listOf(
PlannedExerciseBlock(
repetitions = 1, steps = listOf(
PlannedExerciseStep(
exerciseType = ExerciseSegment.EXERCISE_SEGMENT_TYPE_RUNNING,
exercisePhase = PlannedExerciseStep.EXERCISE_PHASE_ACTIVE,
completionGoal = ExerciseCompletionGoal.RepetitionsGoal(repetitions = 3),
performanceTargets = listOf(
ExercisePerformanceTarget.HeartRateTarget(
minHeartRate = 90.0, maxHeartRate = 110.0
)
)
),
), description = "Three laps around the lake"
)
),
title = "Run at lake",
notes = null,
metadata = Metadata.manualEntry(
device = Device(type = Device.Companion.TYPE_PHONE)
)
)
val insertedPlannedExerciseSessions =
healthConnectClient.insertRecords(listOf(plannedExerciseSessionRecord)).recordIdsList
val insertedPlannedExerciseSessionId = insertedPlannedExerciseSessions.first()
कसरत और गतिविधि का डेटा लॉग करना
दो दिन बाद, उपयोगकर्ता ने कसरत का असली सेशन लॉग किया. इसे Health Connect में कसरत के सेशन के तौर पर सेव करो.
इस उदाहरण में, उपयोगकर्ता के सेशन की अवधि, प्लान की गई अवधि से पूरी तरह मेल खाती है.
यहां दिया गया स्निपेट, किसी ऐसे ऐप्लिकेशन के फ़ॉर्म हैंडलर में मिल सकता है जो कसरत के सेशन को Health Connect में लॉग करता है. यह डेटा, पहनने लायक ऐसे डिवाइस के डेटा को इकट्ठा करने और एक्सपोर्ट करने वाले हैंडलर में भी मिल सकता है जो कसरत के सेशन का पता लगा सकता है और उन्हें लॉग कर सकता है.
यहां insertedPlannedExerciseSessionId
का इस्तेमाल पिछले उदाहरण से किया गया है. असली ऐप्लिकेशन में, आईडी का पता तब चलेगा, जब उपयोगकर्ता मौजूदा सेशन की सूची से प्लान की गई कसरत का सेशन चुनेगा.
// Verify the user has granted all necessary permissions for this task
val grantedPermissions =
healthConnectClient.permissionController.getGrantedPermissions()
if (!grantedPermissions.contains(
HealthPermission.getWritePermission(ExerciseSessionRecord::class))) {
// The user doesn't granted the app permission to write exercise session data.
return
}
val sessionDuration = Duration.ofMinutes(90)
val sessionEndTime = Instant.now()
val sessionStartTime = sessionEndTime.minus(sessionDuration)
val exerciseSessionRecord = ExerciseSessionRecord(
startTime = sessionStartTime,
startZoneOffset = ZoneOffset.UTC,
endTime = sessionEndTime,
endZoneOffset = ZoneOffset.UTC,
exerciseType = ExerciseSessionRecord.EXERCISE_TYPE_RUNNING,
segments = listOf(
ExerciseSegment(
startTime = sessionStartTime,
endTime = sessionEndTime,
repetitions = 3,
segmentType = ExerciseSegment.EXERCISE_SEGMENT_TYPE_RUNNING
)
),
title = "Run at lake",
plannedExerciseSessionId = insertedPlannedExerciseSessionId,
metadata = Metadata.manualEntry(
device = Device(type = Device.Companion.TYPE_PHONE)
)
)
val insertedExerciseSessions =
healthConnectClient.insertRecords(listOf(exerciseSessionRecord))
साथ ही, पहनने लायक डिवाइस से दौड़ के दौरान धड़कन की दर का डेटा भी लॉग किया जाता है. नीचे दिए गए स्निपेट का इस्तेमाल, टारगेट रेंज में रिकॉर्ड जनरेट करने के लिए किया जा सकता है.
किसी असली ऐप्लिकेशन में, इस स्निपेट के मुख्य हिस्से, पहनने लायक डिवाइस से मिले मैसेज के हैंडलर में मिल सकते हैं. यह हैंडलर, डेटा इकट्ठा होने पर Health Connect में मेज़रमेंट लिखता है.
// Verify the user has granted all necessary permissions for this task
val grantedPermissions =
healthConnectClient.permissionController.getGrantedPermissions()
if (!grantedPermissions.contains(
HealthPermission.getWritePermission(HeartRateRecord::class))) {
// The user doesn't granted the app permission to write heart rate record data.
return
}
val samples = mutableListOf<HeartRateRecord.Sample>()
var currentTime = sessionStartTime
while (currentTime.isBefore(sessionEndTime)) {
val bpm = Random.nextInt(21) + 90
val heartRateRecord = HeartRateRecord.Sample(
time = currentTime,
beatsPerMinute = bpm.toLong(),
)
samples.add(heartRateRecord)
currentTime = currentTime.plusSeconds(180)
}
val heartRateRecord = HeartRateRecord(
startTime = sessionStartTime,
startZoneOffset = ZoneOffset.UTC,
endTime = sessionEndTime,
endZoneOffset = ZoneOffset.UTC,
samples = samples,
metadata = Metadata.autoRecorded(
device = Device(type = Device.Companion.TYPE_WATCH)
)
)
val insertedHeartRateRecords = healthConnectClient.insertRecords(listOf(heartRateRecord))
परफ़ॉर्मेंस टारगेट का आकलन करना
उपयोगकर्ता के वर्कआउट के अगले दिन, लॉग किए गए व्यायाम को वापस पाया जा सकता है. साथ ही, प्लान किए गए व्यायाम के किसी भी टारगेट की जांच की जा सकती है. इसके अलावा, सेट किए गए टारगेट पूरे हुए हैं या नहीं, यह पता लगाने के लिए अन्य डेटा टाइप का आकलन किया जा सकता है.
इस तरह का स्निपेट, परफ़ॉर्मेंस टारगेट का आकलन करने के लिए समय-समय पर किए जाने वाले काम में मिल सकता है. इसके अलावा, यह स्निपेट तब भी मिल सकता है, जब एक्सरसाइज़ की सूची लोड की जा रही हो और ऐप्लिकेशन में परफ़ॉर्मेंस टारगेट के बारे में सूचना दिखाई जा रही हो.
// Verify the user has granted all necessary permissions for this task
val grantedPermissions =
healthConnectClient.permissionController.getGrantedPermissions()
if (!grantedPermissions.containsAll(
listOf(
HealthPermission.getReadPermission(ExerciseSessionRecord::class),
HealthPermission.getReadPermission(PlannedExerciseSessionRecord::class),
HealthPermission.getReadPermission(HeartRateRecord::class)
)
)
) {
// The user doesn't granted the app permission to read exercise session record data.
return
}
val searchDuration = Duration.ofDays(1)
val searchEndTime = Instant.now()
val searchStartTime = searchEndTime.minus(searchDuration)
val response = healthConnectClient.readRecords(
ReadRecordsRequest<ExerciseSessionRecord>(
timeRangeFilter = TimeRangeFilter.between(searchStartTime, searchEndTime)
)
)
for (exerciseRecord in response.records) {
val plannedExerciseRecordId = exerciseRecord.plannedExerciseSessionId
val plannedExerciseRecord =
if (plannedExerciseRecordId == null) null else healthConnectClient.readRecord(
PlannedExerciseSessionRecord::class, plannedExerciseRecordId
).record
if (plannedExerciseRecord != null) {
val aggregateRequest = AggregateRequest(
metrics = setOf(HeartRateRecord.BPM_AVG),
timeRangeFilter = TimeRangeFilter.between(
exerciseRecord.startTime, exerciseRecord.endTime
),
)
val aggregationResult = healthConnectClient.aggregate(aggregateRequest)
val maxBpm = aggregationResult[HeartRateRecord.BPM_MAX]
val minBpm = aggregationResult[HeartRateRecord.BPM_MIN]
if (maxBpm != null && minBpm != null) {
plannedExerciseRecord.blocks.forEach { block ->
block.steps.forEach { step ->
step.performanceTargets.forEach { target ->
when (target) {
is ExercisePerformanceTarget.HeartRateTarget -> {
val minTarget = target.minHeartRate
val maxTarget = target.maxHeartRate
if(
minBpm >= minTarget && maxBpm <= maxTarget
) {
// Success!
}
}
// Handle more target types
}
}
}
}
}
}
}
}
कसरत के सेशन
एक्सरसाइज़ सेशन में, दौड़ने से लेकर बैडमिंटन खेलने तक कुछ भी शामिल हो सकता है.
कसरत के सेशन का डेटा सेव करने की अनुमति दें
सेशन शामिल करने का अनुरोध इस तरह बनाया जाता है:
suspend fun writeExerciseSession(healthConnectClient: HealthConnectClient) {
healthConnectClient.insertRecords(
listOf(
ExerciseSessionRecord(
startTime = START_TIME,
startZoneOffset = START_ZONE_OFFSET,
endTime = END_TIME,
endZoneOffset = END_ZONE_OFFSET,
exerciseType = ExerciseSessionRecord.ExerciseType.RUNNING,
title = "My Run"
),
// ... other records
)
)
}
कसरत के सेशन का डेटा पढ़ने की अनुमति दें
यहां कसरत के सेशन को पढ़ने का तरीका बताया गया है:
suspend fun readExerciseSessions(
healthConnectClient: HealthConnectClient,
startTime: Instant,
endTime: Instant
) {
val response =
healthConnectClient.readRecords(
ReadRecordsRequest(
ExerciseSessionRecord::class,
timeRangeFilter = TimeRangeFilter.between(startTime, endTime)
)
)
for (exerciseRecord in response.records) {
// Process each exercise record
// Optionally pull in with other data sources of the same time range.
val distanceRecord =
healthConnectClient
.readRecords(
ReadRecordsRequest(
DistanceRecord::class,
timeRangeFilter =
TimeRangeFilter.between(
exerciseRecord.startTime,
exerciseRecord.endTime
)
)
)
.records
}
}
सबटाइप का डेटा सेव करने की अनुमति दें
सेशन में, वैकल्पिक सबटाइप डेटा भी शामिल हो सकता है. इससे सेशन में ज़्यादा जानकारी मिलती है.
उदाहरण के लिए, कसरत वाले सेशन में ExerciseSegment
, ExerciseLap
, और ExerciseRoute
क्लास शामिल की जा सकती हैं:
val segments = listOf(
ExerciseSegment(
startTime = Instant.parse("2022-01-02T10:10:10Z"),
endTime = Instant.parse("2022-01-02T10:10:13Z"),
segmentType = ActivitySegmentType.BENCH_PRESS,
repetitions = 373
)
)
val laps = listOf(
ExerciseLap(
startTime = Instant.parse("2022-01-02T10:10:10Z"),
endTime = Instant.parse("2022-01-02T10:10:13Z"),
length = 0.meters
)
)
ExerciseSessionRecord(
exerciseType = ExerciseSessionRecord.EXERCISE_TYPE_CALISTHENICS,
startTime = Instant.parse("2022-01-02T10:10:10Z"),
endTime = Instant.parse("2022-01-02T10:10:13Z"),
startZoneOffset = ZoneOffset.UTC,
endZoneOffset = ZoneOffset.UTC,
segments = segments,
laps = laps,
route = route
)