1.1. Overview
The Novarum SDK enables Android applications to capture and analyze lateral flow tests using the device’s camera.
It handles camera setup, image analysis, and result delivery, allowing developers to focus on interpreting and presenting test results in their own UI.
This guide describes how to integrate the SDK into an Android project using Gradle and AWS CodeArtifact.
1.2. Repository Access
1.2.1. 1 AWS CLI Configuration
Access to the Novarum SDK Maven repository is provided via AWS CodeArtifact.
Before adding the dependency, you must install and configure the AWS CLI.
1.2.1.1. Installation
Refer to AWS Command Line Interface for installation details.
On macOS, you can install via Homebrew :
brew install awscli
1.2.1.2. Profile Configuration
You’ll need the AWS credentials provided by Novarum.
Interactive setup:
aws configure --profile ndxcodeartifact
You’ll be prompted for:
-
Access Key ID
-
Secret Access Key
-
AWS Region (e.g.,
eu-west-2)
For non-interactive environments (CI, build agents), configure directly:
aws configure set aws_access_key_id "${ECR_KEY}"
aws configure set aws_secret_access_key "${ECR_SECRET}"
aws configure set region "${AWS_REGION}"
1.3. Project Setup
1.3.1. 1 Minimum Requirements
|
Requirement |
Version |
|---|---|
|
Minimum SDK |
26 |
|
compileSdk |
35 |
|
Java / JVM Target |
17 |
|
Android Gradle Plugin |
8.9.0 |
|
Gradle Wrapper |
8.11.1 |
|
Kotlin |
1.9+ |
1.3.2. 2 Maven Repository Configuration
Add the Novarum Maven repository to your root build.gradle or settings.gradle file.
This configuration retrieves an authorization token for each build from AWS CodeArtifact.
def codeartifactToken = "aws codeartifact get-authorization-token --domain novarumdx --domain-owner 945969778369 --query authorizationToken --output text --profile ndxcodeartifact".execute().text.trim()
allprojects {
repositories {
maven {
credentials {
username = 'aws'
password = codeartifactToken
}
url 'https://novarumdx-945969778369.d.codeartifact.eu-west-2.amazonaws.com/maven/novarum.client.maven/'
}
google()
mavenCentral()
}
}
1.3.3. 3 Gradle Configuration
Ensure your module build.gradle uses the following settings:
android {
namespace "com.example.app"
compileSdk = 35
defaultConfig {
minSdk = 26
targetSdk = 35
}
compileOptions {
sourceCompatibility JavaVersion.VERSION_17
targetCompatibility JavaVersion.VERSION_17
}
kotlinOptions {
jvmTarget = "17"
}
}
dependencies {
implementation "org.novarumdx:camerax:<version>"
}
1.4. Android Manifest Configuration
The SDK requires access to the camera.
Add the following entries to your app’s AndroidManifest.xml:
<uses-permission android:name="android.permission.CAMERA"/>
<uses-feature android:name="android.hardware.camera" android:required="true" />
If your app targets Android 13+ and uses runtime permissions, request android.permission.CAMERA before starting a scan.
Request camera permission before displaying NovarumAnalyzerPreview.
1.5. Using the Reader View
The Novarum Analyzer Preview is the primary camera component used to display the live feed and perform the test analysis.
It can be embedded in either a traditional XML layout or a Jetpack Compose UI, depending on your project setup.
1.5.1. XML-Based Integration
For standard View-based layouts, include the NovarumAnalyzerPreview directly in your XML layout file:
<org.novarumdx.camerax.NovarumAnalyzerPreview
android:id="@+id/previewView"
android:layout_width="match_parent"
android:layout_height="match_parent" />
Then configure it in your Activity or Fragment:
val configJson = /* your analyser configuration JSON */
val analyserConfiguration = PMFLoader.loadAnalyserConfiguration(json = configJson)
binding.previewView.analyzerConfig = analyserConfiguration
binding.previewView.previewMode = PreviewMode.Fill
binding.previewView.onFrameCaptured = { callback ->
// Track scan progress, brightness, orientation, etc.
val progress = callback.progress
}
binding.previewView.onComplete = { result ->
// Handle analysis completion
}
val result = binding.previewView.abort() // Aborts the scan if required
1.5.2. Compose Integration
The SDK also provides a ReaderView composable for use in Jetpack Compose projects.
It wraps NovarumAnalyzerPreview internally and provides the same functionality with Compose-friendly bindings.
@Composable
fun AnalyzerScreen(analyserConfiguration: AnalyserConfiguration, onComplete: (ResultModel) -> Unit) {
ReaderView(
analyserConfiguration = analyserConfiguration,
previewMode = PreviewMode.Fill, // or PreviewMode.Fit
onComplete = onComplete,
onAbort = { result ->
// Handle abort event (result may be null if no frames processed)
}
)
}
1.5.2.1. Example With UI Controls
@Composable
fun AnalyzerScreen(analyserConfiguration: AnalyserConfiguration) {
var progress by remember { mutableFloatStateOf(0f) }
ReaderView(
analyserConfiguration = analyserConfiguration,
previewMode = PreviewMode.Fill,
onFrameCaptured = { callback ->
progress = callback.progress
},
onComplete = { result ->
// Handle analysis result
},
onAbort = { result ->
// Handle abort event
}
)
}
1.5.3. Parameter Overview
|
Parameter |
Type |
Description |
|---|---|---|
|
analyserConfiguration |
|
The analyser configuration JSON object defining the test setup and analysis parameters. |
|
onComplete |
|
Invoked when the analysis successfully completes. Provides the full analysis result. |
|
onAbort |
|
Called when the scan is aborted manually via |
|
onFrameCaptured |
|
Triggered for every frame processed by the reader. Useful for updating progress indicators or monitoring lighting/orientation. |
|
previewMode |
|
Controls camera scaling within the view. Options:
|
To abort a running scan, call
preview.abort()on theNovarumAnalyzerPreviewinstance.
TheonAbortcallback will then receive the partial analysis data.
1.5.4. Callback Data Structures
The SDK exposes several structured models representing frame-level and result-level data.
1.5.4.1. FrameCapturedCallback
data class FrameCapturedCallback(
val progress: Float,
val resultPMF: ResultPMF,
val stripStatuses: List<StripStatus>,
val orientation: List<Double>,
val lux: Float,
)
|
Property |
Type |
Description |
|---|---|---|
|
progress |
|
Current scan progress (0.0 – 1.0). |
|
resultPMF |
|
Frame-level fit classification ( |
|
stripStatuses |
|
Current status of each detected strip. |
|
orientation |
|
Device orientation at capture time. |
|
lux |
|
Ambient light level. |
1.5.4.2. ResultModel
data class ResultModel(
val testConfiguration: TestConfiguration,
val testStrips: List<TestStrip>,
val pmfStory: List<FrameData>,
)
|
Property |
Type |
Description |
|---|---|---|
|
testConfiguration |
|
Test setup and analyser parameters. |
|
testStrips |
|
List of analysed strips with control/test line data. |
|
pmfStory |
|
All captured frame data during the analysis session. |
1.5.5. Related Data Types
|
Type |
Kind |
Description |
|---|---|---|
|
ResultPMF |
|
Indicates the per-frame fit result ( |
|
StripStatus |
|
Indicates strip condition ( |
|
TestStrip |
|
Contains data for one analysed strip (C-line, T-lines, profiles, baselines). |
|
FrameData |
|
Metadata for each captured frame (lighting, homography, orientation, etc.). |
For full type definitions, refer to the generated documentation within Android Studio.
1.5.6. Behaviour Notes
-
previewModedetermines how the live camera preview scales to your layout.Fill(default) maximises coverage, whileFitensures full frame visibility. -
The
abort()method immediately stops scanning and triggersonAbort, returning partial data. -
Both XML and Compose integrations share the same underlying
NovarumAnalyzerPreviewlogic.
1.6. Optional: SVG Overlay Visualisation
The SDK supports an optional SVG-based overlay rendering mode for higher-quality graphics and scalable test result visuals.
-
Default visualisation mode: dotMatrix
-
To enable SVG overlays, request an updated Analyser Configuration File from Novarum support.
-
No code changes are required — the overlay mode is controlled via configuration.
1.7. Embedded Assets
The SDK now includes dedicated image assets for exposure strip errors and other visual cues.
These assets are embedded within the SDK — no customisation or configuration is required by developers.
1.8. Native Code Considerations
If your app or modules build native (JNI/C++) components:
-
Update to NDK r29.0.14033849 rc4
-
Update CMake to 3.22.1
-
Rebuild your project with:
./gradlew clean assembleRelease
This ensures compatibility with the SDK’s OpenCV 4.12.0 dependency.
1.9. Troubleshooting & Support
|
Issue |
Possible Cause |
Resolution |
|---|---|---|
|
Build fails with “invalid target JDK” |
Using JDK 11 or 1.8 |
Update Gradle JDK to 17 |
|
AGP / Gradle mismatch |
AGP < 8.9.0 |
Update Android Gradle Plugin to 8.9.0 and Gradle Wrapper to 8.11.1 |
|
Cannot access CodeArtifact |
Invalid or expired AWS token |
Regenerate token or verify AWS CLI profile |
|
Overlay not scaling correctly |
Outdated configuration file |
Request updated analyser configuration (SVG enabled) |
For further assistance or updated configuration files, contact your Novarum technical representative.
1.10. Version Compatibility Summary
|
Component |
Current Version |
Notes |
|---|---|---|
|
Novarum SDK |
v3.0.0 |
Current release |
|
Minimum SDK |
26 |
Required |
|
compileSdk |
35 |
Required |
|
Java / JVM Target |
17 |
Required |
|
Gradle |
8.11.1 |
Required for AGP 8.9.0 |
|
AGP |
8.9.0 |
Required |
|
OpenCV |
4.12.0 |
Internal dependency |
|
NDK |
29.0.14033849 rc4 |
Required for native builds |
|
CMake |
3.22.1 |
Required for native builds |