Skip to content

Commit

Permalink
Create Health Connect to FHIR converter module (#15)
Browse files Browse the repository at this point in the history
# Create Health Connect to FHIR converter module

The HealthConnectOnFHIR library provides a mapper that converts supported [Android Health
Connect](https://health.google/health-connect-android/) Records to corresponding [HL7® FHIR® R4 Observations](https://hl7.org/fhir/r4/observation.html) with standardized codes (e.g. [LOINC](https://loinc.org/)).
  • Loading branch information
vishnuravi authored Jun 17, 2024
1 parent b77e6ea commit b9f4ae6
Show file tree
Hide file tree
Showing 13 changed files with 918 additions and 10 deletions.
4 changes: 4 additions & 0 deletions gradle/libs.versions.toml
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,8 @@ firebaseStorageKtx = "21.0.0"
foundation = "1.6.7"
googleGmsGoogleServices = "4.4.2"
googleid = "1.1.0"
hapiFhirVersion = "5.7.9"
healthConnectClient = "1.1.0-alpha07"
hiltNavigation = "1.2.0"
hiltVersion = "2.51"
junit = "4.13.2"
Expand All @@ -46,6 +48,7 @@ android-gradle = { group = "com.android.tools.build", name = "gradle", version.r
android-tools-common = { group = "com.android.tools", name = "common", version.ref = "androidTools" }
androidx-activity-compose = { group = "androidx.activity", name = "activity-compose", version.ref = "activityCompose" }
androidx-appcompat = { group = "androidx.appcompat", name = "appcompat", version.ref = "appcompat" }
androidx-health-connect-client = { module = "androidx.health.connect:connect-client", version.ref = "healthConnectClient" }
androidx-core-ktx = { group = "androidx.core", name = "core-ktx", version.ref = "coreKtx" }
androidx-core-testing = { group = "androidx.arch.core", name = "core-testing", version.ref = "coreTestingVersion" }
androidx-credentials-play-services-auth = { module = "androidx.credentials:credentials-play-services-auth", version.ref = "credentialsPlayServicesAuth" }
Expand Down Expand Up @@ -73,6 +76,7 @@ firebase-functions-ktx = { group = "com.google.firebase", name = "firebase-funct
firebase-storage-ktx = { group = "com.google.firebase", name = "firebase-storage-ktx", version.ref = "firebaseStorageKtx" }
google-truth = { group = "com.google.truth", name = "truth", version.ref = "truth" }
googleid = { module = "com.google.android.libraries.identity.googleid:googleid", version.ref = "googleid" }
hapi-fhir-structures-r4 = { module = "ca.uhn.hapi.fhir:hapi-fhir-structures-r4", version.ref = "hapiFhirVersion"}
hilt-compiler = { group = "com.google.dagger", name = "hilt-compiler", version.ref = "hiltVersion" }
hilt-core = { group = "com.google.dagger", name = "hilt-android", version.ref = "hiltVersion" }
hilt-gradle = { group = "com.google.dagger", name = "hilt-android-gradle-plugin", version.ref = "hiltVersion" }
Expand Down
7 changes: 0 additions & 7 deletions modules/contact/src/androidTest/AndroidManifest.xml

This file was deleted.

4 changes: 1 addition & 3 deletions modules/contact/src/main/AndroidManifest.xml
Original file line number Diff line number Diff line change
@@ -1,4 +1,2 @@
<?xml version="1.0" encoding="utf-8"?>
<manifest>

</manifest>
<manifest />
1 change: 1 addition & 0 deletions modules/healthconnectonfhir/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
/build
83 changes: 83 additions & 0 deletions modules/healthconnectonfhir/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
# Module healthconnectonfhir

The HealthConnectOnFHIR library provides a mapper that converts supported [Android Health Connect](https://health.google/health-connect-android/) Records to corresponding [HL7® FHIR® R4 Observations](https://hl7.org/fhir/r4/observation.html) with standardized codes (e.g. [LOINC](https://loinc.org/)).

For more information, please refer to the API documentation.

## Mapping Table

| Health Connect Record | FHIR Observation Category | LOINC Code | Unit | Display |
|------------------------------------------------------------------------------------------------------------------------------------------------|---------------------------|------------|------------|--------------------------------------------|
| [ActiveCaloriesBurnedRecord](https://developer.android.com/reference/kotlin/androidx/health/connect/client/records/ActiveCaloriesBurnedRecord) | Activity | 41981-2 | kcal | Calories burned |
| [BloodGlucoseRecord](https://developer.android.com/reference/kotlin/androidx/health/connect/client/records/BloodGlucoseRecord) | | 41653-7 | mg/dL | Glucose Glucometer (BldC) [Mass/Vol] |
| [BloodPressureRecord](https://developer.android.com/reference/kotlin/androidx/health/connect/client/records/BloodPressureRecord) | Vital Signs | 85354-9 | mmHg | Blood pressure panel with all children optional |
| [BodyFatRecord](https://developer.android.com/reference/kotlin/androidx/health/connect/client/records/BodyFatRecord) | | 41982-0 | % | Percentage of body fat Measured |
| [BodyTemperatureRecord](https://developer.android.com/reference/kotlin/androidx/health/connect/client/records/BodyTemperatureRecord) | Vital Signs | 8310-5 | Cel | Body temperature |
| [HeartRateRecord](https://developer.android.com/reference/kotlin/androidx/health/connect/client/records/HeartRateRecord) | Vital Signs | 8867-4 | /min | Heart rate |
| [HeightRecord](https://developer.android.com/reference/kotlin/androidx/health/connect/client/records/HeightRecord) | Vital Signs | 8302-2 | m | Body height |
| [OxygenSaturationRecord](https://developer.android.com/reference/kotlin/androidx/health/connect/client/records/OxygenSaturationRecord) | Vital Signs | 59408-5 | % | Oxygen saturation in Arterial blood by Pulse oximetry |
| [RespiratoryRateRecord](https://developer.android.com/reference/kotlin/androidx/health/connect/client/records/RespiratoryRateRecord) | Vital Signs | 9279-1 | /min | Respiratory rate |
| [StepsRecord](https://developer.android.com/reference/kotlin/androidx/health/connect/client/records/StepsRecord) | Activity | 55423-8 | steps | Number of steps |
| [WeightRecord](https://developer.android.com/reference/kotlin/androidx/health/connect/client/records/WeightRecord) | Vital Signs | 29463-7 | kg | Body weight |


## Installation

HealthConnectOnFHIR can be installed into your Android Studio project [via Jitpack](https://jitpack.io/#StanfordSpezi/SpeziKt/healthconnectonfhir-maven).

## Usage

```kotlin
// Initialize the mapper
val mapper = RecordToObservationMapperImpl()

// Query a `Record` from Health Connect
val record = // ..

// Map the record to an HL7 FHIR Observation
val observation = mapper.map(record)
```

## Example

First, you will need to configure your application to use Android Health Connect. For more information, please see the [official documentation](https://developer.android.com/health-and-fitness/guides/health-connect).

```kotlin
// Initialize a `HealthConnectClient` (see Health Connect docs for full details)
val healthConnectClient = HealthConnectClient.getOrCreate(context)

// Define a time range for the query
val startTime = Instant.parse("2023-05-01T00:00:00Z")
val endTime = Instant.parse("2023-06-01T00:00:00Z")

// Query a list of `WeightRecord`s from Health Connect
val result = healthConnectClient.readRecords(
ReadRecordsRequest(
recordType = WeightRecord::class,
timeRangeFilter = TimeRangeFilter.between(startTime, endTime)
)
).records

// Initialize the mapper
val mapper = RecordToObservationMapperImpl()

// Convert each weight record to a FHIR Observation
result.forEach { weightRecord ->
val observations = mapper.map(weightRecord)
observations.forEach { observation ->
// Do something with the observation
}
}
```

## License

This project is licensed under the MIT license.

## Contributors

This project is developed as a part of the Stanford Biodesign for Digital Health projects at Stanford. See CONTRIBUTORS.md for a full list of all HealthConnectOnFHIR contributors.

## Notices

Health Connect is a registered trademark of Google. FHIR is a registered trademark of Health Level Seven International.
13 changes: 13 additions & 0 deletions modules/healthconnectonfhir/build.gradle.kts
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
plugins {
alias(libs.plugins.spezi.library)
alias(libs.plugins.spezi.hilt)
}

android {
namespace = "edu.stanford.spezi.modules.healthconnectonfhir"
}

dependencies {
api(libs.androidx.health.connect.client)
api(libs.hapi.fhir.structures.r4)
}
4 changes: 4 additions & 0 deletions modules/healthconnectonfhir/src/main/AndroidManifest.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android">

</manifest>
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
package edu.stanford.healthconnectonfhir

data class MappedUnit(val unit: String, val system: String, val code: String)
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
package edu.stanford.healthconnectonfhir

import androidx.health.connect.client.records.Record
import org.hl7.fhir.r4.model.Observation

interface RecordToObservationMapper {
/**
* Maps a given Health Connect record to a list of HL7 FHIR Observations
*
* @param T the type of the Health Connect record, extending from `Record`
* @param record the record to be mapped
* @return a list of `Observation` objects derived from the provided health record
*/
fun <T : Record> map(record: T): List<Observation>
}
Loading

0 comments on commit b9f4ae6

Please sign in to comment.