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.