The Java API in package com.affectiva.vision, delivered as an AAR
(com.affectiva.android:emotion-sdk) for arm64-v8a devices on Android 8.0 (API 26) and
newer. The native library loads automatically when a detector class is first used. This page
documents exactly what the Android binding exposes; anything not listed (baseline mode, the
sensor/connector pipeline, grayscale input) is available
only in C++.
Detectors
Detector (abstract base class)
Common behavior shared by both concrete detectors. Constructing any detector requires an Android
Context, which the SDK uses to initialize its runtime data on first run.
Lifecycle
| Method | Description |
|---|---|
void start(String license) | validates the Affectiva license key and initializes processing; throws
AffectivaException if the license is missing or invalid |
void stop() | immediately stops processing and deallocates processing resources |
void reset() | re-initializes for a new camera session without stop/start; frame timestamps may restart at 0 |
boolean isRunning() | true after start() and before stop() |
void process(Frame frame) | submits a frame; timestamps must strictly increase |
void dispose() | releases the underlying native detector. Required when the detector is no
longer needed (e.g. in onDestroy()); calls on a disposed detector are ignored and
logged |
Feature control
| Method | Description |
|---|---|
void enable(Feature feature) / void enable(List<Feature> features) | adds to the enabled set |
void disable(Feature feature) / void disable(List<Feature> features) | removes from the enabled set |
boolean isEnabled(Feature feature) | true if the feature is enabled |
boolean isEnabled(List<Feature> features) | true only if all given features are enabled |
List<Feature> getEnabledFeatures() | the currently enabled features |
Listener registration
| Method | Description |
|---|---|
void setImageListener(ImageListener imageListener) | register the per-frame results callback (the primary results interface on Android) |
void setFaceListener(FaceListener faceListener) | register the face found/lost callback |
void setProcessStatusListener(ProcessStatusListener statusListener) | register the background-error callback |
FrameDetector β asynchronous
Queues pushed frames and processes them on a background thread with real-time semantics: frames
that arrive closer together than 1 / processingFrameRate are discarded so processing
never falls behind. Callbacks are invoked on the background thread.
FrameDetector(Context context)
FrameDetector(Context context, float processingFrameRate)
FrameDetector(Context context, float processingFrameRate, int maxNumFaces)
FrameDetector(Context context, float processingFrameRate, int maxNumFaces, int maxThreadPoolSize)
Defaults: processingFrameRate = 30, maxNumFaces = 1,
maxThreadPoolSize = 0 (0 = “use number of CPU cores β 1”).
SyncFrameDetector β synchronous
Processes every pushed frame (never drops) and invokes callbacks on the thread that
called process(), which blocks until the frame’s callbacks complete. Do not use it on
the UI thread.
SyncFrameDetector(Context context)
SyncFrameDetector(Context context, int maxNumFaces)
SyncFrameDetector(Context context, int maxNumFaces, int maxThreadPoolSize)
Defaults: maxNumFaces = 1, maxThreadPoolSize = 0.
Frame
Wraps one image and its timestamp; pixels are supplied as a byte[].
Frame(int width, int height, byte[] pixels, ColorFormat colorFormat, long timeStamp)
Frame(int width, int height, byte[] pixels, ColorFormat colorFormat, Rotation rotation, long timeStamp)
timeStamp is in milliseconds, identifies the frame, and must strictly increase
across successive process() calls.
| Method | Description |
|---|---|
int getWidth() / int getHeight() | dimensions in px |
byte[] getPixels() | the pixel buffer |
ColorFormat getColorFormat() | the declared pixel format |
Rotation getRotation() | the declared rotation |
long getTimeStamp() | timestamp in ms |
Frame.ColorFormat
RGB, BGR, RGBA, BGRA,
YUV_NV21, YUV_I420, YUV_YUY2. Android camera preview data is
typically YUV_NV21 (CameraX YUV_420_888 images convert to NV21).
Grayscale (GRAY) input is not available in the Android binding.
Frame.Rotation
UPRIGHT, CW_90, CW_180, CW_270 β how the
image is rotated (clockwise) relative to an upright face. Map CameraX’s
getRotationDegrees() to these values instead of rotating pixel buffers.
Face
One tracked face in a processed frame, delivered via
ImageListener.onImageResults as a Map<Integer, Face> keyed by face
id. The metric enums are nested inside Face.
| Method | Returns |
|---|---|
int getId() | tracking identifier, stable while the face stays in view |
float getConfidence() | confidence in the presence of the face, 0β100 |
Map<Expression, Float> getExpressions() | one value per enabled expression |
Map<Emotion, Float> getEmotions() | one value per enabled emotion |
Map<Measurement, Float> getMeasurements() | head pose and measurements |
Map<Quality, Float> getQualities() | image quality metrics |
List<Point> getBoundingBox() | two points: top-left, then bottom-right |
Map<FacePoint, Point> getFacePoints() | landmark positions in px |
Face.Point
A 2-D pixel coordinate with float getX() and float getY(). Instances
are created by the SDK.
Listeners
ImageListener
The primary per-frame results interface on Android. Register with
setImageListener() before start().
| Callback | Called when |
|---|---|
void onImageResults(Map<Integer, Face> faces, Frame frame) | a frame has been processed; delivers all tracked faces with their metrics |
void onImageCapture(Frame frame) | every input frame, including frames the asynchronous detector chose not to process |
FaceListener
Face appearance/disappearance events (per-frame metric results arrive via
ImageListener on Android).
| Callback | Called when |
|---|---|
void onFaceFound(long timestamp, int faceId) | the tracker starts tracking a new face |
void onFaceLost(long timestamp, int faceId) | a tracked face is no longer found |
ProcessStatusListener
void onProcessingException(AffectivaException exception)
Delivers exceptions raised on background processing threads, where they cannot be thrown into
your code. Always register one when using FrameDetector.
AffectivaException
Derived from RuntimeException; thrown by SDK methods (for example
start() with a missing or invalid license) and delivered by
ProcessStatusListener for background errors.
Enumerations
The tables below give concise definitions. For a full explanation of each metric β the facial actions behind it, value semantics, and interpretation guidance β see the Metrics guide.
Feature
Top-level enum with two values: EXPRESSIONS and EMOTIONS. Face
detection/tracking metrics (bounding box, face points, measurements, qualities, confidence) are
always delivered for tracked faces; enable only the families you use to reduce CPU load.
Face.Expression
Continuous metrics range 0 (absent) to 100 (fully present); event metrics report 0 or 100.
| Value | Description | Range |
|---|---|---|
SMILE | upward pull of the lip corners | 0β100 |
INNER_BROW_RAISE | raising of the inner brow corners | 0β100 |
BROW_RAISE | raising of both brows | 0β100 |
BROW_FURROW | lowering/drawing together of the brows | 0β100 |
NOSE_WRINKLE | wrinkling of the nose | 0β100 |
UPPER_LIP_RAISE | raising of the upper lip | 0β100 |
LIP_CORNER_DEPRESSOR | downward pull of the lip corners | 0β100 |
CHIN_RAISE | upward push of the chin boss | 0β100 |
LIP_PUCKER | puckering of the lips | 0β100 |
LIP_PRESS | pressing the lips together | 0β100 |
LIP_SUCK | pulling the lips inward | 0β100 |
MOUTH_OPEN | parting of the lips | 0β100 |
SMIRK | asymmetric lip corner pull | 0β100 |
EYE_CLOSURE | both eyelids closed | 0β100 |
SPEAKING | the person is speaking | 0β100 |
ATTENTION | visual attention toward the camera (head orientation) | 0β100 |
EYE_WIDEN | widening of the eyes | 0β100 |
CHEEK_RAISE | raising of the cheeks | 0β100 |
LID_TIGHTEN | tightening of the eyelids | 0β100 |
DIMPLER | tightening of the lip corners (dimpling) | 0β100 |
LIP_STRETCH | horizontal stretching of the lips | 0β100 |
JAW_DROP | lowering of the jaw | 0β100 |
BLINK | a blink occurred | 0 / 100 |
BLINK_RATE | blinks per minute; NaN during the first 10Β s after a face is detected | blinks/min |
YAWN | a yawn occurred | 0 / 100 |
PAIN | continuous estimate that the person is expressing pain; 50 is the model’s decision threshold, so values above 50 mean pain is more likely present than not | 0β100 |
Face.Emotion
0β100 except the valence metrics (β100 to +100). Values: JOY, FEAR,
DISGUST, SADNESS, ANGER, SURPRISE,
CONTEMPT, NEUTRAL, SENTIMENTALITY, CONFUSION,
VALENCE, ENGAGEMENT, CONVERSATIONAL_VALENCE,
CONVERSATIONAL_ENGAGEMENT, ADAPTIVE_VALENCE,
ADAPTIVE_ENGAGEMENT β same definitions as the
C++ Emotion enum.
Face.Measurement
PITCH, YAW, ROLL (head pose in degrees; 0/0/0 = facing the
camera) and INTEROCULAR_DISTANCE (pixels between the outer eye corners).
Face.FacePoint
OUTER_RIGHT_EYE, OUTER_LEFT_EYE, NOSE_TIP,
CHIN_TIP β landmark identifiers for getFacePoints().
Face.Quality
BRIGHTNESS (0β100) β useful for detecting under- or over-exposed capture
conditions.
Lifecycle & threading
- Always
dispose()detectors you no longer need; relying on garbage collection alone leaks native memory. Afterdispose(), further calls on the object are ignored (and logged as errors). FrameDetectorcallbacks arrive on a background thread β post to the main thread before touching views.- Between camera sessions, prefer
reset()over recreating the detector. - The AAR ships arm64-v8a native libraries aligned for 16Β KB memory pages (Android 15+
compatible). Restrict your app’s ABIs accordingly:
ndk { abiFilters 'arm64-v8a' }.