The Scanner SDK targets Android PDA devices. ScanManager provides barcode scanning control, output mode switching, and scanner parameter configuration. Scan results can be delivered via broadcast (Intent) or keyboard wedge output.
1.2、Version history
This document matches the 2026-08-28 Scanner development guide. It covers core ScanManager APIs, common parameter examples, broadcast-based scan image capture, and broadcast-based scanner settings on Android 11 and above.
1.3、Key Features
Switch between broadcast and keyboard output modes
Programmatic start/stop decode, trigger mode, and scanner engine control
Configure scanner parameters via PropertyID (int / String)
Receive barcode data through broadcast on successful decode
Receive scan head images via broadcast (Android 11+, OS builds from 2024 onward)
Configure scanner parameters via system broadcast com.android.broadcast.uscanner.settings (Android 11+)
1.4、Use Cases
Warehouse, retail, and logistics barcode capture on PDAs
Integrations that require custom broadcast Action / data keys
Applications that need decoded images and bounding coordinates
1.5、Requirements
Item
Requirement
Platform
Android PDA
Language
Java
Core class
android.device.ScanManager
Parameter constants
android.device.scanner.configuration.PropertyID
Auto image return
Android 11+, OS version from 2024 onward
Broadcast parameter settings
Android 11+
2、Integration
2.1、Obtain the SDK
The Scanner SDK is shipped as a JAR file: ScannerSDK-20250427.jar. It includes core classes such as android.device.ScanManager and android.device.scanner.configuration.PropertyID. Obtain the JAR from the SDK distribution package or refer to the included sample project: ScannerAPIsSamples.
2.2、Add the SDK Dependency
Add the JAR to your Android project as follows (same approach as the ScannerDemo sample project):
Copy ScannerSDK-20250427.jar into your project's app/libs/ directory.
Add a local JAR dependency in app/build.gradle under dependencies:
After sync, you can import android.device.ScanManager and call the APIs in code.
Note: The JAR provides compile-time API declarations. Scanning capability is provided by the device system at runtime; verify on a physical device.
2.3、Project Setup
Create a ScanManager instance in an Activity or Service.
For broadcast output, call switchOutputMode(0) or set Settings → Scan Settings → Output Mode → Intent output on the device.
Register a BroadcastReceiver for the scan result Action (default android.intent.ACTION_DECODE_DATA; use ScanManager.ACTION_DECODE or read configured values at runtime).
Call unregisterReceiver in onPause or when the screen is destroyed to avoid leaks.
Default broadcast Action is android.intent.ACTION_DECODE_DATA; default data key is barcode_string. You may also use ScanManager.ACTION_DECODE and ScanManager.BARCODE_STRING_TAG.
3、Quick Start
Minimal broadcast-mode barcode capture:
java
ScanManager mScanManager = new ScanManager();
mScanManager.switchOutputMode(0);
IntentFilter filter = new IntentFilter();
filter.addAction(ScanManager.ACTION_DECODE);
registerReceiver(mReceiver, filter);
Starts decoding programmatically; equivalent to pressing the physical scan key. Skip this call if you only use hardware keys.
public boolean startDecode()
Returns
boolean — true on success; false on failure.
Example
java
mScanManager.startDecode();
ScanManager
4.1.6、stopDecode
Stops an active decode session programmatically.
public boolean stopDecode()
Returns
boolean — true on success; false on failure.
Example
java
mScanManager.stopDecode();
ScanManager
4.1.7、setTriggerMode
Sets the trigger scan mode.
public void setTriggerMode(Triggering tgMode)
Parameters
Name
Type
Description
tgMode
Triggering
PULSE, CONTINUOUS, or HOST; see Triggering enum
Example
java
mScanManager.setTriggerMode(Triggering.PULSE);
ScanManager
4.1.8、getTriggerMode
Returns the current trigger scan mode.
public Triggering getTriggerMode()
Returns
Triggering — PULSE, CONTINUOUS, or HOST.
Example
java
mScanManager.getTriggerMode();
ScanManager
4.1.9、lockTriggler
Disables scan triggering (hardware key and programmatic scan methods).
public boolean lockTriggler()
Returns
boolean — true on success; false on failure.
Example
java
mScanManager.lockTriggler();
ScanManager
4.1.10、unlockTriggler
Re-enables scan triggering (hardware scan key).
public boolean unlockTriggler()
Returns
boolean — true on success; false on failure.
Example
java
mScanManager.unlockTriggler();
ScanManager
4.1.11、openScanner
Opens the scan engine. Devices are usually already enabled; this call is optional.
public boolean openScanner()
Returns
boolean — true on success; false on failure.
Example
java
mScanManager.openScanner();
ScanManager
4.1.12、closeScanner
Closes the scan engine. Scanning is unavailable while closed.
public boolean closeScanner()
Returns
boolean — true on success; false on failure.
Example
java
mScanManager.closeScanner();
ScanManager
4.1.13、setParameterString
Sets scanner parameters with String values.
public boolean setParameterString(int[] index, String[] value)
Parameters
Name
Type
Description
index
int[]
Parameter key array (PropertyID)
value
String[]
Value array with the same length as index
Returns
boolean — true on success; false on failure.
Example
java
mScanManager.setParameterString(
new int[]{PropertyID.WEDGE_INTENT_ACTION_NAME, PropertyID.WEDGE_INTENT_DATA_STRING_TAG},
new String[]{"com.pkuhit.intent.action.SCANRECVR", "yourKeyString"}
);
int[] — Result indices match the input index array.
Example
java
int[] keys = new int[]{
PropertyID.SEND_GOOD_READ_BEEP_ENABLE,
PropertyID.SEND_GOOD_READ_VIBRATE_ENABLE
};
int[] ret = mScanManager.getPropertyInts(keys);
ScanManager
4.1.17、resetScannerParameters
Resets scanner-related settings to factory defaults.
public boolean resetScannerParameters()
Returns
boolean — true on success; false on failure.
Example
java
mScanManager.resetScannerParameters();
Scan Head Image (Broadcast Mode)
4.2.1、Auto return
For Android 11+ devices with OS builds from 2024 onward. Send the configuration broadcast once at startup; subsequent scans return image data automatically.
Send configuration:
java
private static String BROADCAST_IMAGE_ACTION = "com.ubx.scanner_capture_image_result";
Intent intentImage = new Intent();
intentImage.setAction("com.ubx.barcode.broadcast_image");
intentImage.putExtra("imageAction", BROADCAST_IMAGE_ACTION);
// Broadcast image and barcode data immediately after a successful decode
intentImage.putExtra("enableSendImage", true);
// Send failed-decode images by default (not supported on all scan engines; contact technical support)
intentImage.putExtra("enableSendFailedImage", true);
// Image output form: 0 bitmap byte array; 1 saved file path
intentImage.putExtra("outputImageMode", 0);
// JPEG quality percentage: 1-100; system default is 50 (50%)
intentImage.putExtra("jpegQuality", 100);
// Return bounding coordinates
intentImage.putExtra("outputBounds", true);
// Saved image format: 0 png; 1 jpg; 2 bmp
intentImage.putExtra("imageFormat", 0);
// Image save directory path
intentImage.putExtra("saveImageDirPath", "/storage/emulated/0/imageSave/");
sendBroadcast(intentImage);
Register and receive:
java
IntentFilter filter = new IntentFilter();
filter.addAction(BROADCAST_IMAGE_ACTION);
registerReceiver(mGetBitmapReceiver, filter);
In broadcast mode, property IDs use the SEND prefix:
java
ScanManager mScanManager = new ScanManager();
mScanManager.setPropertyInts(new int[]{PropertyID.SEND_GOOD_READ_BEEP_ENABLE}, new int[]{0});
mScanManager.setPropertyInts(new int[]{PropertyID.SEND_GOOD_READ_VIBRATE_ENABLE}, new int[]{0});
new ScanManager().setParameterString(
new int[]{PropertyID.WEDGE_INTENT_ACTION_NAME, PropertyID.WEDGE_INTENT_DATA_STRING_TAG},
new String[]{"yourAction", "yourKeyString"}
);
Keyboard mode: beep and vibration
java
ScanManager mScanManager = new ScanManager();
mScanManager.setPropertyInts(new int[]{PropertyID.GOOD_READ_BEEP_ENABLE}, new int[]{0});
mScanManager.setPropertyInts(new int[]{PropertyID.GOOD_READ_VIBRATE_ENABLE}, new int[]{0});
Keyboard type
Output mode must be keyboard mode:
java
new ScanManager().setPropertyInts(new int[]{PropertyID.WEDGE_KEYBOARD_TYPE}, new int[]{1});
// 0 physical; 1 IME; 2 physical only; 3 IME only
Append key character
java
new ScanManager().setPropertyInts(new int[]{PropertyID.LABEL_APPEND_ENTER}, new int[]{1});
// 0 None; 1 CR; 2 IME action done; 3 TAB
Output mode
java
new ScanManager().switchOutputMode(0);
new ScanManager().switchOutputMode(1);
Application identifier
java
int[] keyInt = new int[]{PropertyID.LABEL_SEPARATOR_ENABLE};
int[] valueInt = new int[]{1};
new ScanManager().setPropertyInts(keyInt, valueInt);
Label prefix/suffix
java
new ScanManager().setPropertyInts(new int[]{PropertyID.SEND_LABEL_PREFIX_SUFFIX}, new int[]{1});
Barcode replacement
java
new ScanManager().setParameterString(
new int[]{PropertyID.LABEL_MATCHER_TARGETREGEX, PropertyID.LABEL_MATCHER_REPLACEMENT},
new String[]{"oldStr", "newStr"}
);
Multi-barcode
java
int[] multiConfigbuf = new int[]{
PropertyID.MULTI_DECODE_MODE,
PropertyID.FULL_READ_MODE,
PropertyID.BAR_CODES_TO_READ
};
int[] multiConfigval = new int[]{1, 1, 4};
new ScanManager().setPropertyInts(multiConfigbuf, multiConfigval);
String moreBarcodeStr = intent.getStringExtra("com.ubx.datawedge.data_string");
Continuous scan deduplication
java
new ScanManager().setPropertyInts(new int[]{PropertyID.DEC_Multiple_Decode_MODE}, new int[]{0});
Same-symbol interval and scan timeout
java
ScanManager mScanManager = new ScanManager();
mScanManager.setPropertyInts(new int[]{PropertyID.TIMEOUT_BETWEEN_SAME_SYMBOL}, new int[]{1});
mScanManager.setPropertyInts(new int[]{PropertyID.DEC_Multiple_Decode_INTERVAL}, new int[]{50});
mScanManager.setPropertyInts(new int[]{PropertyID.DEC_Multiple_Decode_TIMEOUT}, new int[]{5000});
Symbology enable/disable
java
ScanManager mScanManager = new ScanManager();
mScanManager.enableSymbology(Symbology.AZTEC, false);
mScanManager.enableAllSymbologies(true);
Aim mode and security level
java
mScanManager.setPropertyInts(new int[]{PropertyID.DEC_PICKLIST_AIM_MODE}, new int[]{1});
new ScanManager().setPropertyInts(
new int[]{PropertyID.LINEAR_CODE_TYPE_SECURITY_LEVEL}, new int[]{1}
);
Symbology and check digit
java
int[] codeChecksumKey = new int[]{
PropertyID.EAN13_ENABLE, PropertyID.UPCA_ENABLE, PropertyID.UPCE_ENABLE, PropertyID.UPCE1_ENABLE,
PropertyID.EAN13_SEND_CHECK, PropertyID.UPCA_SEND_CHECK, PropertyID.UPCE_SEND_CHECK, PropertyID.UPCE1_SEND_CHECK
};
int[] codeChecksumvalue = new int[]{1, 1, 1, 1, 0, 0, 0, 0};
new ScanManager().setPropertyInts(codeChecksumKey, codeChecksumvalue);
Low contrast and illumination
java
ScanManager mScanManager = new ScanManager();
mScanManager.setPropertyInts(
new int[]{PropertyID.LOW_CONTRAST_IMPROVED, PropertyID.LOW_CONTRAST_IMPROVED_ALGORITHM},
new int[]{2, 0}
);
new ScanManager().setPropertyInts(new int[]{PropertyID.DEC_2D_LIGHTS_MODE}, new int[]{1});
Viewfinder and encoding
java
mScanManager.setPropertyInts(
new int[]{PropertyID.DEC_2D_CENTERING_ENABLE, PropertyID.DEC_2D_CENTERING_MODE},
new int[]{1, 2}
);
mScanManager.setPropertyInts(new int[]{PropertyID.CODING_FORMAT}, new int[]{1});
OCR and exposure
java
mScanManager.setPropertyInts(
new int[]{PropertyID.DEC_OCR_MODE, PropertyID.DEC_OCR_TEMPLATE}, new int[]{3, 0}
);
mScanManager.setPropertyInts(
new int[]{PropertyID.IMAGE_EXPOSURE_MODE, PropertyID.DEC_ES_MAX_EXP, PropertyID.DEC_ES_MAX_GAIN, PropertyID.DEC_ES_TARGET_VALUE},
new int[]{1, 500, 4, 4000}
);
Broadcast output requires switchOutputMode(0) or Intent output in system settings before results can be received by broadcast.
See ScannerAPIsSamples or contact technical support for the full PropertyID list.
Auto image return and broadcast parameter settings require Android 11+. Auto image return also requires a 2024-or-later OS build.
Some features (multi-barcode, failed-decode images) depend on scan engine hardware; validate on target devices.
Legacy examples may reference setParameterInts while the API section documents setPropertyInts; use the method name exposed on your device SDK.
6.2、FAQ
Q: What are the default broadcast Action and data key?
A: Default Action is android.intent.ACTION_DECODE_DATA; default key is barcode_string. You may also use ScanManager.ACTION_DECODE and ScanManager.BARCODE_STRING_TAG, or read current values with getParameterString.
Q: Can I use broadcast mode without calling the API?
A: Yes. Set Settings → Scan Settings → Output Mode → Intent output on the PDA, then register a BroadcastReceiver for the configured Action and key.
Q: How do I unlock scanning after lock?
A: Call unlockTriggler(), or send broadcast with keyInt = -14 and valueInt = 1.
public boolean setParameterString(int[] index, String[] value)
参数
参数
类型
说明
index
int[]
参数 key 数组,对应 PropertyID
value
String[]
与 index 等长的参数值数组
返回值
boolean — true 设置成功;false 设置失败。
示例
java
mScanManager.setParameterString(
new int[]{PropertyID.WEDGE_INTENT_ACTION_NAME, PropertyID.WEDGE_INTENT_DATA_STRING_TAG},
new String[]{"com.pkuhit.intent.action.SCANRECVR", "你接收的KeyString"}
);
ScanManager mScanManager = new ScanManager();
mScanManager.setPropertyInts(new int[]{PropertyID.SEND_GOOD_READ_BEEP_ENABLE}, new int[]{0});
// 声音:0 关闭;1 短促;2 尖锐
mScanManager.setPropertyInts(new int[]{PropertyID.SEND_GOOD_READ_VIBRATE_ENABLE}, new int[]{0});
// 震动:0 关闭;1 开启
new ScanManager().setParameterString(
new int[]{PropertyID.WEDGE_INTENT_ACTION_NAME, PropertyID.WEDGE_INTENT_DATA_STRING_TAG},
new String[]{"你的Action", "你接收的KeyString"}
);
键盘模式:声音与震动
键盘模式下使用不带 SEND 前缀的属性:
java
ScanManager mScanManager = new ScanManager();
mScanManager.setPropertyInts(new int[]{PropertyID.GOOD_READ_BEEP_ENABLE}, new int[]{0});
mScanManager.setPropertyInts(new int[]{PropertyID.GOOD_READ_VIBRATE_ENABLE}, new int[]{0});
键盘类型
输出模式须为键盘模式:
java
new ScanManager().setPropertyInts(new int[]{PropertyID.WEDGE_KEYBOARD_TYPE}, new int[]{1});
// 0:物理键盘;1:输入法软件;2:仅用物理键盘;3:仅用输入法
设置操作键字符
java
new ScanManager().setPropertyInts(new int[]{PropertyID.LABEL_APPEND_ENTER}, new int[]{1});
// 0: None;1: Carriage return;2: IME action done;3: TAB
设置输出模式
java
new ScanManager().switchOutputMode(0); // 广播模式
new ScanManager().switchOutputMode(1); // 键盘模式
应用标识符
java
int[] keyInt = new int[]{PropertyID.LABEL_SEPARATOR_ENABLE};
int[] valueInt = new int[]{1}; // 0 关闭;1 开启
new ScanManager().setPropertyInts(keyInt, valueInt);
扫码附加前后缀
java
new ScanManager().setPropertyInts(new int[]{PropertyID.SEND_LABEL_PREFIX_SUFFIX}, new int[]{1});
条码替换
java
new ScanManager().setParameterString(
new int[]{PropertyID.LABEL_MATCHER_TARGETREGEX, PropertyID.LABEL_MATCHER_REPLACEMENT},
new String[]{"oldStr", "newStr"}
);
new ScanManager().setPropertyInts(
new int[]{PropertyID.DEC_Multiple_Decode_MODE}, new int[]{0}
);
// 0 可重复解码;1 连续不重复;2 缓存内不重复
相同条码间隔与扫描超时
java
ScanManager mScanManager = new ScanManager();
mScanManager.setPropertyInts(new int[]{PropertyID.TIMEOUT_BETWEEN_SAME_SYMBOL}, new int[]{1});
// value * 100 ms,范围 1–99
mScanManager.setPropertyInts(new int[]{PropertyID.DEC_Multiple_Decode_INTERVAL}, new int[]{50});
// 扫描间隔,默认 50ms(0–5000ms)
mScanManager.setPropertyInts(new int[]{PropertyID.DEC_Multiple_Decode_TIMEOUT}, new int[]{5000});
// 扫描超时,默认 5000ms(50–60000ms)
码制开关
java
ScanManager mScanManager = new ScanManager();
mScanManager.enableSymbology(Symbology.AZTEC, false);
mScanManager.enableAllSymbologies(true);
瞄准模式与码校验
java
mScanManager.setPropertyInts(new int[]{PropertyID.DEC_PICKLIST_AIM_MODE}, new int[]{1});
int[] codeleveindex = new int[]{PropertyID.LINEAR_CODE_TYPE_SECURITY_LEVEL};
int[] codelevevalue = new int[]{1}; // 级别 0–3
new ScanManager().setPropertyInts(codeleveindex, codelevevalue);
码制与校验位
java
int[] codeChecksumKey = new int[]{
PropertyID.EAN13_ENABLE, PropertyID.UPCA_ENABLE, PropertyID.UPCE_ENABLE, PropertyID.UPCE1_ENABLE,
PropertyID.EAN13_SEND_CHECK, PropertyID.UPCA_SEND_CHECK, PropertyID.UPCE_SEND_CHECK, PropertyID.UPCE1_SEND_CHECK
};
int[] codeChecksumvalue = new int[]{1, 1, 1, 1, 0, 0, 0, 0};
new ScanManager().setPropertyInts(codeChecksumKey, codeChecksumvalue);
低对比图像与照明灯
java
ScanManager mScanManager = new ScanManager();
mScanManager.setPropertyInts(
new int[]{PropertyID.LOW_CONTRAST_IMPROVED, PropertyID.LOW_CONTRAST_IMPROVED_ALGORITHM},
new int[]{2, 0}
);
new ScanManager().setPropertyInts(new int[]{PropertyID.DEC_2D_LIGHTS_MODE}, new int[]{1});
// 1 仅瞄准灯;2 仅照明灯;3 交替;4 同时
取景框与编码格式
java
mScanManager.setPropertyInts(
new int[]{PropertyID.DEC_2D_CENTERING_ENABLE, PropertyID.DEC_2D_CENTERING_MODE},
new int[]{1, 2}
);
int[] key = new int[]{PropertyID.CODING_FORMAT};
int[] value = new int[]{1}; // 0 UTF-8;1 GBK
mScanManager.setPropertyInts(key, value);
OCR 与曝光参数
java
int[] key = new int[]{PropertyID.DEC_OCR_MODE, PropertyID.DEC_OCR_TEMPLATE};
int[] value = new int[]{3, 0};
mScanManager.setPropertyInts(key, value);
int[] expKey = new int[]{
PropertyID.IMAGE_EXPOSURE_MODE, PropertyID.DEC_ES_MAX_EXP,
PropertyID.DEC_ES_MAX_GAIN, PropertyID.DEC_ES_TARGET_VALUE
};
int[] expValue = new int[]{1, 500, 4, 4000};
mScanManager.setPropertyInts(expKey, expValue);