यह गाइड, Health Connect के 1.1.0-alpha12 वर्शन के साथ काम करती है.
कसरत के रूट की मदद से, उपयोगकर्ता कसरत से जुड़ी गतिविधियों के लिए जीपीएस रूट को ट्रैक कर सकते हैं. साथ ही, अपने वर्कआउट के मैप को अन्य ऐप्लिकेशन के साथ शेयर कर सकते हैं.
यह देखना कि Health Connect मौजूद और चालू है या नहीं
Health Connect का इस्तेमाल करने से पहले, आपके ऐप्लिकेशन को यह पुष्टि करनी चाहिए कि उपयोगकर्ता के डिवाइस पर Health Connect इंस्टॉल हो. ऐसा हो सकता है कि Health Connect, सभी डिवाइसों पर पहले से इंस्टॉल न हो या इसे बंद कर दिया गया हो.
HealthConnectClient.getSdkStatus()
का इस्तेमाल करके, यह देखा जा सकता है कि Health Connect उपलब्ध है या नहीं.
यह देखने का तरीका कि Health Connect मौजूद और चालू है या नहीं
fun checkHealthConnectAvailability(context: Context) { val providerPackageName = "com.google.android.apps.healthdata" // Or get from HealthConnectClient.DEFAULT_PROVIDER_PACKAGE_NAME val availabilityStatus = HealthConnectClient.getSdkStatus(context, providerPackageName) if (availabilityStatus == HealthConnectClient.SDK_UNAVAILABLE) { // Health Connect is not available. Guide the user to install/enable it. // For example, show a dialog. return // early return as there is no viable integration } if (availabilityStatus == HealthConnectClient.SDK_UNAVAILABLE_PROVIDER_UPDATE_REQUIRED) { // Health Connect is available but requires an update. // Optionally redirect to package installer to find a provider, for example: val uriString = "market://details?id=$providerPackageName&url=healthconnect%3A%2F%2Fonboarding" context.startActivity( Intent(Intent.ACTION_VIEW).apply { setPackage("com.android.vending") data = Uri.parse(uriString) putExtra("overlay", true) putExtra("callerId", context.packageName) } ) return } // Health Connect is available, obtain a HealthConnectClient instance val healthConnectClient = HealthConnectClient.getOrCreate(context) // Issue operations with healthConnectClient }
getSdkStatus() से मिले स्टेटस के आधार पर, ज़रूरी होने पर उपयोगकर्ता को Google Play Store से 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_EXERCISE_ROUTESandroid.permission.health.WRITE_EXERCISE_ROUTE
READ_EXERCISE_ROUTES बहुवचन है, जबकि WRITE_EXERCISE_ROUTE एकवचन है.
अपने ऐप्लिकेशन में कसरत के रूट की जानकारी देने की सुविधा जोड़नी है, तो ExerciseSession डेटा टाइप के लिए, अनुमतियों का अनुरोध करें.
यहां उस अनुमति के बारे में बताया गया है जिसके बारे में आपको एलान करना होगा, ताकि कसरत के रूट से जुड़े डेटा में बदलाव किया जा सके:
<application>
<uses-permission
android:name="android.permission.health.WRITE_EXERCISE_ROUTE" />
...
</application>
कसरत के रूट की जानकारी ऐक्सेस करने के लिए, आपको ये अनुमतियां मांगनी होंगी:
<application>
<uses-permission
android:name="android.permission.health.READ_EXERCISE_ROUTES" />
...
</application>
आपको कसरत की अनुमति के बारे में भी एलान करना होगा, क्योंकि हर रूट किसी कसरत सेशन से जुड़ा होता है (एक सेशन = एक वर्कआउट).
अनुमतियों का अनुरोध करने के लिए, अपने ऐप्लिकेशन को पहली बार Health Connect से कनेक्ट करते समय, PermissionController.createRequestPermissionResultContract() तरीके का इस्तेमाल करें. यहां कुछ अनुमतियां दी गई हैं जिनके लिए अनुरोध किया जा सकता है:
- सेहत और फ़िटनेस से जुड़ा डेटा पढ़ने की अनुमति. इसमें रास्ते का डेटा भी शामिल है:
HealthPermission.getReadPermission(ExerciseSessionRecord::class) - सेहत और फ़िटनेस से जुड़ा डेटा लिखना, जिसमें रास्ते का डेटा भी शामिल है:
HealthPermission.getWritePermission(ExerciseSessionRecord::class) - कसरत के रूट का डेटा सेव करने की अनुमति:
HealthPermission.PERMISSION_WRITE_EXERCISE_ROUTE
उपयोगकर्ता से अनुमतियों का अनुरोध करना
क्लाइंट इंस्टेंस बनाने के बाद, आपके ऐप्लिकेशन को उपयोगकर्ता से अनुमतियों का अनुरोध करना होगा. उपयोगकर्ताओं के पास किसी भी समय अनुमतियां देने या अस्वीकार करने का विकल्प ज़रूर होना चाहिए.
इसके लिए, ज़रूरी डेटा टाइप के लिए अनुमतियों का सेट बनाएं. पक्का करें कि सेट में मौजूद अनुमतियों का एलान, सबसे पहले आपके Android मेनिफ़ेस्ट में किया गया हो.
// Create a set of permissions for required data types
val PERMISSIONS =
setOf(
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)
}
}
उपयोगकर्ता किसी भी समय अनुमतियां दे सकते हैं या उन्हें रद्द कर सकते हैं. इसलिए, आपके ऐप्लिकेशन को हर बार अनुमतियों का इस्तेमाल करने से पहले, उनकी जांच करनी होगी. साथ ही, उन स्थितियों को मैनेज करना होगा जिनमें अनुमति नहीं दी गई है.
कसरत के सेशन के रिकॉर्ड में शामिल जानकारी
कसरत के हर सेशन के रिकॉर्ड में यह जानकारी शामिल होती है:
- कसरत का टाइप, जैसे कि साइकल चलाना.
- कसरत का रास्ता, जिसमें अक्षांश, देशांतर, और ऊंचाई जैसी जानकारी शामिल होती है.
इस्तेमाल किए जा सकने वाले एग्रीगेशन
ExerciseSessionRecord के लिए, ये एग्रीगेट वैल्यू उपलब्ध हैं:
उदाहरण उपयोग
यहां दिए गए कोड स्निपेट में, कसरत के रास्ते को पढ़ने और लिखने का तरीका बताया गया है.
कसरत का रूट देखें
बैकग्राउंड में चलने पर, आपका ऐप्लिकेशन अन्य ऐप्लिकेशन से बनाए गए कसरत के रूट का डेटा नहीं पढ़ सकता.
जब आपका ऐप्लिकेशन बैकग्राउंड में चलता है और किसी दूसरे ऐप्लिकेशन से बनाए गए कसरत के रूट को पढ़ने की कोशिश करता है, तो Health Connect ExerciseRouteResult.ConsentRequiredजवाब देता है. भले ही, आपके ऐप्लिकेशन के पास कसरत के रूट के डेटा को हमेशा अनुमति दें का ऐक्सेस हो.
इस वजह से, हमारा सुझाव है कि आप रूट के लिए अनुरोध तब करें, जब उपयोगकर्ता आपके ऐप्लिकेशन के यूज़र इंटरफ़ेस (यूआई) के साथ सक्रिय रूप से इंटरैक्ट कर रहा हो.
बैकग्राउंड में डेटा पढ़ने की सुविधा के बारे में ज़्यादा जानने के लिए, बैकग्राउंड में डेटा पढ़ने की सुविधा का उदाहरण देखें.
यहां दिए गए कोड स्निपेट में, Health Connect में किसी सेशन को पढ़ने और उस सेशन से रूट का अनुरोध करने का तरीका बताया गया है:
private suspend fun readExerciseSessionAndRoute() { val client = healthConnectClient ?: return val endTime = Instant.now() val startTime = endTime.minus(Duration.ofHours(1)) val grantedPermissions = client.permissionController.getGrantedPermissions() // 1. Verify basic Exercise Session permissions if (!grantedPermissions.contains( HealthPermission.getReadPermission(ExerciseSessionRecord::class) ) ) { return } // 2. Read the sessions val readResponse = client.readRecords( ReadRecordsRequest( ExerciseSessionRecord::class, TimeRangeFilter.between(startTime, endTime) ) ) val exerciseRecord = readResponse.records.firstOrNull() ?: return val recordId = exerciseRecord.metadata.id // 3. Read the specific record to check for the route val sessionResponse = client.readRecord(ExerciseSessionRecord::class, recordId) // 4. Handle the Route Result directly from the response when (val routeResult = sessionResponse.record.exerciseRouteResult) { is ExerciseRouteResult.Data -> { displayExerciseRoute(routeResult.exerciseRoute) } is ExerciseRouteResult.ConsentRequired -> { // Since you are in a Service, you cannot launch ActivityResultLauncher. // Send a notification to the user to grant route-specific consent. handleConsentRequired(recordId) } is ExerciseRouteResult.NoData -> Unit else -> Unit } } private fun displayExerciseRoute(route: ExerciseRoute) { val locations = route.route.orEmpty() for (location in locations) { println(location) } }
कसरत का रूट सेव करने की अनुमति
यहां दिए गए कोड में, किसी ऐसे सेशन को रिकॉर्ड करने का तरीका बताया गया है जिसमें कसरत का रूट शामिल है:
private suspend fun insertExerciseRoute() { val client = healthConnectClient ?: return val grantedPermissions = client.permissionController.getGrantedPermissions() // 1. Verify Session Write Permission val hasWriteSession = grantedPermissions.contains( HealthPermission.getWritePermission(ExerciseSessionRecord::class) ) if (!hasWriteSession) return val sessionStartTime = Instant.now() val sessionDuration = Duration.ofMinutes(20) val sessionEndTime = sessionStartTime.plus(sessionDuration) // 2. Build the route if route-specific write permission is granted val hasWriteRoute = grantedPermissions.contains(HealthPermission.PERMISSION_WRITE_EXERCISE_ROUTE) val exerciseRoute = if (hasWriteRoute) { ExerciseRoute( listOf( ExerciseRoute.Location( time = sessionStartTime, latitude = 6.5483, longitude = 0.5488, horizontalAccuracy = Length.meters(2.0), verticalAccuracy = Length.meters(2.0), altitude = Length.meters(9.0), ), ExerciseRoute.Location( time = sessionEndTime.minusSeconds(1), latitude = 6.4578, longitude = 0.6577, horizontalAccuracy = Length.meters(2.0), verticalAccuracy = Length.meters(2.0), altitude = Length.meters(9.2), ) ) ) } else { null } // 3. Create the session record val exerciseSessionRecord = ExerciseSessionRecord( startTime = sessionStartTime, startZoneOffset = ZoneOffset.UTC, endTime = sessionEndTime, endZoneOffset = ZoneOffset.UTC, exerciseType = ExerciseSessionRecord.EXERCISE_TYPE_BIKING, title = "Morning Bike Ride", exerciseRoute = exerciseRoute, metadata = Metadata( device = Device(type = Device.TYPE_PHONE) ) ) // 4. Insert into Health Connect client.insertRecords(listOf(exerciseSessionRecord)) }
कसरत के सेशन
कसरत के सेशन में, दौड़ने से लेकर बैडमिंटन खेलने तक कुछ भी शामिल हो सकता है.
कसरत के सेशन का डेटा सेव करने की अनुमति
सेशन शामिल करने का अनुरोध इस तरह बनाया जाता है:
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",
metadata = Metadata.manualEntry()
),
// ... 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,
metadata = Metadata.manualEntry()
)
कसरत का कोई सेशन मिटाना
कसरत के सेशन को मिटाने के दो तरीके हैं:
- समयसीमा के हिसाब से.
- यूआईडी के हिसाब से.
यहां समयसीमा के हिसाब से सबटाइप का डेटा मिटाने का तरीका बताया गया है:
suspend fun deleteExerciseSessionByTimeRange( healthConnectClient: HealthConnectClient, exerciseRecord: ExerciseSessionRecord, ) { val timeRangeFilter = TimeRangeFilter.between(exerciseRecord.startTime, exerciseRecord.endTime) healthConnectClient.deleteRecords(ExerciseSessionRecord::class, timeRangeFilter) // delete the associated distance record healthConnectClient.deleteRecords(DistanceRecord::class, timeRangeFilter) }
यूआईडी के हिसाब से भी सबटाइप का डेटा मिटाया जा सकता है. ऐसा करने से सिर्फ़ कसरत का सेशन मिटता है, उससे जुड़ा डेटा नहीं:
suspend fun deleteExerciseSessionByUid( healthConnectClient: HealthConnectClient, exerciseRecord: ExerciseSessionRecord, ) { healthConnectClient.deleteRecords( ExerciseSessionRecord::class, recordIdsList = listOf(exerciseRecord.metadata.id), clientRecordIdsList = emptyList() ) }