Luscii Android SDK
Getting started
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.kts
file, 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:packages
permission.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.7.0")
// 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
Luscii
instance 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
Luscii
method, 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 Action
s 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 Instrument
s it has. Each instrument has Instrument.Item
s. Each item has a quantity
, which is the type of value you can submit as a measurement.
All measurement values are String
s, 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()
This is the same screen that is shown in the default Actions screen when tapping "My schedule".
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.7.0")
// 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.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
getAction
method to retrieve a singularAction
by idMake
Action.id
its own type:Action.Id
Change
Action.iconUrl
fromURL
toURI
Remove 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
patientApiKey
fromLusciiConfiguration
, pass it toauthenticate
instead0.4.1
Add sources jar for Kotlin docs in IDE
Fix a small Kotlin code-gen issue
0.4.0
Add methods to launch
Activity
s instead ofFragment
sAdd 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
patientApiKey
throughLusciiConfiguration
, pass it toauthenticate
instead0.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
Action
is not a data class anymore, it's now equal to otherAction
s only by itsid
0.3.17
Fix
InflateException
when launching an action flowFix the need for having to supply a theme in
<application>
in the manifest