Ecosyste.ms: Awesome

An open API service indexing awesome lists of open source software.

Awesome Lists | Featured Topics | Projects

https://github.com/shubhamsinghshubham777/khealth

A Kotlin Multiplatform wrapper for Android's Health Connect and Apple's HealthKit 🏥
https://github.com/shubhamsinghshubham777/khealth

android apple health health-connect healthkit ios kotlin-library kotlin-multiplatform watchos

Last synced: about 2 months ago
JSON representation

A Kotlin Multiplatform wrapper for Android's Health Connect and Apple's HealthKit 🏥

Awesome Lists containing this project

README

        

🏥 KHealth 🏥







**KHealth** (_short for Kotlin Health_) is a simple Kotlin Multiplatform wrapper over
Android's [Health Connect](https://developer.android.com/health-and-fitness/guides/health-connect)
and Apple's [HealthKit](https://developer.apple.com/documentation/healthkit) APIs. It provides a
simple and effective way to consume these native APIs in a Kotlin/Compose Multiplatform environment.

## Demo

> [!NOTE]
> You can find the following app in the `sample*` directories (e.g. `sampleAndroidApp` and
`sampleAppleApps`)

https://github.com/user-attachments/assets/ef0ddd40-ce10-4143-9711-806d0687bc5b

https://github.com/user-attachments/assets/2dfa8a48-412c-4dc5-8ccd-6ce5149eccca

https://github.com/user-attachments/assets/8e6f609b-8f17-4370-8662-42ac0dad3bc0

## 🚀 Getting Started

![Maven Central Version](https://img.shields.io/maven-central/v/io.github.shubhamsinghshubham777/khealth?label=Stable)

Add the following to your shared module's `build.gradle.kts`:

```kotlin
implementation("io.github.shubhamsinghshubham777:khealth:0.0.1")
```

or add it to your version catalog:

```toml
[versions]
khealth = "0.0.1"

[libraries]
khealth = { module = "io.github.shubhamsinghshubham777:khealth", version.ref = "khealth" }

[plugins]
```

and use it in your `build.gradle.kts`:

```kotlin
kotlin {
sourceSets {
commonMain.dependencies {
implementation(libs.khealth)
}
}
}
```

## ⚙️ Usage

1. Add dependencies in AndroidManifest.xml (Android only)

| Type | Permissions |
|-------------------------|--------------------------------------------------------------------------------------------------------------------|
| ACTIVE_CALORIES_BURNED | android.permission.health.READ_ACTIVE_CALORIES_BURNED
android.permission.health.WRITE_ACTIVE_CALORIES_BURNED |
| BASAL_METABOLIC_RATE | android.permission.health.READ_BASAL_METABOLIC_RATE
android.permission.health.WRITE_BASAL_METABOLIC_RATE |
| BLOOD_GLUCOSE | android.permission.health.READ_BLOOD_GLUCOSE
android.permission.health.WRITE_BLOOD_GLUCOSE |
| BLOOD_PRESSURE | android.permission.health.READ_BLOOD_PRESSURE
android.permission.health.WRITE_BLOOD_PRESSURE |
| BODY_FAT | android.permission.health.READ_BODY_FAT
android.permission.health.WRITE_BODY_FAT |
| BODY_TEMPERATURE | android.permission.health.READ_BODY_TEMPERATURE
android.permission.health.WRITE_BODY_TEMPERATURE |
| BODY_WATER_MASS | android.permission.health.READ_BODY_WATER_MASS
android.permission.health.WRITE_BODY_WATER_MASS |
| BONE_MASS | android.permission.health.READ_BONE_MASS
android.permission.health.WRITE_BONE_MASS |
| CERVICAL_MUCUS | android.permission.health.READ_CERVICAL_MUCUS
android.permission.health.WRITE_CERVICAL_MUCUS |
| EXERCISE | android.permission.health.READ_EXERCISE
android.permission.health.WRITE_EXERCISE |
| DISTANCE | android.permission.health.READ_DISTANCE
android.permission.health.WRITE_DISTANCE |
| ELEVATION_GAINED | android.permission.health.READ_ELEVATION_GAINED
android.permission.health.WRITE_ELEVATION_GAINED |
| FLOORS_CLIMBED | android.permission.health.READ_FLOORS_CLIMBED
android.permission.health.WRITE_FLOORS_CLIMBED |
| HEART_RATE | android.permission.health.READ_HEART_RATE
android.permission.health.WRITE_HEART_RATE |
| HEART_RATE_VARIABILITY | android.permission.health.READ_HEART_RATE_VARIABILITY
android.permission.health.WRITE_HEART_RATE_VARIABILITY |
| HEIGHT | android.permission.health.READ_HEIGHT
android.permission.health.WRITE_HEIGHT |
| HYDRATION | android.permission.health.READ_HYDRATION
android.permission.health.WRITE_HYDRATION |
| INTERMENSTRUAL_BLEEDING | android.permission.health.READ_INTERMENSTRUAL_BLEEDING
android.permission.health.WRITE_INTERMENSTRUAL_BLEEDING |
| LEAN_BODY_MASS | android.permission.health.READ_LEAN_BODY_MASS
android.permission.health.WRITE_LEAN_BODY_MASS |
| MENSTRUATION | android.permission.health.READ_MENSTRUATION
android.permission.health.WRITE_MENSTRUATION |
| MENSTRUATION | android.permission.health.READ_MENSTRUATION
android.permission.health.WRITE_MENSTRUATION |
| OVULATION_TEST | android.permission.health.READ_OVULATION_TEST
android.permission.health.WRITE_OVULATION_TEST |
| OXYGEN_SATURATION | android.permission.health.READ_OXYGEN_SATURATION
android.permission.health.WRITE_OXYGEN_SATURATION |
| POWER | android.permission.health.READ_POWER
android.permission.health.WRITE_POWER |
| RESPIRATORY_RATE | android.permission.health.READ_RESPIRATORY_RATE
android.permission.health.WRITE_RESPIRATORY_RATE |
| RESTING_HEART_RATE | android.permission.health.READ_RESTING_HEART_RATE
android.permission.health.WRITE_RESTING_HEART_RATE |
| SEXUAL_ACTIVITY | android.permission.health.READ_SEXUAL_ACTIVITY
android.permission.health.WRITE_SEXUAL_ACTIVITY |
| SLEEP | android.permission.health.READ_SLEEP
android.permission.health.WRITE_SLEEP |
| SPEED | android.permission.health.READ_SPEED
android.permission.health.WRITE_SPEED |
| STEPS | android.permission.health.READ_STEPS
android.permission.health.WRITE_STEPS |
| VO2_MAX | android.permission.health.READ_VO2_MAX
android.permission.health.WRITE_VO2_MAX |
| WEIGHT | android.permission.health.READ_WEIGHT
android.permission.health.WRITE_WEIGHT |
| WHEELCHAIR_PUSHES | android.permission.health.READ_WHEELCHAIR_PUSHES
android.permission.health.WRITE_WHEELCHAIR_PUSHES |

2. Instantiate

```kotlin
// On Apple (iOS, watchOS)
val kHealth = KHealth()

// On Android (inside a ComponentActivity)
class MainActivity : ComponentActivity() {
private val kHealth = KHealth(this)

// Rest of your code
}
```

3. Initialise (only required on Android)

```kotlin
// Inside a `ComponentActivity`
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
// Initialise (only on Android, on Apple, this function is no-op)
kHealth.initialise()
}
```

4. Check Permission Status

```kotlin
val permissionStatuses: Set = kHealth.checkPermissions(
KHPermission(
dataType = KHDataType.ActiveCaloriesBurned,
read = true,
write = true,
),
KHPermission(
dataType = KHDataType.HeartRate,
read = true,
write = false,
),
// Add as many requests as you want
)
```

5. Request Permissions

```kotlin
val permissionStatuses: Set = kHealth.requestPermissions(
KHPermission(
dataType = KHDataType.ActiveCaloriesBurned,
read = true,
write = true,
),
KHPermission(
dataType = KHDataType.HeartRate,
read = true,
write = false,
),
// Add as many requests as you want
)
```

6. Check if permission was granted

```kotlin
val caloriesWriteStatus = permissionStatuses.first {
it.permission.dataType == KHDataType.ActiveCaloriesBurned
}.writeStatus

val wasWritePermissionGranted = caloriesWriteStatus == KHPermissionStatus.Granted
```

7. Write records

```kotlin
if (wasWritePermissionGranted) {
val insertResponse: KHWriteResponse = kHealth.writeRecords(
KHRecord.ActiveCaloriesBurned(
unit = KHUnit.Energy.KiloCalorie,
value = 3.4,
startTime = Clock.System.now().minus(10.minutes),
endTime = Clock.System.now(),
),
KHRecord.HeartRate(
samples = listOf(
KHHeartRateSample(
beatsPerMinute = 126,
time = Clock.System.now().minus(10.minutes)
)
),
),
// Add as many records as you want
)

when (insertResponse) {
is KHWriteResponse.Failed -> {
println("Records insertion failed ❌ Reason: ${insertResponse.throwable}")
}

KHWriteResponse.SomeFailed -> println("Some records were not inserted ⚠️")

KHWriteResponse.Success -> println("Records inserted ✅")
}
}
```

8. Read records
```kotlin
val heartRateRecords = kHealth.readRecords(
KHReadRequest.HeartRate(
startTime = Clock.System.now().minus(1.days),
endTime = Clock.System.now()
)
)
println("Heart Rate records: $heartRateRecords")
```

## Supported Data Types (based on platforms)

KHealth supports reading and writing the following data types on the following platforms:

| Type | Android | Apple (iOS & watchOS) |
|------------------------|---------|-----------------------|
| ActiveCaloriesBurned | ✅ | ✅ |
| BasalMetabolicRate | ✅ | ✅ |
| BloodGlucose | ✅ | ✅ |
| BloodPressure | ✅ | ✅ |
| BodyFat | ✅ | ✅ |
| BodyTemperature | ✅ | ✅ |
| BodyWaterMass | ✅ | ❌ |
| BoneMass | ✅ | ❌ |
| CervicalMucus | ✅ | ✅ |
| CyclingPedalingCadence | ✅ | ❌ |
| Distance | ✅ | ✅ |
| ElevationGained | ✅ | ❌ |
| FloorsClimbed | ✅ | ✅ |
| HeartRate | ✅ | ✅ |
| HeartRateVariability | ✅ | ✅ |
| Height | ✅ | ✅ |
| Hydration | ✅ | ✅ |
| IntermenstrualBleeding | ✅ | ✅ |
| LeanBodyMass | ✅ | ✅ |
| MenstruationPeriod | ✅ | ❌ |
| MenstruationFlow | ✅ | ✅ |
| OvulationTest | ✅ | ✅ |
| OxygenSaturation | ✅ | ✅ |
| Power | ✅ | ✅ |
| RespiratoryRate | ✅ | ✅ |
| RestingHeartRate | ✅ | ✅ |
| SexualActivity | ✅ | ✅ |
| SleepSession | ✅ | ✅ |
| Speed | ✅ | ❌ |
| RunningSpeed | ❌ | ✅ |
| CyclingSpeed | ❌ | ✅ |
| StepCount | ✅ | ✅ |
| Vo2Max | ✅ | ✅ |
| Weight | ✅ | ✅ |
| WheelChairPushes | ✅ | ✅ |

>[!NOTE]
> The unsupported data types will simply be ignored by all platforms.

## 🤝 Contributing

Contributions are welcome! Please feel free to submit a Pull Request.

## 📄 License

This library is licensed under the Apache 2.0 License. See the [LICENSE](LICENSE) file for details.