Skip to content

Latest commit

 

History

History
431 lines (376 loc) · 23 KB

README.md

File metadata and controls

431 lines (376 loc) · 23 KB

🏥 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.