@asiriindatissa/capacitor-health 8.2.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md ADDED
@@ -0,0 +1,426 @@
1
+ # @asiriindatissa/capacitor-health
2
+
3
+ Capacitor plugin to read and write health metrics via Health Connect on Android. The TypeScript API provides a unified interface for health data access.
4
+
5
+ ## Why Capacitor Health?
6
+
7
+ The only **free**, **unified** health data plugin for Capacitor supporting the latest native APIs:
8
+
9
+ - **Health Connect (Android)** - Uses Google's newest health platform (replaces deprecated Google Fit)
10
+ - **Unified API** - TypeScript interface with consistent units
11
+ - **Multiple metrics** - Steps, distance, calories, heart rate, weight
12
+ - **Read & Write** - Query historical data and save new health entries
13
+ - **Modern standards** - Supports Android 8.0+
14
+
15
+ Perfect for fitness apps, health trackers, wellness platforms, and medical applications.
16
+
17
+ ## Install
18
+
19
+ ```bash
20
+ npm install @asiriindatissa/capacitor-health
21
+ npx cap sync
22
+ ```
23
+
24
+ ## Android Setup
25
+
26
+ This plugin now uses [Health Connect](https://developer.android.com/health-and-fitness/guides/health-connect) instead of Google Fit. Make sure your app meets the requirements below:
27
+
28
+ 1. **Min SDK 26+.** Health Connect is only available on Android 8.0 (API 26) and above. The plugin's Gradle setup already targets this level.
29
+ 2. **Declare Health permissions.** The plugin manifest ships with the required `<uses-permission>` declarations (`READ_/WRITE_STEPS`, `READ_/WRITE_DISTANCE`, `READ_/WRITE_ACTIVE_CALORIES_BURNED`, `READ_/WRITE_HEART_RATE`, `READ_/WRITE_WEIGHT`). Your app does not need to duplicate them, but you must surface a user-facing rationale because the permissions are considered health sensitive.
30
+ 3. **Ensure Health Connect is installed.** Devices on Android 14+ include it by default. For earlier versions the user must install _Health Connect by Android_ from the Play Store. The `Health.isAvailable()` helper exposes the current status so you can prompt accordingly.
31
+ 4. **Request runtime access.** The plugin opens the Health Connect permission UI when you call `requestAuthorization`. You should still handle denial flows (e.g., show a message if `checkAuthorization` reports missing scopes).
32
+ 5. **Provide a Privacy Policy.** Health Connect requires apps to display a privacy policy explaining how health data is used. See the [Privacy Policy Setup](#privacy-policy-setup) section below.
33
+
34
+ If you already used Google Fit in your project you can remove the associated dependencies (`play-services-fitness`, `play-services-auth`, OAuth configuration, etc.).
35
+
36
+ ### Privacy Policy Setup
37
+
38
+ Health Connect requires your app to provide a privacy policy that explains how you handle health data. When users tap "Privacy policy" in the Health Connect permissions dialog, your app must display this information.
39
+
40
+ **Option 1: HTML file in assets (recommended for simple cases)**
41
+
42
+ Place an HTML file at `android/app/src/main/assets/public/privacypolicy.html`:
43
+
44
+ ```html
45
+ <!DOCTYPE html>
46
+ <html>
47
+ <head>
48
+ <meta charset="utf-8" />
49
+ <meta name="viewport" content="width=device-width, initial-scale=1" />
50
+ <title>Privacy Policy</title>
51
+ </head>
52
+ <body>
53
+ <h1>Privacy Policy</h1>
54
+ <p>Your privacy policy content here...</p>
55
+ <h2>Health Data</h2>
56
+ <p>Explain how you collect, use, and protect health data...</p>
57
+ </body>
58
+ </html>
59
+ ```
60
+
61
+ **Option 2: Custom URL (recommended for hosted privacy policies)**
62
+
63
+ Add a string resource to your app's `android/app/src/main/res/values/strings.xml`:
64
+
65
+ ```xml
66
+ <resources>
67
+ <!-- Your other strings... -->
68
+ <string name="health_connect_privacy_policy_url">https://yourapp.com/privacy-policy</string>
69
+ </resources>
70
+ ```
71
+
72
+ This URL will be loaded in a WebView when the user requests to see your privacy policy.
73
+
74
+ **Programmatic access:**
75
+
76
+ You can also show the privacy policy or open Health Connect settings from your app:
77
+
78
+ ```ts
79
+ // Show the privacy policy screen
80
+ await Health.showPrivacyPolicy();
81
+
82
+ // Open Health Connect settings (useful for managing permissions)
83
+ await Health.openHealthConnectSettings();
84
+ ```
85
+
86
+ ## Usage
87
+
88
+ ```ts
89
+ import { Health } from '@asiriindatissa/capacitor-health';
90
+
91
+ // Verify that the native health SDK is present on this device
92
+ const availability = await Health.isAvailable();
93
+ if (!availability.available) {
94
+ console.warn('Health access unavailable:', availability.reason);
95
+ }
96
+
97
+ // Ask for separate read/write access scopes
98
+ await Health.requestAuthorization({
99
+ read: ['steps', 'heartRate', 'weight'],
100
+ write: ['weight'],
101
+ });
102
+
103
+ // Query the last 50 step samples from the past 24 hours
104
+ const { samples } = await Health.readSamples({
105
+ dataType: 'steps',
106
+ startDate: new Date(Date.now() - 24 * 60 * 60 * 1000).toISOString(),
107
+ endDate: new Date().toISOString(),
108
+ limit: 50,
109
+ });
110
+
111
+ // Persist a new body-weight entry (kilograms by default)
112
+ await Health.saveSample({
113
+ dataType: 'weight',
114
+ value: 74.3,
115
+ });
116
+ ```
117
+
118
+ ### Supported data types
119
+
120
+ | Identifier | Default unit | Notes |
121
+ | ----------- | ------------- | -------------------------- |
122
+ | `steps` | `count` | Step count deltas |
123
+ | `distance` | `meter` | Walking / running distance |
124
+ | `calories` | `kilocalorie` | Active energy burned |
125
+ | `heartRate` | `bpm` | Beats per minute |
126
+ | `weight` | `kilogram` | Body mass |
127
+
128
+ All write operations expect the default unit shown above. On Android the `metadata` option is currently ignored by Health Connect.
129
+
130
+ ## API
131
+
132
+ <docgen-index>
133
+
134
+ * [`isAvailable()`](#isavailable)
135
+ * [`requestAuthorization(...)`](#requestauthorization)
136
+ * [`checkAuthorization(...)`](#checkauthorization)
137
+ * [`readSamples(...)`](#readsamples)
138
+ * [`saveSample(...)`](#savesample)
139
+ * [`getPluginVersion()`](#getpluginversion)
140
+ * [`openHealthConnectSettings()`](#openhealthconnectsettings)
141
+ * [`showPrivacyPolicy()`](#showprivacypolicy)
142
+ * [`queryWorkouts(...)`](#queryworkouts)
143
+ * [Interfaces](#interfaces)
144
+ * [Type Aliases](#type-aliases)
145
+
146
+ </docgen-index>
147
+
148
+ <docgen-api>
149
+ <!--Update the source file JSDoc comments and rerun docgen to update the docs below-->
150
+
151
+ ### isAvailable()
152
+
153
+ ```typescript
154
+ isAvailable() => Promise<AvailabilityResult>
155
+ ```
156
+
157
+ Returns whether the current platform supports the native health SDK.
158
+
159
+ **Returns:** <code>Promise&lt;<a href="#availabilityresult">AvailabilityResult</a>&gt;</code>
160
+
161
+ --------------------
162
+
163
+
164
+ ### requestAuthorization(...)
165
+
166
+ ```typescript
167
+ requestAuthorization(options: AuthorizationOptions) => Promise<AuthorizationStatus>
168
+ ```
169
+
170
+ Requests read/write access to the provided data types.
171
+
172
+ | Param | Type |
173
+ | ------------- | --------------------------------------------------------------------- |
174
+ | **`options`** | <code><a href="#authorizationoptions">AuthorizationOptions</a></code> |
175
+
176
+ **Returns:** <code>Promise&lt;<a href="#authorizationstatus">AuthorizationStatus</a>&gt;</code>
177
+
178
+ --------------------
179
+
180
+
181
+ ### checkAuthorization(...)
182
+
183
+ ```typescript
184
+ checkAuthorization(options: AuthorizationOptions) => Promise<AuthorizationStatus>
185
+ ```
186
+
187
+ Checks authorization status for the provided data types without prompting the user.
188
+
189
+ | Param | Type |
190
+ | ------------- | --------------------------------------------------------------------- |
191
+ | **`options`** | <code><a href="#authorizationoptions">AuthorizationOptions</a></code> |
192
+
193
+ **Returns:** <code>Promise&lt;<a href="#authorizationstatus">AuthorizationStatus</a>&gt;</code>
194
+
195
+ --------------------
196
+
197
+
198
+ ### readSamples(...)
199
+
200
+ ```typescript
201
+ readSamples(options: QueryOptions) => Promise<ReadSamplesResult>
202
+ ```
203
+
204
+ Reads samples for the given data type within the specified time frame.
205
+
206
+ | Param | Type |
207
+ | ------------- | ----------------------------------------------------- |
208
+ | **`options`** | <code><a href="#queryoptions">QueryOptions</a></code> |
209
+
210
+ **Returns:** <code>Promise&lt;<a href="#readsamplesresult">ReadSamplesResult</a>&gt;</code>
211
+
212
+ --------------------
213
+
214
+
215
+ ### saveSample(...)
216
+
217
+ ```typescript
218
+ saveSample(options: WriteSampleOptions) => Promise<void>
219
+ ```
220
+
221
+ Writes a single sample to the native health store.
222
+
223
+ | Param | Type |
224
+ | ------------- | ----------------------------------------------------------------- |
225
+ | **`options`** | <code><a href="#writesampleoptions">WriteSampleOptions</a></code> |
226
+
227
+ --------------------
228
+
229
+
230
+ ### getPluginVersion()
231
+
232
+ ```typescript
233
+ getPluginVersion() => Promise<{ version: string; }>
234
+ ```
235
+
236
+ Get the native Capacitor plugin version
237
+
238
+ **Returns:** <code>Promise&lt;{ version: string; }&gt;</code>
239
+
240
+ --------------------
241
+
242
+
243
+ ### openHealthConnectSettings()
244
+
245
+ ```typescript
246
+ openHealthConnectSettings() => Promise<void>
247
+ ```
248
+
249
+ Opens the Health Connect settings screen.
250
+
251
+ Use this to direct users to manage their Health Connect permissions
252
+ or to install Health Connect if not available.
253
+
254
+ --------------------
255
+
256
+
257
+ ### showPrivacyPolicy()
258
+
259
+ ```typescript
260
+ showPrivacyPolicy() => Promise<void>
261
+ ```
262
+
263
+ Shows the app's privacy policy for Health Connect.
264
+
265
+ This displays the same privacy policy screen that Health Connect shows
266
+ when the user taps "Privacy policy" in the permissions dialog.
267
+
268
+ The privacy policy URL can be configured by adding a string resource
269
+ named "health_connect_privacy_policy_url" in your app's strings.xml,
270
+ or by placing an HTML file at www/privacypolicy.html in your assets.
271
+
272
+ --------------------
273
+
274
+
275
+ ### queryWorkouts(...)
276
+
277
+ ```typescript
278
+ queryWorkouts(options: QueryWorkoutsOptions) => Promise<QueryWorkoutsResult>
279
+ ```
280
+
281
+ Queries workout sessions from the native health store on Android (Health Connect).
282
+
283
+ | Param | Type | Description |
284
+ | ------------- | --------------------------------------------------------------------- | --------------------------------------------------------------------------------------- |
285
+ | **`options`** | <code><a href="#queryworkoutsoptions">QueryWorkoutsOptions</a></code> | Query options including optional workout type filter, date range, limit, and sort order |
286
+
287
+ **Returns:** <code>Promise&lt;<a href="#queryworkoutsresult">QueryWorkoutsResult</a>&gt;</code>
288
+
289
+ --------------------
290
+
291
+
292
+ ### Interfaces
293
+
294
+
295
+ #### AvailabilityResult
296
+
297
+ | Prop | Type | Description |
298
+ | --------------- | ------------------------------- | ------------------------------------------------------ |
299
+ | **`available`** | <code>boolean</code> | |
300
+ | **`platform`** | <code>'android' \| 'web'</code> | Platform specific details (for debugging/diagnostics). |
301
+ | **`reason`** | <code>string</code> | |
302
+
303
+
304
+ #### AuthorizationStatus
305
+
306
+ | Prop | Type |
307
+ | --------------------- | ----------------------------- |
308
+ | **`readAuthorized`** | <code>HealthDataType[]</code> |
309
+ | **`readDenied`** | <code>HealthDataType[]</code> |
310
+ | **`writeAuthorized`** | <code>HealthDataType[]</code> |
311
+ | **`writeDenied`** | <code>HealthDataType[]</code> |
312
+
313
+
314
+ #### AuthorizationOptions
315
+
316
+ | Prop | Type | Description |
317
+ | ----------- | ----------------------------- | ------------------------------------------------------- |
318
+ | **`read`** | <code>HealthDataType[]</code> | Data types that should be readable after authorization. |
319
+ | **`write`** | <code>HealthDataType[]</code> | Data types that should be writable after authorization. |
320
+
321
+
322
+ #### ReadSamplesResult
323
+
324
+ | Prop | Type |
325
+ | ------------- | --------------------------- |
326
+ | **`samples`** | <code>HealthSample[]</code> |
327
+
328
+
329
+ #### HealthSample
330
+
331
+ | Prop | Type |
332
+ | ---------------- | --------------------------------------------------------- |
333
+ | **`dataType`** | <code><a href="#healthdatatype">HealthDataType</a></code> |
334
+ | **`value`** | <code>number</code> |
335
+ | **`unit`** | <code><a href="#healthunit">HealthUnit</a></code> |
336
+ | **`startDate`** | <code>string</code> |
337
+ | **`endDate`** | <code>string</code> |
338
+ | **`sourceName`** | <code>string</code> |
339
+ | **`sourceId`** | <code>string</code> |
340
+
341
+
342
+ #### QueryOptions
343
+
344
+ | Prop | Type | Description |
345
+ | --------------- | --------------------------------------------------------- | ------------------------------------------------------------------ |
346
+ | **`dataType`** | <code><a href="#healthdatatype">HealthDataType</a></code> | The type of data to retrieve from the health store. |
347
+ | **`startDate`** | <code>string</code> | Inclusive ISO 8601 start date (defaults to now - 1 day). |
348
+ | **`endDate`** | <code>string</code> | Exclusive ISO 8601 end date (defaults to now). |
349
+ | **`limit`** | <code>number</code> | Maximum number of samples to return (defaults to 100). |
350
+ | **`ascending`** | <code>boolean</code> | Return results sorted ascending by start date (defaults to false). |
351
+
352
+
353
+ #### WriteSampleOptions
354
+
355
+ | Prop | Type | Description |
356
+ | --------------- | --------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
357
+ | **`dataType`** | <code><a href="#healthdatatype">HealthDataType</a></code> | |
358
+ | **`value`** | <code>number</code> | |
359
+ | **`unit`** | <code><a href="#healthunit">HealthUnit</a></code> | Optional unit override. If omitted, the default unit for the data type is used (count for `steps`, meter for `distance`, kilocalorie for `calories`, bpm for `heartRate`, kilogram for `weight`). |
360
+ | **`startDate`** | <code>string</code> | ISO 8601 start date for the sample. Defaults to now. |
361
+ | **`endDate`** | <code>string</code> | ISO 8601 end date for the sample. Defaults to startDate. |
362
+ | **`metadata`** | <code><a href="#record">Record</a>&lt;string, string&gt;</code> | Metadata key-value pairs forwarded to the native APIs where supported. |
363
+
364
+
365
+ #### QueryWorkoutsResult
366
+
367
+ | Prop | Type |
368
+ | -------------- | ---------------------- |
369
+ | **`workouts`** | <code>Workout[]</code> |
370
+
371
+
372
+ #### Workout
373
+
374
+ | Prop | Type | Description |
375
+ | ----------------------- | --------------------------------------------------------------- | --------------------------------------------------- |
376
+ | **`workoutType`** | <code><a href="#workouttype">WorkoutType</a></code> | The type of workout. |
377
+ | **`duration`** | <code>number</code> | Duration of the workout in seconds. |
378
+ | **`totalEnergyBurned`** | <code>number</code> | Total energy burned in kilocalories (if available). |
379
+ | **`totalDistance`** | <code>number</code> | Total distance in meters (if available). |
380
+ | **`startDate`** | <code>string</code> | ISO 8601 start date of the workout. |
381
+ | **`endDate`** | <code>string</code> | ISO 8601 end date of the workout. |
382
+ | **`sourceName`** | <code>string</code> | Source name that recorded the workout. |
383
+ | **`sourceId`** | <code>string</code> | Source bundle identifier. |
384
+ | **`metadata`** | <code><a href="#record">Record</a>&lt;string, string&gt;</code> | Additional metadata (if available). |
385
+
386
+
387
+ #### QueryWorkoutsOptions
388
+
389
+ | Prop | Type | Description |
390
+ | ----------------- | --------------------------------------------------- | ------------------------------------------------------------------------- |
391
+ | **`workoutType`** | <code><a href="#workouttype">WorkoutType</a></code> | Optional workout type filter. If omitted, all workout types are returned. |
392
+ | **`startDate`** | <code>string</code> | Inclusive ISO 8601 start date (defaults to now - 1 day). |
393
+ | **`endDate`** | <code>string</code> | Exclusive ISO 8601 end date (defaults to now). |
394
+ | **`limit`** | <code>number</code> | Maximum number of workouts to return (defaults to 100). |
395
+ | **`ascending`** | <code>boolean</code> | Return results sorted ascending by start date (defaults to false). |
396
+
397
+
398
+ ### Type Aliases
399
+
400
+
401
+ #### HealthDataType
402
+
403
+ <code>'steps' | 'distance' | 'calories' | 'heartRate' | 'weight'</code>
404
+
405
+
406
+ #### HealthUnit
407
+
408
+ <code>'count' | 'meter' | 'kilocalorie' | 'bpm' | 'kilogram'</code>
409
+
410
+
411
+ #### Record
412
+
413
+ Construct a type with a set of properties K of type T
414
+
415
+ <code>{
416
  [P in K]: T;
1
417
  }</code>
418
+
419
+
420
+ #### WorkoutType
421
+
422
+ <code>'running' | 'cycling' | 'walking' | 'swimming' | 'yoga' | 'strengthTraining' | 'hiking' | 'tennis' | 'basketball' | 'soccer' | 'americanFootball' | 'baseball' | 'crossTraining' | 'elliptical' | 'rowing' | 'stairClimbing' | 'traditionalStrengthTraining' | 'waterFitness' | 'waterPolo' | 'waterSports' | 'wrestling' | 'other'</code>
423
+
424
+ </docgen-api>
425
+
426
+ ### Credits:
427
+
428
+ this plugin was inspired by the work of https://github.com/perfood/capacitor-google-fit for Android
@@ -0,0 +1,70 @@
1
+ def kotlinVersion = '1.9.25'
2
+ project.ext.kotlinVersion = kotlinVersion
3
+
4
+ ext {
5
+ junitVersion = '4.13.2'
6
+ androidxAppCompatVersion = '1.7.1'
7
+ androidxJunitVersion = '1.2.1'
8
+ androidxEspressoCoreVersion = '3.6.1'
9
+ }
10
+
11
+ buildscript {
12
+ repositories {
13
+ google()
14
+ mavenCentral()
15
+ }
16
+ dependencies {
17
+ classpath 'com.android.tools.build:gradle:8.13.0'
18
+ classpath 'org.jetbrains.kotlin:kotlin-gradle-plugin:1.9.25'
19
+ }
20
+ }
21
+
22
+ apply plugin: 'com.android.library'
23
+ apply plugin: 'org.jetbrains.kotlin.android'
24
+
25
+ android {
26
+ namespace = "app.capgo.plugin.health"
27
+ compileSdk = 36
28
+
29
+ defaultConfig {
30
+ minSdk 26
31
+ targetSdk 36
32
+ versionCode 1
33
+ versionName "1.0"
34
+ testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
35
+ }
36
+ buildTypes {
37
+ release {
38
+ minifyEnabled false
39
+ proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
40
+ }
41
+ }
42
+ lint {
43
+ abortOnError = false
44
+ }
45
+ compileOptions {
46
+ sourceCompatibility JavaVersion.VERSION_21
47
+ targetCompatibility JavaVersion.VERSION_21
48
+ }
49
+ kotlinOptions {
50
+ jvmTarget = JavaVersion.VERSION_21.toString()
51
+ }
52
+ }
53
+
54
+ repositories {
55
+ google()
56
+ mavenCentral()
57
+ }
58
+
59
+
60
+ dependencies {
61
+ implementation fileTree(dir: 'libs', include: ['*.jar'])
62
+ implementation project(':capacitor-android')
63
+ implementation "androidx.appcompat:appcompat:${androidxAppCompatVersion}"
64
+ implementation ("org.jetbrains.kotlin:kotlin-stdlib:" + project.ext.kotlinVersion)
65
+ implementation 'androidx.health.connect:connect-client:1.1.0-alpha10'
66
+ implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-android:1.8.1'
67
+ testImplementation "junit:junit:${junitVersion}"
68
+ androidTestImplementation "androidx.test.ext:junit:${androidxJunitVersion}"
69
+ androidTestImplementation "androidx.test.espresso:espresso-core:${androidxEspressoCoreVersion}"
70
+ }
@@ -0,0 +1,41 @@
1
+ <manifest xmlns:android="http://schemas.android.com/apk/res/android">
2
+ <uses-permission android:name="android.permission.health.READ_STEPS" />
3
+ <uses-permission android:name="android.permission.health.WRITE_STEPS" />
4
+ <uses-permission android:name="android.permission.health.READ_DISTANCE" />
5
+ <uses-permission android:name="android.permission.health.WRITE_DISTANCE" />
6
+ <uses-permission android:name="android.permission.health.READ_ACTIVE_CALORIES_BURNED" />
7
+ <uses-permission android:name="android.permission.health.WRITE_ACTIVE_CALORIES_BURNED" />
8
+ <uses-permission android:name="android.permission.health.READ_HEART_RATE" />
9
+ <uses-permission android:name="android.permission.health.WRITE_HEART_RATE" />
10
+ <uses-permission android:name="android.permission.health.READ_WEIGHT" />
11
+ <uses-permission android:name="android.permission.health.WRITE_WEIGHT" />
12
+
13
+ <!-- Query for Health Connect availability -->
14
+ <queries>
15
+ <package android:name="com.google.android.apps.healthdata" />
16
+ </queries>
17
+
18
+ <application>
19
+ <!-- Activity to display privacy policy rationale for Health Connect permissions (Android 13 and earlier) -->
20
+ <activity
21
+ android:name=".PermissionsRationaleActivity"
22
+ android:exported="true"
23
+ android:theme="@android:style/Theme.DeviceDefault.Light.NoActionBar">
24
+ <intent-filter>
25
+ <action android:name="androidx.health.ACTION_SHOW_PERMISSIONS_RATIONALE" />
26
+ </intent-filter>
27
+ </activity>
28
+
29
+ <!-- Activity alias for Android 14+ (API 34+) permission usage view -->
30
+ <activity-alias
31
+ android:name=".ViewPermissionUsageActivity"
32
+ android:exported="true"
33
+ android:targetActivity=".PermissionsRationaleActivity"
34
+ android:permission="android.permission.START_VIEW_PERMISSION_USAGE">
35
+ <intent-filter>
36
+ <action android:name="android.intent.action.VIEW_PERMISSION_USAGE" />
37
+ <category android:name="android.intent.category.HEALTH_PERMISSIONS" />
38
+ </intent-filter>
39
+ </activity-alias>
40
+ </application>
41
+ </manifest>
@@ -0,0 +1,34 @@
1
+ package app.capgo.plugin.health
2
+
3
+ import androidx.health.connect.client.permission.HealthPermission
4
+ import androidx.health.connect.client.records.ActiveCaloriesBurnedRecord
5
+ import androidx.health.connect.client.records.DistanceRecord
6
+ import androidx.health.connect.client.records.HeartRateRecord
7
+ import androidx.health.connect.client.records.Record
8
+ import androidx.health.connect.client.records.StepsRecord
9
+ import androidx.health.connect.client.records.WeightRecord
10
+ import kotlin.reflect.KClass
11
+
12
+ enum class HealthDataType(
13
+ val identifier: String,
14
+ val recordClass: KClass<out Record>,
15
+ val unit: String
16
+ ) {
17
+ STEPS("steps", StepsRecord::class, "count"),
18
+ DISTANCE("distance", DistanceRecord::class, "meter"),
19
+ CALORIES("calories", ActiveCaloriesBurnedRecord::class, "kilocalorie"),
20
+ HEART_RATE("heartRate", HeartRateRecord::class, "bpm"),
21
+ WEIGHT("weight", WeightRecord::class, "kilogram");
22
+
23
+ val readPermission: String
24
+ get() = HealthPermission.getReadPermission(recordClass)
25
+
26
+ val writePermission: String
27
+ get() = HealthPermission.getWritePermission(recordClass)
28
+
29
+ companion object {
30
+ fun from(identifier: String): HealthDataType? {
31
+ return entries.firstOrNull { it.identifier == identifier }
32
+ }
33
+ }
34
+ }