@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/LICENSE +373 -0
- package/README.md +426 -0
- package/android/build.gradle +70 -0
- package/android/src/main/AndroidManifest.xml +41 -0
- package/android/src/main/java/app/capgo/plugin/health/HealthDataType.kt +34 -0
- package/android/src/main/java/app/capgo/plugin/health/HealthManager.kt +420 -0
- package/android/src/main/java/app/capgo/plugin/health/HealthPlugin.kt +393 -0
- package/android/src/main/java/app/capgo/plugin/health/PermissionsRationaleActivity.kt +57 -0
- package/android/src/main/java/app/capgo/plugin/health/WorkoutType.kt +64 -0
- package/android/src/main/res/.gitkeep +0 -0
- package/dist/docs.json +773 -0
- package/dist/esm/definitions.d.ts +146 -0
- package/dist/esm/definitions.js +2 -0
- package/dist/esm/definitions.js.map +1 -0
- package/dist/esm/index.d.ts +4 -0
- package/dist/esm/index.js +7 -0
- package/dist/esm/index.js.map +1 -0
- package/dist/esm/web.d.ts +15 -0
- package/dist/esm/web.js +35 -0
- package/dist/esm/web.js.map +1 -0
- package/dist/plugin.cjs.js +49 -0
- package/dist/plugin.cjs.js.map +1 -0
- package/dist/plugin.js +52 -0
- package/dist/plugin.js.map +1 -0
- package/package.json +75 -0
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<<a href="#availabilityresult">AvailabilityResult</a>></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<<a href="#authorizationstatus">AuthorizationStatus</a>></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<<a href="#authorizationstatus">AuthorizationStatus</a>></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<<a href="#readsamplesresult">ReadSamplesResult</a>></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<{ version: string; }></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<<a href="#queryworkoutsresult">QueryWorkoutsResult</a>></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><string, string></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><string, string></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
|
+
}
|