KHealth (short for Kotlin Health) is a simple Kotlin Multiplatform wrapper over Android's Health Connect and Apple's HealthKit APIs. It provides a simple and effective way to consume these native APIs in a Kotlin/Compose Multiplatform environment.
Note
You can find the following app in the sample*
directories (e.g. sampleAndroidApp
and
sampleAppleApps
)
android.mp4
iOS.mp4
watchOS.mp4
Add the following to your shared module's build.gradle.kts
:
implementation("io.github.shubhamsinghshubham777:khealth:1.1.0")
or add it to your version catalog:
[versions]
khealth = "1.1.0"
[libraries]
khealth = { module = "io.github.shubhamsinghshubham777:khealth", version.ref = "khealth" }
[plugins]
and use it in your build.gradle.kts
:
kotlin {
sourceSets {
commonMain.dependencies {
implementation(libs.khealth)
}
}
}
-
(Apple Only) Add the following code in your
Info.plist
file:<plist> <dict> ... ... ... <key>NSHealthUpdateUsageDescription</key> <string>We will sync your data with the Apple Health app to give you better insights</string> <key>NSHealthShareUsageDescription</key> <string>We will sync your data with the Apple Health app to give you better insights</string> </dict> </plist>
-
(Android only) Add the following code in your
AndroidManifest.xml
:<uses-permission android:name="..." /> <!-- Check if Health Connect is installed --> <queries> <package android:name="com.google.android.apps.healthdata" /> </queries> <application ...> <!-- For supported versions through Android 13, create an activity to show the rationale of Health Connect permissions once users click the privacy policy link. --> <activity android:name=".PermissionsRationaleActivity" android:exported="true"> <intent-filter> <action android:name="androidx.health.ACTION_SHOW_PERMISSIONS_RATIONALE" /> </intent-filter> </activity> <!-- For versions starting Android 14, create an activity alias to show the rationale of Health Connect permissions once users click the privacy policy link. --> <activity-alias android:name="ViewPermissionUsageActivity" android:exported="true" android:permission="android.permission.START_VIEW_PERMISSION_USAGE" android:targetActivity=".PermissionsRationaleActivity"> <intent-filter> <action android:name="android.intent.action.VIEW_PERMISSION_USAGE" /> <category android:name="android.intent.category.HEALTH_PERMISSIONS" /> </intent-filter> </activity-alias> </application>
-
(Android only) Add the dependencies you require to use in
AndroidManifest.xml
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
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
EXERCISE android.permission.health.READ_EXERCISE
android.permission.health.WRITE_EXERCISE
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
NUTRITION android.permission.health.READ_NUTRITION
android.permission.health.WRITE_NUTRITION
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
-
Instantiate
// On Apple (iOS, watchOS) val kHealth = KHealth() // On Android (inside a ComponentActivity) class MainActivity : ComponentActivity() { private val kHealth = KHealth(this) // Rest of your code }
-
Initialise (only required on Android)
// Inside a `ComponentActivity` override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) // Initialise (only on Android, on Apple, this function is no-op) kHealth.initialise() }
-
Check Permission Status
val permissionResponse: Set<KHPermission> = kHealth.checkPermissions( KHPermission.ActiveCaloriesBurned(read = true, write = true), KHPermission.HeartRate(read = true, write = false), // Add as many requests as you want )
-
Request Permissions
// Same syntax as `checkPermissions` val permissionResponse: Set<KHPermission> = kHealth.requestPermissions( KHPermission.ActiveCaloriesBurned(read = true, write = true), KHPermission.HeartRate(read = true, write = false), // Add as many requests as you want )
-
Check if permission was granted
val caloriesPermResponse = permissionResponse.first { response -> response is KHPermission.ActiveCaloriesBurned }.writeStatus val wasWritePermissionGranted = caloriesPermResponse.write == true
-
Write records
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 ✅") } }
-
Read records
val heartRateRecords = kHealth.readRecords(
KHReadRequest.HeartRate(
startTime = Clock.System.now().minus(1.days),
endTime = Clock.System.now()
)
)
println("Heart Rate records: $heartRateRecords")
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 | ✅ | |
Exercise | ✅ | ✅ |
FloorsClimbed | ✅ | ✅ |
HeartRate | ✅ | ✅ |
HeartRateVariability | ✅ | ✅ |
Height | ✅ | ✅ |
Hydration | ✅ | ✅ |
IntermenstrualBleeding | ✅ | ✅ |
LeanBodyMass | ✅ | ✅ |
MenstruationPeriod | ✅ | |
MenstruationFlow | ✅ | ✅ |
Nutrition | ✅ | ✅ |
OvulationTest | ✅ | ✅ |
OxygenSaturation | ✅ | ✅ |
Power | ✅ | ✅ |
RespiratoryRate | ✅ | ✅ |
RestingHeartRate | ✅ | ✅ |
SexualActivity | ✅ | ✅ |
SleepSession | ✅ | ✅ |
Speed | ✅ | |
RunningSpeed | ✅ | |
CyclingSpeed | ✅ | |
StepCount | ✅ | ✅ |
Vo2Max | ✅ | ✅ |
Weight | ✅ | ✅ |
WheelChairPushes | ✅ | ✅ |
KHealth supports reading and writing the following exercise/workout types on the following platforms:
Type | Android | Apple (iOS & watchOS) |
---|---|---|
AmericanFootball | ✅ | ✅ |
Archery | ✅ | |
AustralianFootball | ✅ | ✅ |
Badminton | ✅ | ✅ |
Barre | ✅ | |
Baseball | ✅ | ✅ |
Basketball | ✅ | ✅ |
Biking | ✅ | ✅ |
BikingStationary | ✅ | ✅ |
BootCamp | ✅ | ✅ |
Bowling | ✅ | |
Boxing | ✅ | ✅ |
Calisthenics | ✅ | ✅ |
CardioDance | ✅ | |
Climbing | ✅ | |
Cooldown | ✅ | |
CoreTraining | ✅ | |
Cricket | ✅ | ✅ |
CrossCountrySkiing | ✅ | |
CrossTraining | ✅ | |
Curling | ✅ | |
Cycling | ✅ | |
Dance | ✅ | |
DanceInspiredTraining | ✅ | |
Dancing | ✅ | ✅ |
DiscSports | ✅ | |
DownhillSkiing | ✅ | |
Elliptical | ✅ | ✅ |
EquestrianSports | ✅ | |
ExerciseClass | ✅ | ✅ |
Fencing | ✅ | ✅ |
Fishing | ✅ | |
FitnessGaming | ✅ | |
Flexibility | ✅ | |
FrisbeeDisc | ✅ | |
FunctionalStrengthTraining | ✅ | |
Golf | ✅ | ✅ |
GuidedBreathing | ✅ | ✅ |
Gymnastics | ✅ | ✅ |
HandCycling | ✅ | |
Handball | ✅ | ✅ |
HighIntensityIntervalTraining | ✅ | ✅ |
Hiking | ✅ | ✅ |
Hockey | ✅ | |
Hunting | ✅ | |
IceHockey | ✅ | ✅ |
IceSkating | ✅ | ✅ |
JumpRope | ✅ | |
Kickboxing | ✅ | |
Lacrosse | ✅ | |
MartialArts | ✅ | ✅ |
MindAndBody | ✅ | |
MixedCardio | ✅ | |
MixedMetabolicCardioTraining | ✅ | |
Other | ✅ | ✅ |
PaddleSports | ✅ | |
Paddling | ✅ | ✅ |
Paragliding | ✅ | ✅ |
Pickleball | ✅ | |
Pilates | ✅ | ✅ |
Play | ✅ | |
PreparationAndRecovery | ✅ | |
Racquetball | ✅ | ✅ |
RockClimbing | ✅ | ✅ |
RollerHockey | ✅ | ✅ |
Rowing | ✅ | ✅ |
RowingMachine | ✅ | ✅ |
Rugby | ✅ | ✅ |
Running | ✅ | ✅ |
RunningTreadmill | ✅ | ✅ |
Sailing | ✅ | ✅ |
ScubaDiving | ✅ | ✅ |
Skating | ✅ | ✅ |
SkatingSports | ✅ | |
Skiing | ✅ | ✅ |
SnowSports | ✅ | |
Snowboarding | ✅ | ✅ |
Snowshoeing | ✅ | ✅ |
Soccer | ✅ | ✅ |
SocialDance | ✅ | |
Softball | ✅ | ✅ |
Squash | ✅ | ✅ |
StairClimbing | ✅ | ✅ |
StairClimbingMachine | ✅ | ✅ |
Stairs | ✅ | |
StepTraining | ✅ | |
StrengthTraining | ✅ | ✅ |
Stretching | ✅ | ✅ |
Surfing | ✅ | ✅ |
SurfingSports | ✅ | |
SwimBikeRun | ✅ | |
Swimming | ✅ | |
SwimmingOpenWater | ✅ | |
SwimmingPool | ✅ | |
TableTennis | ✅ | ✅ |
TaiChi | ✅ | |
Tennis | ✅ | ✅ |
TrackAndField | ✅ | |
TraditionalStrengthTraining | ✅ | |
Transition | ✅ | |
UnderwaterDiving | ✅ | |
Volleyball | ✅ | ✅ |
Walking | ✅ | ✅ |
WaterFitness | ✅ | |
WaterPolo | ✅ | ✅ |
WaterSports | ✅ | |
Weightlifting | ✅ | ✅ |
Wheelchair | ✅ | ✅ |
WheelchairRunPace | ✅ | |
WheelchairWalkPace | ✅ | |
Wrestling | ✅ | |
Yoga | ✅ | ✅ |
Note
The unsupported types will simply be ignored by all platforms.
Contributions are welcome! Please feel free to submit a Pull Request.
This library is licensed under the Apache 2.0 License. See the LICENSE file for details.