Kotlin Multiplatform (KMP) client for the Personal Health Data Platform (PHDP)
This is the Android and Java SDK of Data4Life. The SDK encapsulates the backend functionality of the Data4Life Personal Health Data Platform (PHDP) and enables end-to-end encryption of health data. It allows users to store and access sensitive data on the secure platform and share it to authorized users and applications.
For more information about the Data4Life platform, visit our website.
-
Authorization/Authentication
-
End-to-End encryption
-
API client for PHDP
-
Data types support for custom, FHIR 3 and FHIR 4
Notes:
-
The SDK ships with BouncyCastle and will replace the BouncyCastle version provided by the Android system. Ensure that if youโre using or depend on BouncyCastle CryptoProvider, youโre still compatible.
To use the SDK, you must have a Data4Life partner ID. To obtain a partner ID, get in touch with us at [email protected].
Once you have a partner ID, follow these steps to start working with the SDK:
-
Android 6.0 (API 23) to Android 13 (API 33)
-
Java 8 Limitations Desugaring
-
Kotlin 1.7.10
We use GitHub Packages to distribute the SDK. In order to consume our dependencies you need to generate a GitHub Personal Access Token. Please follow the how to authenticate to GitHub Packages.
- NOTICE
-
You need to have read access to this repository and generate a personal access token with
repo
andread:packages
scope.
The token needs to be made available.
-
Add
gpr.user = {GitHub username}
andgpr.key = {GitHub Personal Access Token}
to your global Gradle properties~/.gradle/gradle.properties
gpr.user=github-username gpr.key=github-token
-
Or add following environment variables
PACKAGE_REGISTRY_USERNAME={GitHub username}
andPACKAGE_REGISTRY_TOKEN={GitHub Personal Access Token}
Add the following maven repository configuration to your root build.gradle/build.gradle.kts
:
Gradle KTS
allprojects {
repositories {
...
maven {
url = uri("https://maven.pkg.github.com/d4l-data4life/hc-sdk-kmp")
credentials {
username = project.findProperty("gpr.user") as String? ?: System.getenv("PACKAGE_REGISTRY_USERNAME")
password = project.findProperty("gpr.key") as String? ?: System.getenv("PACKAGE_REGISTRY_TOKEN")
}
}
}
}
Gradle Groovy
allprojects {
repositories {
...
maven {
url = uri("https://maven.pkg.github.com/d4l-data4life/hc-sdk-kmp")
credentials {
username = project.findProperty("gpr.user") as ?: System.getenv("PACKAGE_REGISTRY_USERNAME")
password = project.findProperty("gpr.key") as ?: System.getenv("PACKAGE_REGISTRY_TOKEN")
}
}
}
}
dependencies {
implementation("care.data4life.hc-sdk-kmp:sdk-android:LATEST_VERSION")
}
The SDK ships with ThreeTenBP a Java 8 Time backport. For Android, its loading mechanism of time zone information is inefficient. So we recommend providing your favorite Android ThreeTen library here, for example ThreeTenABP.
dependencies {
implementation("care.data4life.hc-sdk-kmp:sdk-android:LATEST_VERSION") {
...
// exclude the threetenbp dependency from the `sdk`
exclude group: "org.threeten", module: "threetenbp"
}
// provide your favorite ThreeTen library here
implementation "com.jakewharton.threetenabp:threetenabp:1.4.0"
}
The SDK is only published as release variant. So you need to add a matchingFallbacks
config to all of your buildTypes
and flavors
. See variant awareness for more details.
android {
buildTypes {
debug {
matchingFallbacks = ["release", "debug"]
}
}
}
To ensure Java 8 compatibility, add compile options to app build.gradle/build.gradle.kts
:
android {
compileOptions {
sourceCompatibility = "1.8"
targetCompatibility = "1.8"
}
kotlinOptions {
jvmTarget = "1.8"
}
}
Add the following dependencies to your app build.gradle/build.gradle.kts
file.
dependencies {
implementation("care.data4life.hc-sdk-kmp:sdk-jvm:LATEST_VERSION")
}
To ensure Java 8 compatibility, add compile options to app build.gradle/build.gradle.kts
:
java {
sourceCompatibility = JavaVersion.VERSION_1_8
targetCompatibility = JavaVersion.VERSION_1_8
}
tasks.withType(org.jetbrains.kotlin.gradle.tasks.KotlinCompile).all {
kotlinOptions {
jvmTarget = "1.8"
}
}
On Android manifest placeholders are used to pass the configuration to the SDK.
-
Add the
manifestPlaceholders
property with theplatform
,environment
,clientId
,clientSecret
, andredirectScheme
keys to your build.gradle/build.gradle.kts file.Gradle KTS
android { defaultConfig { manifestPlaceholders(mapOf( "platform" to "D4L", "environment" to "production", "clientId" to "clientId", "clientSecret" to "clientSecret", "redirectScheme" to "com.example", "debug" to "true" )) } }
Gradle Groovy
android { defaultConfig { manifestPlaceholders = [ platform : "D4L", environment : "production", clientId : "clientId", clientSecret : "clientSecret", redirectScheme: "com.example", debug : "false" ] } }
๐The debug
flag is set tofalse
if your app is not debuggable. -
To log in, use the
startActivityForResult
method with login intent.Intent loginIntent = Data4LifeClient.getLoginIntent(context, null);
or with custom scopes
Intent loginIntent = Data4LifeClient.getLoginIntent( context, new String[] {"scope:r", "scope:w"} );
and then
startActivityForResult(loginIntent, Data4LifeClient.D4L_AUTH);
-
Handle the login result in your
onActivityResult
method.@Override protected void onActivityResult(int requestCode, int resultCode, Intent data) { super.onActivityResult(requestCode, resultCode, data); if (requestCode == D4L_AUTH){ if (resultCode == RESULT_OK){ // you are now logged in } } }
-
Get the Data4Life client instance inside Activity or Fragment.
Data4LifeClient client = Data4LifeClient.getInstance();
-
Now you can use the available API for the 3 supported data types which will return results on background thread.
The Java SDK only supports a single-user use case. For every individual user, the SDK must be instantiated with the user alias.
-
Instantiate the client with
alias
,platform
,environment
,clientId
,clientSecret
, andredirectUrl
properties:Data4LifeClient client = Data4LifeClient.init( "alias", "clientId", "clientSecret", Environment.PRODUCTION, "redirectUrl", "platform" );
๐The alias
is used to namespace the session that is bound to a client instance. This allows multiple instances of the client running with different sessions in parallel. Could be used to bind a client instance to a user in a multiuser environment. -
To log in, you need start the OAuth 2.0 authorization flow by generating the authorization url and hand it over to a browser and let the user authorize.
String authorizationUrl = client.getAuthorizationUrl();
-
After the browser auth session calls the previously registered
redirectUrl
, pass the received OAuth callback URL to the client instanceString callbackUrl = "https://.../oauth/callback?code=12345&state=abcde" boolean authorized = client.finishLogin(callbackUrl);
-
If youโre in a multiuser setup with multiple SDK instances, you could extract the alias from the callbackUrl
UserIdExtractor extractor = new UserIdExtractor(); String userId = extractor.extract(callbackUrl);
๐Multiple instance management is not handled by the SDK and needs to be done by you, e.g. with a Map<String,Data4LifeClient> or better suitable solution -
Now you can use the available API for the 3 supported data types which will return results on background thread.
This project is work in progress. We are working on adding more functionality, guidelines, documentation and other improvements.
Also see the open issues for a list of proposed features and known issues.
See changelog
We use Semantic Versioning as a guideline for our versioning.
Releases use this format: {major}.{minor}.{patch}
-
Breaking changes bump
{major}
and reset{minor}
&{patch}
-
Backward compatible changes bump
{minor}
and reset{patch}
-
Bug fixes bump
{patch}
You want to help or share a proposal? You have a specific problem? Read the following:
-
Code of conduct for details on our code of conduct.
-
Contributing for details about how to report bugs and propose features.
-
Developing for details about our development process and how to build and test the project.
Copyright (c) 2022 D4L data4life gGmbH / All rights reserved.
Please refer to our License for further details.