Reader SDK Documents

IFU009(03) Reader SDK Android Integration Guide

Novarum DX Ltd
Instructions for Use / Guides

Document ID: IFU009 
Revision: 03 
Released: Aug 5, 2026 

1. Overview

The Novarum Reader SDK for Android enables Android applications to perform camera capture, analysis, PMF fitting, strip status reporting, and result callback delivery for lateral flow tests.

This guide describes how to integrate the SDK into an Android project using Gradle and AWS CodeArtifact.

2. Project Setup

2.1. Minimum Requirements

Item

Minimum

Minimum SDK

26

compileSdk

35

Java / JVM target

17

Android Gradle Plugin

8.9.0

Gradle Wrapper

8.11.1

Kotlin

1.9+

2.2. Registry Authentication

Access to the Novarum SDK Maven repository is provided via AWS CodeArtifact.
Install and configure the AWS CLI before adding the dependency.

2.2.1. Installation

Refer to AWS Command Line Interface for installation details.
On macOS, you can install via Homebrew:

Bash
brew install awscli

2.2.2. Profile Configuration

You will need the AWS credentials provided by Novarum.

Interactive setup:

Bash
aws configure --profile ndxcodeartifact

You will 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:

Bash
aws configure set aws_access_key_id "${ECR_KEY}"
aws configure set aws_secret_access_key "${ECR_SECRET}"
aws configure set region "${AWS_REGION}"

2.3. Add the SDK Dependency

Add the Novarum Maven repository to your root build.gradle or settings.gradle file.

This configuration retrieves an authorisation token for each build from AWS CodeArtifact.

Groovy
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()
    }
}

2.4. Platform Configuration

Ensure your module build.gradle uses the following settings:

Kotlin
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:ndx-imaging-android:<version>"
}

The SDK requires access to the camera.
Add the following entries to your app’s AndroidManifest.xml:

XML
<uses-permission android:name="android.permission.CAMERA"/>
<uses-feature android:name="android.hardware.camera" android:required="true" />

3. Using the Reader View

The Novarum Analyser Preview is the primary camera component used to display the live feed and perform the test analysis.
Embed it in either a Jetpack Compose UI or a traditional XML layout, depending on your project setup.

3.1. Loading the Analyser Configuration

Load the analyser configuration JSON file you were provided by Novarum:

Kotlin
val configJson = /* your analyser configuration JSON */
val analyserConfiguration = PMFLoader.loadAnalyserConfiguration(json = configJson)

3.2. Jetpack Compose Integration

The SDK is compatible with Compose UI. Wrap NovarumAnalyzerPreview with AndroidView.

This note applies to Jetpack Compose only. Hide or remove the preview before navigation so the camera preview does not display over the next screen.

Kotlin
@Composable
fun ReaderView(
    analyserConfiguration: AnalyserConfiguration,
    onComplete: (AnalysisModel) -> Unit = {},
    onAbort: (AnalysisModel?) -> Unit = {},
    previewMode: PreviewMode = PreviewMode.Fill,
) {
    var progress by remember { mutableFloatStateOf(0f) }
    var isFinished by remember { mutableStateOf(false) }
    val context = LocalContext.current
    val preview = remember {
        NovarumAnalyzerPreview(context).apply {
            analyzerConfig = analyserConfiguration
            onFrameCaptured = { callback ->
                progress = callback.progress
            }
            this.onComplete = { result ->
                isFinished = true
                onComplete(result)
            }
            this.previewMode = previewMode
        }
    }

    AndroidView(factory = { preview })

    BackHandler {
        onAbort(preview.abort())
    }
}

3.3. XML Integration

For standard View-based layouts, include NovarumAnalyzerPreview directly in your XML layout file:

XML
<org.novarumdx.camerax.NovarumAnalyzerPreview
    android:id="@+id/previewView"
    android:layout_width="match_parent"
    android:layout_height="match_parent" />

Configure the preview in your Activity or Fragment:

Kotlin
binding.previewView.analyzerConfig = analyserConfiguration
binding.previewView.previewMode = PreviewMode.Fill

binding.previewView.onFrameCaptured = { callback ->
    val progress = callback.progress
}

binding.previewView.onComplete = { result ->
    // Handle analysis completion
}

val result = binding.previewView.abort()

3.4. Parameter Overview

Parameter

Type

Required

Description

analyserConfiguration

AnalyserConfiguration

Yes

The analyser configuration JSON object defining the test setup and analysis parameters.

onComplete

(AnalysisModel) -> Unit

Yes

Invoked when the analysis completes. Provides the full analysis result.

onAbort

(AnalysisModel?) -> Unit

No

Called when the scan is aborted manually via preview.abort(). Returns partial results or null if none are collected.

onFrameCaptured

(FrameCapturedCallback) -> Unit

No

Triggered for every frame processed by the reader. Use it to update progress indicators or monitor lighting and orientation.

previewMode

PreviewMode

No

Controls camera scaling within the view. Use PreviewMode.Fill to fill the container or PreviewMode.Fit to fit the full frame.

To abort a running scan, call preview.abort() on the NovarumAnalyzerPreview instance.

The onAbort callback receives the partial analysis data.

3.5. Callback Data Structures

The SDK exposes several structured models representing frame-level and result-level data.

3.5.1. FrameCapturedCallback

Kotlin
data class FrameCapturedCallback(
    val progress: Float,
    val resultPMF: ResultPMF,
    val stripStatuses: List<StripStatus>,
    val orientation: List<Double>,
    val lux: Float,
)

Property

Type

Description

progress

Float

Current scan progress (0.0 – 1.0).

resultPMF

ResultPMF

Frame-level fit classification (Fit, MarginalFit, NoFit).

stripStatuses

List<StripStatus>

Current status of each detected strip.

orientation

List<Double>

Device orientation at capture time.

lux

Float

Ambient light level.

3.5.2. ResultModel

Kotlin
data class AnalysisModel(
    val testConfiguration: TestConfiguration,
    val testStrips: List<TestStrip>,
    val pmfStory: List<FrameData>,
)

Property

Type

Description

testConfiguration

TestConfiguration

Test setup and analyser parameters.

testStrips

List<TestStrip>

List of analysed strips with control/test line data.

pmfStory

List<FrameData>

All captured frame data during the analysis session.

Type

Kind

Description

ResultPMF

enum

Indicates the per-frame fit result (Fit, MarginalFit, NoFit).

StripStatus

enum

Indicates strip condition (None, ExposureError, BaselineError, Good, Done).

TestStrip

data class

Contains data for one analysed strip (C-line, T-lines, profiles, baselines).

FrameData

data class

Metadata for each captured frame (lighting, homography, orientation, etc.).

For full type definitions, refer to the generated documentation within Android Studio.

3.7. Behaviour Notes

  • Preview mode. previewMode determines how the live camera preview scales to your layout. PreviewMode.Fill maximises coverage, while PreviewMode.Fit keeps the full frame visible.

  • Abort. Call abort() to stop scanning immediately and trigger onAbort with partial data when available.

  • Screen keep-awake. The SDK keeps the screen awake during active capture by setting FLAG_KEEP_SCREEN_ON or the equivalent platform flag.

  • Backgrounding and foregrounding. The camera pauses when the app moves to the background and resumes when the app returns to the foreground, subject to the host Activity or Fragment lifecycle.

  • PMFInitialHScaleFactor. Android does not require a public integration parameter for PMFInitialHScaleFactor; configure PMF behaviour through the analyser configuration supplied by Novarum.

  • Shared preview logic. XML and Compose integrations use the same underlying NovarumAnalyzerPreview behaviour.

3.8. 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.

4. Version Compatibility Summary

Component

Current Version

Notes

Novarum Android SDK

v4.1.1

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

4.1. 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:

    Bash
    ./gradlew clean assembleRelease
    

This ensures compatibility with the SDK’s OpenCV 4.12.0 dependency.

5. Support & Troubleshooting

Symptom

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 the token or verify the AWS CLI profile.

UnauthorizedException or 403 from Maven during build

CodeArtifact authorisation token has expired. Tokens last 12 hours by default.

Re-run aws codeartifact get-authorization-token to refresh the token, or automate token refresh in your CI pipeline.

For access credentials, configuration files, or integration assistance, please contact your Novarum support representative or technical account manager.


For streamlined support and rapid troubleshooting, users can access the https://novarum.atlassian.net/servicedesk/customer/portal/15. This portal provides a direct channel for submitting integration queries, reporting issues, and tracking the status of your requests. In addition, the service desk is equipped with an intelligent agent capable of answering common technical questions and guiding you through standard troubleshooting steps.

We recommend using this resource for the fastest resolution of SDK-related issues or to obtain up-to-date technical guidance.

6. Document History

Revision Summary Date
01 Initial document revision Nov 13, 2025
02 Revision for version 4.0.1 Android SDK layer using c++ core 1.0.0 Jul 20, 2026
03 AI Review to sync the different platforms Aug 5, 2026