Suntech.KazamCaptureAI 1.0.12

Suggested Alternatives

Suntech.Cattura.SDK 1.0.12

dotnet add package Suntech.KazamCaptureAI --version 1.0.12
                    
NuGet\Install-Package Suntech.KazamCaptureAI -Version 1.0.12
                    
This command is intended to be used within the Package Manager Console in Visual Studio, as it uses the NuGet module's version of Install-Package.
<PackageReference Include="Suntech.KazamCaptureAI" Version="1.0.12" />
                    
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="Suntech.KazamCaptureAI" Version="1.0.12" />
                    
Directory.Packages.props
<PackageReference Include="Suntech.KazamCaptureAI" />
                    
Project file
For projects that support Central Package Management (CPM), copy this XML node into the solution Directory.Packages.props file to version the package.
paket add Suntech.KazamCaptureAI --version 1.0.12
                    
#r "nuget: Suntech.KazamCaptureAI, 1.0.12"
                    
#r directive can be used in F# Interactive and Polyglot Notebooks. Copy this into the interactive tool or source code of the script to reference the package.
#:package Suntech.KazamCaptureAI@1.0.12
                    
#:package directive can be used in C# file-based apps starting in .NET 10 preview 4. Copy this into a .cs file before any lines of code to reference the package.
#addin nuget:?package=Suntech.KazamCaptureAI&version=1.0.12
                    
Install as a Cake Addin
#tool nuget:?package=Suntech.KazamCaptureAI&version=1.0.12
                    
Install as a Cake Tool

Suntech.KazamCaptureAI

KAZAM CAPTURE AI — Zebra AI DataCapture SDK for .NET MAUI and .NET for Android.

A .NET binding library that exposes barcode decoding and OCR (text recognition) capabilities of Zebra AI DataCapture on Zebra mobile devices.


Table of contents


Features

  • Barcode decoding — 44+ symbologies (1D/2D/postal) via Zebra AI DataCapture SDK
  • OCR text recognition — Multi-line, high-accuracy text recognition with stabilization
  • Combined mode — Barcode + OCR simultaneously in the same camera preview
  • Three selection modes — Automatic, Manual (tap), Accumulate (batch)
  • OCR filters — Numeric, alpha, alphanumeric, exact match, starts-with, contains, regex
  • Offline JWT license — RSA-SHA256 signed, device-locked, no network calls
  • DEMO mode — Full functionality with degraded results (asterisks) for evaluation
  • Full-screen overlay UI — Built-in camera preview, torch, settings panel
  • Tap-to-focus — Tap any area of the preview to focus at that point
  • Inactivity timeout — Auto-closes the scanner after N ms of no detections

Requirements

  • .NET 10 or later (net10.0-android36.0)
  • .NET MAUI or .NET for Android project
  • Zebra mobile device with Zebra AI DataCapture support
  • Android API 30+ (Android 11 or later)
  • License JWT provided by Suntech, or the string "DEMO" for evaluation

Compatible devices

Device Barcode OCR Notes
Zebra TC53 Primary target, fully tested
Other Zebra AI DataCapture devices Requires Zebra AI DataCapture SDK support

The SDK uses Zebra AI Vision libraries which are only available on Zebra hardware. On non-Zebra devices the callback will receive ZebraAiError with code CODE_SDK_NOT_AVAILABLE.


Installation

<PackageReference Include="Suntech.KazamCaptureAI" Version="1.0.12" />

All transitive dependencies (Kotlin stdlib, CameraX, AndroidX, etc.) are declared in the package and resolved automatically by NuGet — no manual package additions required.


Android Manifest permissions

Add the following permissions to your AndroidManifest.xml:


<uses-permission android:name="android.permission.CAMERA" />


<uses-permission android:name="android.permission.VIBRATE" />


<uses-permission android:name="android.permission.READ_PHONE_STATE" />

MAUI note: Request CAMERA permission at runtime before calling Scan(). The SDK internally requests it via ActivityCompat.requestPermissions if missing, but it is better practice to request it from your app code.


Quick start

Minimal example

using IT.Suntech.Zebraai.Sdk;

// ── 1. Initialize once at app startup ───────────────────────────────────────
// Pass your JWT license, or "DEMO" for evaluation
try
{
    ZebraAiScanner.Initialize(context, "DEMO");
}
catch (LicenseException ex)
{
    // Invalid JWT, expired license, or unauthorized device
    Console.Error.WriteLine(ex.Message);
    return;
}

// ── 2. Configure the scanner ─────────────────────────────────────────────────
ZebraAiScanner.Configure(new ZebraAiConfig
{
    RecognitionMode = RecognitionMode.Barcode,
    SelectionMode   = SelectionMode.Automatic,
});

// ── 3. Start a scan ───────────────────────────────────────────────────────────
ZebraAiScanner.Scan(activity, new MyCallback());

// ── 4. Handle the result ──────────────────────────────────────────────────────
class MyCallback : Java.Lang.Object, IZebraAiCallback
{
    public void OnResult(ZebraAiResult result)
        => Console.WriteLine($"[{result.Type}] {result.Symbology}: {result.Value}");

    public void OnResults(IList<ZebraAiResult> results)
    {
        foreach (var r in results)
            Console.WriteLine($"[{r.Type}] {r.Symbology}: {r.Value}");
    }

    public void OnError(ZebraAiError error)
        => Console.Error.WriteLine($"Error {error.Code}: {error.Message}");

    public void OnCancelled()
        => Console.WriteLine("Scan cancelled by user");
}
// Wraps the callback in a TaskCompletionSource — await the result directly.
var tcs = new TaskCompletionSource<IList<ZebraAiResult>>();

ZebraAiScanner.Configure(new ZebraAiConfig
{
    RecognitionMode = RecognitionMode.Ocr,
    SelectionMode   = SelectionMode.Accumulate,
    OcrFilter = new OcrFilterConfig
    {
        MinConfidencePercent = 70,
        FilterType           = OcrFilterType.NumericOnly,
    }
});

ZebraAiScanner.Scan(Platform.CurrentActivity, new SimpleCallback(
    onResult:    r  => tcs.TrySetResult(new[] { r }),
    onResults:   rs => tcs.TrySetResult(rs),
    onError:     e  => tcs.TrySetException(new Exception($"{e.Code}: {e.Message}")),
    onCancelled: () => tcs.TrySetCanceled()
));

var results = await tcs.Task;

Lifecycle

App startup
    └─ ZebraAiScanner.Initialize(context, licenseJwt)   ← once only
           │
           ├─ License verified (offline RSA-SHA256)
           ├─ Native Zebra libraries loaded
           └─ SDK ready

Per-scan
    └─ ZebraAiScanner.Configure(config)                  ← optional, update config
           │
    └─ ZebraAiScanner.Scan(activity, callback)           ← opens full-screen overlay
           │
           ├─ Camera starts, AI decoders initialized
           ├─ Results detected → callback.OnResult / OnResults
           ├─ User presses CLOSE → callback.OnCancelled
           └─ Overlay closed, scanner ready for next scan

App shutdown
    └─ ZebraAiScanner.Dispose()                          ← releases AI decoders

Initialize() is idempotent — calling it more than once is a no-op. Configure() can be called at any time between scans.


API reference

ZebraAiScanner {#zebraaiscannerclass}

The main entry point of the SDK. All methods are static.

namespace IT.Suntech.Zebraai.Sdk
static class ZebraAiScanner
Method Description
Initialize(Context, string) Verifies the JWT license and loads native libraries. Throws LicenseException on failure. Must be called once before any other method.
Configure(ZebraAiConfig) Updates the scanner configuration. Can be called at any time.
GetConfig() Returns the current ZebraAiConfig.
Scan(Activity, IZebraAiCallback) Opens the full-screen camera overlay. Calls the callback on result/error/cancellation.
Cancel() Requests cancellation of an ongoing scan. The callback will receive OnCancelled.
Dispose() Releases AI decoder resources. Call when the app is closing.
IsInitialized() Returns true if the SDK has been successfully initialized.
IsScanning() Returns true if a scan is currently in progress.

Properties:

Property Type Description
LicenseInfo ZebraAiScanner.LicenseInfoData? Active license info (customer, expiry, features, device count). null if not initialized.

ZebraAiConfig

Scanner configuration. All fields have default values — only override what you need.

var config = new ZebraAiConfig
{
    RecognitionMode      = RecognitionMode.Barcode,
    SelectionMode        = SelectionMode.Automatic,
    InactivityTimeoutMs  = 15_000,
    ShowSettingsButton   = false,
    OcrFilter            = new OcrFilterConfig { ... }
};
ZebraAiScanner.Configure(config);
Core options
Field Type Default Description
RecognitionMode RecognitionMode Barcode Recognition engine to use.
SelectionMode SelectionMode Automatic How results are selected and sent.
InactivityTimeoutMs long 10000 Auto-close timeout in ms. 0 = disabled.
ShowSettingsButton bool true Shows the ⚙ button in the overlay.
ShowTorchButton bool true Shows the flashlight button.
EnableTapToFocus bool true Tap empty area → camera focuses there.
Camera options
Field Type Default Description
CameraResolution CameraResolution FHD_1080P Camera capture resolution.
ProcessorType ProcessorType Auto AI inference processor (DSP, GPU, CPU, Auto).
Barcode options
Field Type Default Description
BarcodeModelInput int 1280 AI model input size in pixels (640, 1280, 1600).
EnabledSymbologies MutableSet<Symbology> Common set Set of enabled barcode symbologies.
Inverse1DMode int 2 0=Disabled, 1=Enabled, 2=Auto.
LinearSecurityLevel int 0 0–3 (aggressive→safe).
MarginlessDecodeEffortLevel int 0 0–3.
PoorQualityDecodeEffortLevel int 0 0–3.
DatamatrixInverse int 2 0=Regular, 1=InverseOnly, 2=AutoDetect.
DotCodeInverse int 2 0=Disabled, 1=Enabled, 2=Auto.
GridMatrixMode int 2 0=Disabled, 1=Enabled, 2=Auto.
OCR options
Field Type Default Description
OcrModelInput int 1600 AI model input size (640, 1280, 1600, 2560).
OcrStabilizationFrames int 5 Frames for stabilization (1=fast, 15=stable).
OcrFilter OcrFilterConfig (see below) Text filter applied to OCR results.

OcrFilterConfig

Controls which OCR results are passed to the callback.

var config = new ZebraAiConfig
{
    RecognitionMode = RecognitionMode.Ocr,
    OcrFilter = new OcrFilterConfig
    {
        FilterType           = OcrFilterType.NumericOnly,
        MinConfidencePercent = 80,
        MinLength            = 6,
        MaxLength            = 13,
        CaseTransform        = OcrCaseTransform.Uppercase,
    }
};
Field Type Default Description
FilterType OcrFilterType ShowAll Text filter to apply.
CaseTransform OcrCaseTransform None Output case transformation.
MinConfidencePercent int 0 Minimum OCR confidence (0–100). Lines below this are discarded before stabilization.
MinLength int 1 Minimum character length (for types 1–6).
MaxLength int 50 Maximum character length (for types 1–6).
ExactMatchList string "" Comma-separated values for ExactMatch.
StartsWithList string "" Comma-separated prefixes for StartsWith.
ContainsList string "" Comma-separated substrings for Contains.
RegexPattern string "" Regular expression for Regex.

OcrFilterType values:

Value Description
ShowAll No filtering — all detected text is shown.
NumericOnly Keeps only lines that are purely numeric (digits).
AlphaOnly Keeps only lines that are purely alphabetic.
AlphaNumericOnly Keeps only lines with letters and digits (no special characters).
ExactMatch Keeps lines that exactly match any value in ExactMatchList.
StartsWith Keeps lines starting with any prefix in StartsWithList.
Contains Keeps lines containing any substring in ContainsList.
Regex Keeps lines matching RegexPattern.

IZebraAiCallback {#zebraicallback}

Implement this interface to receive scan results. In MAUI you must extend both Java.Lang.Object and the interface:

class MyCallback : Java.Lang.Object, IZebraAiCallback
{
    // Called for AUTOMATIC, MANUAL, or single tap in ACCUMULATE mode
    public void OnResult(ZebraAiResult result) { ... }

    // Called for ACCUMULATE mode when the user presses "SEND ALL"
    public void OnResults(IList<ZebraAiResult> results) { ... }

    // Called on any error (see ZebraAiError error codes)
    public void OnError(ZebraAiError error) { ... }

    // Called when the user closes the scanner without scanning
    public void OnCancelled() { ... }
}

Which method is called, by mode:

SelectionMode Single result Multiple results
Automatic OnResult
Manual OnResult (user taps a box)
Accumulate OnResult (tap single item from list) OnResults ("SEND ALL")

ZebraAiResult

public class ZebraAiResult
{
    public string Value        { get; }  // Decoded value
    public ResultType Type     { get; }  // BARCODE or OCR
    public string? Symbology   { get; }  // e.g. "Code128", null for OCR
    public int SymbologyId     { get; }  // Zebra SDK numeric ID, -1 for OCR
    public float Confidence    { get; }  // 0.0 – 1.0
    public long Timestamp      { get; }  // Epoch milliseconds
}

ZebraAiError {#zebraierror}

public class ZebraAiError
{
    public int Code      { get; }
    public string Message { get; }
}

Error codes:

Constant Code When
CODE_SDK_NOT_AVAILABLE 1 Zebra AI DataCapture not available on this device.
CODE_CAMERA_PERMISSION_DENIED 2 Camera permission was denied by the user.
CODE_DECODER_INIT_FAILED 3 AI decoder failed to initialize.
CODE_ALREADY_SCANNING 4 Scan() called while a scan is already in progress.
CODE_NOT_INITIALIZED 5 Scan() called before Initialize().
CODE_INACTIVITY_TIMEOUT 6 No detections within InactivityTimeoutMs.
CODE_UNKNOWN 99 Unclassified error.

Enumerations

RecognitionMode
Value Description
Barcode Barcode decoding only.
Ocr Text recognition only.
Both Barcode + OCR simultaneously.
SelectionMode
Value Description
Automatic First decoded result is sent immediately, overlay closes.
Accumulate Results accumulate (✓ button appears). User presses ✓ to confirm.
Manual Green boxes are shown; user taps the one they want.
CameraResolution
Value Resolution Notes
HD_720P 1280×720 (1 MP) Fastest, lower quality.
FHD_1080P 1920×1080 (2 MP) Default. Recommended balance.
QHD_1512P 2688×1512 (4 MP) Better for small/dense barcodes.
UHD_2160P 3840×2160 (8 MP) Highest quality, highest CPU/memory load.
ProcessorType
Value Description
Auto DSP → CPU → GPU (tries fastest available). Default.
Dsp Force DSP. Fastest on Zebra hardware.
Gpu Force GPU.
Cpu Force CPU. Slowest, most compatible.
Symbology (common subset)

AZTEC, CODE_39, CODE_128, DATA_MATRIX, EAN_8, EAN_13, GS1_DATABAR, GS1_DATABAR_EXPANDED, MAILMARK, MAXICODE, PDF417, QR_CODE, UPC_A, UPC_E (enabled by default), plus 30 additional symbologies including all postal codes.

To restrict to a subset:

config.EnabledSymbologies = new HashSet<Symbology> { Symbology.Qr_Code, Symbology.Code_128 };

License management

DEMO mode

Pass "DEMO" as the license JWT to evaluate the SDK without a real license:

ZebraAiScanner.Initialize(context, "DEMO");
  • No signature, device serial, or expiry verification
  • Results are degraded: ~40% of alphanumeric characters are replaced with *
  • Spaces and punctuation are preserved
  • LicenseInfo.Customer returns "DEMO"

Production JWT license

Contact Suntech to obtain a JWT license. You must provide the serial of each authorized device.

Getting the device serial:

# Method 1 — hardware serial (requires READ_PHONE_STATE)
adb shell getprop ro.serialno

# Method 2 — ANDROID_ID (always readable, resets on factory reset)
adb shell settings get secure android_id

The SDK tries the hardware serial first; if READ_PHONE_STATE is not granted it automatically falls back to ANDROID_ID.

JWT payload structure:

{
  "sub": "zebraai-maui",
  "customer": "Acme Corp",
  "allowedSerials": ["ABC123456", "XYZ789012"],
  "features": ["barcode", "ocr"],
  "exp": 1893456000
}

Checking license info at runtime:

var info = ZebraAiScanner.LicenseInfo;
if (info != null)
{
    Console.WriteLine($"Customer: {info.Customer}");
    Console.WriteLine($"Expires:  {info.Expiry}");
    Console.WriteLine($"Features: {string.Join(", ", info.Features)}");
    Console.WriteLine($"Devices:  {info.DeviceCount}");
}

Localization

The SDK ships a full-screen camera overlay with built-in UI strings (torch label, close button, settings panel, accumulate counter, etc.). These strings live inside the AAR as Android string resources and are merged into your APK at build time.

Supported languages

The AAR currently ships resources for the following locales:

Locale Folder in AAR
English (default) values/
Italian values-it/

The overlay will automatically display in the device's system language if a matching locale is present; otherwise it falls back to English.

Restricting locale resources (reduce APK size)

By default the .NET Android linker keeps all locale folders from the AAR. To include only the languages your app needs, add SupportedLocales to your .csproj:

<PropertyGroup>
  
  <SupportedLocales>en;it</SupportedLocales>
</PropertyGroup>

This maps to the Android resConfig build option and can meaningfully reduce APK size when the AAR bundles many locales.

Adding or overriding translations

Create a strings.xml under the appropriate platform resource folder of your app project and define the keys you want to override. .NET MAUI resource merging gives your app's resources higher priority than those from the AAR.

Example — override the overlay close button label in Italian (Platforms/Android/Resources/values-it/strings.xml):

<?xml version="1.0" encoding="utf-8"?>
<resources>
    <string name="kazam_btn_close">Chiudi</string>
    <string name="kazam_btn_send_all">Invia tutti</string>
</resources>

Tip: Run aapt2 dump resources <path-to-aar> (or inspect the AAR as a zip) to list all available string keys that can be overridden.


Troubleshooting

LicenseException on Initialize

Message Cause Fix
"Invalid JWT format" The string is not a valid JWT (3 dot-separated parts). Check the JWT string.
"Invalid license signature" JWT was not signed with the Suntech private key. Use the JWT provided by Suntech.
"License expired on..." The exp field is in the past. Contact Suntech to renew.
"License not valid for this product" sub is not zebraai-maui. Use the correct license for this SDK.
"Device '...' not authorized" The current device serial is not in allowedSerials. Provide the serial to Suntech to update the license.

Error CODE_SDK_NOT_AVAILABLE (1)

The Zebra AI DataCapture native libraries (libctolandroidsdkwrapper.so etc.) are not present on the device. Ensure the device is a Zebra with AI DataCapture support and the Zebra Android SDK is installed on it.

Error CODE_DECODER_INIT_FAILED (3)

The AI decoder failed to initialize. Common causes:

  • Insufficient device memory (UHD_2160P model input with OCR is memory-intensive)
  • AI DataCapture SDK version mismatch (this package ships SDK 3.2.8)
  • First run on a fresh device (give the device time to warm up its AI runtime)

Reduce OcrModelInput or BarcodeModelInput to 640 or 1280 if this occurs.

Scan does not open (no callback called)

Verify that:

  1. Initialize() was called and succeeded (no exception thrown).
  2. Platform.CurrentActivity is not null.
  3. The calling activity is in the foreground.

OCR returns too many / too few results

Tune OcrFilter.MinConfidencePercent (raise to reduce false positives) and OcrStabilizationFrames (raise for stability, lower for speed).


Support

For production license requests, device authorizations, or technical support:

Please include the device model, Android version, SDK version (1.0.12), and the full exception message or logcat output.


© 2025 Suntech Srl — All rights reserved. See LICENSE for terms.

Product Compatible and additional computed target framework versions.
.NET net10.0-android36.0 is compatible. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.

NuGet packages

This package is not used by any NuGet packages.

GitHub repositories

This package is not used by any popular GitHub repositories.

Version Downloads Last Updated
1.0.12 160 4/15/2026 1.0.12 is deprecated because it is no longer maintained.
1.0.6 118 4/14/2026
1.0.5 125 4/14/2026 1.0.5 is deprecated because it has critical bugs.
1.0.4 119 4/13/2026
1.0.3 116 4/13/2026

v1.0.12: Rebuilt underlying zebraai-sdk AAR with Kotlin 2.3.20, AGP 9.1,
     CameraX 1.6.0, compileSdk 36, serialization 1.11.0, coroutines 1.10.2.
     All transitive dependencies aligned to latest stable. No public API changes.
     v1.0.11: ZebraAiScanner.Initialize() now auto-pre-loads AI decoders
     in background when called with an Activity context (no extra API call
     needed). Use Platform.CurrentActivity from MAUI OnAppearing.
     v1.0.10: Added ZebraAiScanner.PreloadDecoders(activity) — pre-loads
     AI decoders in background after Initialize() so the first Scan()
     starts the camera immediately instead of showing the "Initializing AI
     engine" overlay for several seconds. Must be called from an Activity
     context so JNI gets the correct classloader.
     v1.0.9: Detect non-AI-capable Zebra devices upfront via ro.soc.model
     (e.g. TC22 with QCM5430): ZebraAiScanner.Scan() returns
     ZebraAiError.CODE_SDK_NOT_AVAILABLE immediately instead of opening
     the camera and silently failing. Added BarcodeOverlayLabelSizeSp
     and OcrOverlayLabelSizeSp on ZebraAiConfig (10-40 sp, default 18).
     Overlay boxes now use distinct colors: green for barcode, blue for OCR.
     v1.0.8: Added ZebraAiScanner.ShowDeviceId(context) public API — shows AlertDialog with
     model + device ID + Copy button, and logs values to logcat (tag: ZebraAi.SDK).
     v1.0.7: Added ZebraAiScanner.GetDeviceId(context) public API for license activation;
     device info section (model + device ID + copy button) added to settings panel;
     LicenseValidator uses 5-level fallback chain for device identifier (Android 14 compatible).