Skip to content

shubhamsinghshubham777/KHealth

Repository files navigation

πŸ₯ KHealth πŸ₯

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.

Demo

Note

You can find the following app in the sample* directories (e.g. sampleAndroidApp and sampleAppleApps)

android.mp4
iOS.mp4
watchOS.mp4

πŸš€ Getting Started

Maven Central Version

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)
        }
    }
}

βš™οΈ Usage

  1. (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>
    
  2. (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>
  3. (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
  4. 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
    }
  5. 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()
    }
  6. 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
     )
  7. 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
     )
  8. Check if permission was granted

    val caloriesPermResponse = permissionResponse.first { response ->
        response is KHPermission.ActiveCaloriesBurned
    }.writeStatus
    
    val wasWritePermissionGranted = caloriesPermResponse.write == true 
  9. 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 βœ…")
         }
    }
  10. Read records

 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 βœ…
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 βœ… βœ…

Supported Exercise Types (based on platforms)

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.

🀝 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 file for details.