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.0.0")
or add it to your version catalog:
[versions]
khealth = "1.0.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)
}
}
}
-
(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_BURNEDBASAL_METABOLIC_RATE android.permission.health.READ_BASAL_METABOLIC_RATE
android.permission.health.WRITE_BASAL_METABOLIC_RATEBLOOD_GLUCOSE android.permission.health.READ_BLOOD_GLUCOSE
android.permission.health.WRITE_BLOOD_GLUCOSEBLOOD_PRESSURE android.permission.health.READ_BLOOD_PRESSURE
android.permission.health.WRITE_BLOOD_PRESSUREBODY_FAT android.permission.health.READ_BODY_FAT
android.permission.health.WRITE_BODY_FATBODY_TEMPERATURE android.permission.health.READ_BODY_TEMPERATURE
android.permission.health.WRITE_BODY_TEMPERATUREBODY_WATER_MASS android.permission.health.READ_BODY_WATER_MASS
android.permission.health.WRITE_BODY_WATER_MASSBONE_MASS android.permission.health.READ_BONE_MASS
android.permission.health.WRITE_BONE_MASSCERVICAL_MUCUS android.permission.health.READ_CERVICAL_MUCUS
android.permission.health.WRITE_CERVICAL_MUCUSDISTANCE android.permission.health.READ_DISTANCE
android.permission.health.WRITE_DISTANCEELEVATION_GAINED android.permission.health.READ_ELEVATION_GAINED
android.permission.health.WRITE_ELEVATION_GAINEDEXERCISE android.permission.health.READ_EXERCISE
android.permission.health.WRITE_EXERCISEFLOORS_CLIMBED android.permission.health.READ_FLOORS_CLIMBED
android.permission.health.WRITE_FLOORS_CLIMBEDHEART_RATE android.permission.health.READ_HEART_RATE
android.permission.health.WRITE_HEART_RATEHEART_RATE_VARIABILITY android.permission.health.READ_HEART_RATE_VARIABILITY
android.permission.health.WRITE_HEART_RATE_VARIABILITYHEIGHT android.permission.health.READ_HEIGHT
android.permission.health.WRITE_HEIGHTHYDRATION android.permission.health.READ_HYDRATION
android.permission.health.WRITE_HYDRATIONINTERMENSTRUAL_BLEEDING android.permission.health.READ_INTERMENSTRUAL_BLEEDING
android.permission.health.WRITE_INTERMENSTRUAL_BLEEDINGLEAN_BODY_MASS android.permission.health.READ_LEAN_BODY_MASS
android.permission.health.WRITE_LEAN_BODY_MASSMENSTRUATION android.permission.health.READ_MENSTRUATION
android.permission.health.WRITE_MENSTRUATIONMENSTRUATION android.permission.health.READ_MENSTRUATION
android.permission.health.WRITE_MENSTRUATIONNUTRITION android.permission.health.READ_NUTRITION
android.permission.health.WRITE_NUTRITIONOVULATION_TEST android.permission.health.READ_OVULATION_TEST
android.permission.health.WRITE_OVULATION_TESTOXYGEN_SATURATION android.permission.health.READ_OXYGEN_SATURATION
android.permission.health.WRITE_OXYGEN_SATURATIONPOWER android.permission.health.READ_POWER
android.permission.health.WRITE_POWERRESPIRATORY_RATE android.permission.health.READ_RESPIRATORY_RATE
android.permission.health.WRITE_RESPIRATORY_RATERESTING_HEART_RATE android.permission.health.READ_RESTING_HEART_RATE
android.permission.health.WRITE_RESTING_HEART_RATESEXUAL_ACTIVITY android.permission.health.READ_SEXUAL_ACTIVITY
android.permission.health.WRITE_SEXUAL_ACTIVITYSLEEP android.permission.health.READ_SLEEP
android.permission.health.WRITE_SLEEPSPEED android.permission.health.READ_SPEED
android.permission.health.WRITE_SPEEDSTEPS android.permission.health.READ_STEPS
android.permission.health.WRITE_STEPSVO2_MAX android.permission.health.READ_VO2_MAX
android.permission.health.WRITE_VO2_MAXWEIGHT android.permission.health.READ_WEIGHT
android.permission.health.WRITE_WEIGHTWHEELCHAIR_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 | β | β |
FloorsClimbed | β | β |
HeartRate | β | β |
HeartRateVariability | β | β |
Height | β | β |
Hydration | β | β |
IntermenstrualBleeding | β | β |
LeanBodyMass | β | β |
MenstruationPeriod | β | β |
MenstruationFlow | β | β |
Nutrition | β | β |
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.
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.