Methods
Reference for all public Circadify Android SDK methods.
Reference for the public methods on CircadifySDK.
measureVitals(options)
Runs the full measurement flow: session creation, camera capture, quality checks, secure upload, and result polling.
lifecycleScope.launch {
try {
val result = sdk.measureVitals(
MeasurementOptions(
lifecycleOwner = this@MainActivity,
previewView = previewView,
),
)
showResult(result)
} catch (error: CircadifyError) {
showError(error.message)
}
}kotlinParameters (MeasurementOptions):
| Name | Type | Required | Description |
|---|---|---|---|
lifecycleOwner | LifecycleOwner | Yes | Lifecycle used by CameraX. Usually an Activity, Fragment, or LifecycleOwner from Compose. |
previewView | PreviewView? | No | CameraX preview surface owned by your app. |
demographics | Demographics? | No | Optional age, sex, and Fitzpatrick skin type. See Configuration → Demographics for the full type. |
cancellationSignal | CancellationSignal? | No | Cancels this measurement. |
Returns: VitalSignsResult
data class VitalSignsResult(
val heartRate: Double,
val hrv: Double?,
val respiratoryRate: Double?,
val spo2: Double?,
val systolicBp: Double?,
val diastolicBp: Double?,
val confidence: Double,
val timestamp: Long,
val sessionId: String,
)kotlinA confidence above 0.7 indicates a reliable measurement. Below 0.4 suggests quality issues and should usually prompt a retry.
Capture behavior
The Android SDK uses a frame-threshold capture policy instead of requiring a fixed 720-frame payload. By default, capture targets 10 FPS and starts upload once at least 150 quality frames have been accepted. The SDK encodes the actual frame count and FPS in the upload payload so the Circadify backend can process measurements from a wider range of Android devices.
If a lower-end device accepts frames more slowly, the SDK continues only until the minimum accepted-frame threshold is reached or the capture timeout is hit. If quality is good, upload starts immediately after enough usable frames are available.
val sdk = CircadifySDK(
context = context,
config = CircadifyConfig(
apiKey = "ck_live_your_key_here",
measurementDurationSeconds = 30,
targetCaptureFps = 10,
minimumAcceptedFrames = 150,
maximumAcceptedFrames = 720,
),
)kotlinPrefer the defaults unless you have validated a different policy on your target devices. Lowering targetCaptureFps reduces device load; lowering minimumAcceptedFrames may reduce result confidence.
checkCameraAccess()
Checks whether camera permission is granted and a camera exists on the device. It does not request permission.
if (sdk.checkCameraAccess()) {
startMeasurement()
} else {
requestCameraPermission()
}kotlinReturns: Boolean
getDeviceCapabilities()
Returns camera support and permission information.
val capabilities = sdk.getDeviceCapabilities()
// Check the lens you plan to capture from: hasFrontCamera for the default front
// camera, or hasBackCamera when you set cameraLensFacing = CameraLensFacing.BACK.
if (!capabilities.hasFrontCamera) {
showMessage("A front camera is required for self-measurement.")
}kotlinReturns: DeviceCapabilities
data class DeviceCapabilities(
val hasCamera: Boolean,
val hasFrontCamera: Boolean,
val cameraPermissionGranted: Boolean,
val mediaDevicesSupported: Boolean = true,
val isSecureContext: Boolean = true,
val maxResolution: Resolution? = null,
val hasBackCamera: Boolean = false,
)kotlinCircadifyOverlayView
A standard Android View that renders the SDK's first-party thermal scan overlay — a gold guide oval plus a heat-glow that roves across the forehead and cheeks, tracking the live face and pulsing hotter while a measurement runs. Drop it on top of your CameraX PreviewView (identical bounds, e.g. in a FrameLayout) and feed it geometry from the onScanFace callback.
// Geometry arrives on the onScanFace callback; null when no face is detected.
overlay.scanFace = face
// Drive the hotter, faster glow while a measurement runs.
overlay.isScanning = true
// Optionally retheme the glow colors and per-region timings.
overlay.style = CircadifyScanStyle()kotlinscanFace: CircadifyScanFace?— live face geometry to paint, ornullto clear the glow. Fed fromCircadifyCallbacks.onScanFace.isScanning: Boolean—truedrives the hotter, faster glow during an active measurement;falseis the calmer idle/framing look.style: CircadifyScanStyle— glow colors and per-region timings. Defaults to the warm thermal ramp; override any field to recolor or re-time the glow.
The view does not intercept touches and animates itself while attached to the window (respecting the system "remove animations" accessibility setting). See Scan Overlay for the full layout, lifecycle, and custom-overlay guide.
cancel()
Cancels an active measurement. The running measureVitals() call throws a CircadifyError with code CANCELLED.
cancelButton.setOnClickListener {
sdk.cancel()
}kotlinYou can also cancel by cancelling the coroutine or by passing a CancellationSignal:
val signal = CancellationSignal()
lifecycleScope.launch {
sdk.measureVitals(
MeasurementOptions(
lifecycleOwner = this@MainActivity,
previewView = previewView,
cancellationSignal = signal,
),
)
}
signal.cancel()kotlindestroy()
Releases SDK resources and cancels active scanning. Call it when the owning screen is destroyed.
override fun onDestroy() {
sdk.destroy()
super.onDestroy()
}kotlinAfter destroy(), create a new CircadifySDK instance before measuring again.
Next Steps
- Configuration - Callbacks and options
- Performance & Device Support - Lower-end device tuning
- Camera & Permissions - Permission flow
- Error Handling - Handle
CircadifyError