PDA Scanner Plus
Configurable Android PDA barcode scanner broadcasts for Flutter. Select a vendor profile for known defaults or provide your own broadcast action and barcode data key.
Android only. This package receives Android intent broadcasts emitted by the scanner or wedge application installed on the PDA.
Installation
dependencies:
pda_scanner_plus: ^1.0.0
Device setup
In the PDA's scanner, wedge, or DataWedge application, select Intent output or Broadcast output. Configure its intent action and barcode-data extra key to the values for the selected profile below. The device setup is required; this package cannot configure proprietary scanner applications itself.
Note: PDA scanner settings are configurable. Built-in profiles provide vendor defaults, but they will not work if the device's configured broadcast action or data key has been changed. Use profile overrides or
PdaScanner.customto match the current device settings.
Configure the scanner
Create one PdaScanner for the PDA configuration used by your app, then call
initialize() once during app startup. Most applications use one scanner
instance.
For a supported device, use its prebuilt profile:
final scanner = PdaScanner.profile(PdaScannerProfiles.urovo);
await scanner.initialize();
For a device with custom Intent Output settings, use a custom configuration:
final scanner = PdaScanner.custom(
broadcastAction: 'com.vendor.scanner.RESULT',
dataKey: 'barcode',
);
await scanner.initialize();
Use either a profile or a custom configuration for each scanner instance. A profile already supplies the broadcast action and data key; provide overrides only when that specific device uses different values.
Consume scan data
scanner.scans is a Stream<ScanResult>. Each scan's decoded barcode is the
non-null String in ScanResult.data.
final StreamSubscription<ScanResult> subscription = scanner.scans.listen((scan) {
final String barcode = scan.data;
print(barcode);
});
Subscribe to scanner.scans after initialization. Each ScanResult contains:
data— the decoded barcode as a non-nullString.profileId— the selected profile ID, when a profile was used.additionalData— an immutable map of optional extras requested throughadditionalExtraKeys.
// Fields on your State class.
final scanner = PdaScanner.profile(PdaScannerProfiles.urovo);
String barcode = '';
late final StreamSubscription<ScanResult> subscription;
@override
void initState() {
super.initState();
subscription = scanner.scans.listen((scan) {
setState(() => barcode = scan.data);
debugPrint('Symbology: ${scan.additionalData['symbology']}');
});
}
@override
void dispose() {
subscription.cancel();
super.dispose();
}
Lifecycle
Keep the configured PdaScanner instance for the lifetime of barcode scanning.
Subscribe to scanner.scans where scan data is needed and cancel each
subscription when its owner is disposed.
Call await scanner.dispose() when that scanner is no longer needed. It
unregisters the Android receiver only when that instance is still active.
The plugin supports one active scanner configuration per Flutter engine, which
matches the normal one-PDA, one-scanner-app setup.
Every profile value can be overridden for device-specific firmware:
final scanner = PdaScanner.profile(
PdaScannerProfiles.newland,
dataKey: 'SCAN_BARCODE2',
);
await scanner.initialize();
For Zebra or any unknown device, provide both settings configured in the device scanner application:
final scanner = PdaScanner.custom(
broadcastAction: 'com.zebra.scanner.ACTION',
dataKey: 'com.symbol.datawedge.data_string',
);
await scanner.initialize();
Profiles
| Profile | Broadcast action | Data key |
|---|---|---|
| AIDA | com.android.scanner.broadcast |
scandata |
| SEUIC | com.android.server.scannerservice.broadcast |
scannerdata |
| UROVO | android.intent.ACTION_DECODE_DATA |
barcode_string |
| NEWLAND | nlscan.action.SCANNER_RESULT |
SCAN_BARCODE1 |
| Datalogic | com.datalogic.decodewedge.decode_action |
com.datalogic.decode.intentwedge.barcode_string |
| Honeywell | com.honeywell.sample.action.BARCODE |
Override required |
| iData | android.intent.action.SCANRESULT |
Override required |
| Zebra, PL, KAICOM, HIKVISION | Override required | Override required |
Honeywell and iData include their documented action but require a model-specific
dataKey. Zebra, PL, KAICOM, and HIKVISION require both values until their
device-specific settings are confirmed. All values are always overrideable.
Errors and security
initialize throws PdaScannerConfigurationException for incomplete or blank
configuration, and may throw PlatformException if Android rejects setup.
Malformed native events are surfaced as PdaScannerEventException on scans.
try {
final scanner = PdaScanner.profile(PdaScannerProfiles.honeywell);
await scanner.initialize();
} on PdaScannerConfigurationException catch (error) {
// Supply the Honeywell model's dataKey before retrying.
debugPrint(error.message);
} on PlatformException catch (error) {
debugPrint('Native scanner setup failed: ${error.message}');
}
The Android receiver must be exported to receive broadcasts from vendor scanner apps. Any app can therefore send the configured action. Treat scans as untrusted input: validate their format and never use a barcode alone as authentication or authorization proof.
Additional extras
Pass additionalExtraKeys to expose vendor extras in ScanResult.additionalData:
final scanner = PdaScanner.profile(
PdaScannerProfiles.urovo,
additionalExtraKeys: {'symbology': 'barcode_type'},
);
await scanner.initialize();
Contributing profiles
Profiles are maintained in lib/src/pda_scanner_profiles.dart. Contributions
must include public vendor documentation or reproducible device evidence for
each action/data-key pair, an accompanying test, and a README table update. If
either required value is unknown, add a partial profile with a clear note; it
must require callers to supply the missing override rather than guessing.
Libraries
- pda_scanner_plus
- Configurable PDA barcode scanning for Android.