Luscii Android SDK
Getting started
The minimum required Android SDK is 26 (Android 8.0).
Hilt is required (for now). If your app already uses Hilt, no setup is necessary, except adding the correct @AndroidEntryPoint annotation to the Activity the SDK is used in.
If your app does not use Hilt yet, from the Dependency injection with Hilt page, follow the Adding dependencies, Hilt application class and Hilt application class steps.
The Luscii Android SDK is published to a public Maven repo hosted on Github Packages.
In the
settings.gradle.ktsfile, add the Luscii Maven repo: Because Github does not support anonymous access for their Maven package repositories, you have to provide your Github username, and as a password a classic Github access token with theread:packagespermission.You don't need any invite or approval from Luscii before you can retrieve the package.
Also add the Jitpack repository, because the SDK depends on a library from there.
dependencyResolutionManagement {
repositories {
// Other repositories..
maven {
url = uri("https://maven.pkg.github.com/Luscii/actions-sdk-android")
// These should be loaded from a .properties file
credentials {
username = "githubusername"
password = "gh_someToken123"
}
}
maven(url = "https://jitpack.io")
}
}Content copied to clipboardIn the project's
build.gradke.kts, add the following dependency:dependencies {
implementation("com.luscii:sdk:0.8.1")
// Other dependencies..
}Content copied to clipboardAlso in the project's
build.gradke.kts, specifydataBinding = true:android {
// Other stuff..
buildFeatures {
dataBinding = true
}
}Content copied to clipboard
Usage
Initialize a
Lusciiinstance somewhere::val luscii = Luscii {
applicationContext = ...
useDynamicTheming = true // Optional, use if you want to use Material You, defaults to false
}Content copied to clipboardBefore using any other
Lusciimethod, make sure to authenticate.luscii.authenticate(patientApiKey = "some-api-key")Content copied to clipboard
Default Actions screen
If you want to use the default, pre-made Actions screen, you can launch it like so:
luscii.startActionsActivity()Custom Actions screen
You can also create your own Actions screen UI, using:
val actionsToday = luscii.getActions()This method returns all Actions for today.
An Action can be launched by starting an activity using:
import com.luscii.sdk.actions.ActionFlowResult.*
val actionFlowLauncher = registerForActivityResult(
luscii.createActionFlowActivityResultContract()
) { result: ActionFlowResult ->
// Handle result
when (result) {
is Completed -> TODO()
is Cancelled -> TODO()
is Error -> TODO()
}
}Launchable status
However, it's recommend to first check if the Action is launchable. An Action might have to be completed today, but in a specific timeframe. There are a few ways to check for this:
val launchable = someAction.isLaunchable()import com.luscii.sdk.actions.Action.LaunchableStatus.*
// Somewhere down..
when (someAction.getLaunchableStatus()) {
is CompletedAt -> TODO()
is Launchable -> TODO()
is LaunchableAfter -> TODO()
is LaunchableBefore -> TODO()
}import com.luscii.sdk.actions.Action.LaunchableStatus.*
// Somewhere down..
when (someAction.getLaunchableStatus()) {
is Launchable -> TODO()
is NotLaunchable -> TODO()
}Programmatic measurements
It's also possible to submit measurements programmatically, for example if you want to keep using your own measurement flow.
For each action you can check the Instruments it has. Each instrument has Instrument.Items. Each item has a quantity, which is the type of value you can submit as a measurement.
All measurement values are Strings, meaning your are responsible for encoding it properly, such as using the correct decimal seperator and decimal places.
If an action has expired (it's NotLaunchable), measurements can still be submitted, but they are not submitted in name of the planned action, but an extra action is created which the measurements will be associated with.
Use luscii.submitMeasurements to submit measurements:
luscii.submitMeasurements(
Action.Measurements(
someAction,
// When all measurements were completed.
completedAt = ZonedDateTime.now(), // Or earlier.
// Each instrument has a set of Instrument.Measurements, which is a list
// of measurements per item.
Action.Instrument.Measurements(
someInstrumentOfSomeAction,
// When this instrument's measurements were processed.
processedAt = ZonedDateTime.now(), // Or earlier.
// Here are the measurements per item:
Action.Instrument.Item.Measurement(
someItemOfSomeInstrumentOfSomeAction,
value = "123.45"
),
),
// Constructor accepts a vararg or list, so all measurements can be submitted in one go.
)
)Schedule
You can show the "My Schedule" screen, which shows all upcoming and previous actions, by using:
luscii.startScheduleActivity(context)Self-Care
You can show the "Self-Care" screen, which shows all self-care actions, by using:
luscii.startSelfCareActivity(context)You can also retrieve all self-care actions programmatically using:
val selfCareActions = luscii.getSelfCareActions()These are actions that are not scheduled, but can be performed at any time, in addtion to the scheduled actions for today returned by luscii.getTodayActions().
Disclaimer
If a patient is newly registered, they must accept the Luscii disclaimer before they can launch actions.
If the patient has not accepted the disclaimer yet, it will be shown automatically when opening either the #default-actions-screen or a #custom-action-screen.
You can also show the disclaimer at a more convenient moment, for example your own onboarding flow, by using
val disclaimerLauncher = registerForActivityResult(
luscii.createDisclaimerActivityResultContract()
) { result: DisclaimerResult ->
when (result) {
is DisclaimerResult.Accepted -> TODO()
is DisclaimerResult.NotAccepted -> TODO()
}
}
// ...
// Use the extension method for launching the disclaimer, not the regular one.
disclaimerLauncher.launch()If the disclaimer is already accepted, DisclaimerResult.Accepted will be returned immediately, and no screen is shown. Hence, there's no need to check if the disclaimer is already accepted before using the activity result contract.
Example app
For a demo on how how to use the Luscii Android SDK, you can check out the demo app here.
Acceptance environment
If you want to use the SDK on Luscii's acceptance environment, use the following dependency in your build.gradle.kts instead of the one mentioned before:
dependencies {
implementation("com.luscii:sdk-acceptance:0.8.1")
// Other dependencies..
}Notes
Some actions require third-party SDKs from Happitech, iHealth, etc. If these are not present, the SDK will not show devices using those SDKs as an option when performing an action. Some actions force the use of a third-party device. When launching such an action, an error message will be displayed to the user.
Changelog
0.8.1 (Hilt: 2.57.2)
Fix
MirLicenseissue when launching an action flowRemove
androidx.hilt-worktransitive dependency0.8.0 (Hilt: 2.57.1)
Add method to show "Self-Care" screen (
startSelfCareActivity)Add method to retrieve self-care actions programmatically (
getSelfCareActions)Add
isSelfCare,isPlannedandisExtratoActionDeprecate
getActionsin favor ofgetTodayActionsFix 16kb alignment issues
0.7.0
Add method to show "My Schedule" screen
Remove unnecessary permissions from SDK's manifest
0.6.0
Add methods to submit measurements programmatically
Add
getActionmethod to retrieve a singularActionby idMake
Action.idits own type:Action.IdChange
Action.iconUrlfromURLtoURIRemove need for core library desugaring
0.5.0
Show #Disclaimer for patients to accept before launching an Action
Add an explicit method to show the disclaimer
Show an app bar in the default Actions activity
Support edge-to-edge in default Actions activity
Fix Hilt name clash issue
Fix data binding name clash issue
Remove
patientApiKeyfromLusciiConfiguration, pass it toauthenticateinstead0.4.1
Add sources jar for Kotlin docs in IDE
Fix a small Kotlin code-gen issue
0.4.0
Add methods to launch
Activitys instead ofFragmentsAdd support for enabling dynamic theming (Material You)
Fix an issue where a completed action would have a blank screen after pressing back
Remove passing a
patientApiKeythroughLusciiConfiguration, pass it toauthenticateinstead0.3.19
Fix multiple issues regarding minifying and Proguard
0.3.18
Fix background not being dark in dark-mode in the default actions screen
Actionis not a data class anymore, it's now equal to otherActions only by itsid0.3.17
Fix
InflateExceptionwhen launching an action flowFix the need for having to supply a theme in
<application>in the manifest