zebra_wedge_scanner 1.0.0
zebra_wedge_scanner: ^1.0.0 copied to clipboard
Flutter plugin for Zebra DataWedge (Android) with typed and generic command APIs.
Zebra_Datawedge_With_Flutter #
Flutter plugin that works with Zebra DataWedge on compatible Zebra Android devices.
This README is written for beginners and junior Flutter developers. It explains what each major part of the package does and how to use it in a real app.
Table of Contents #
- What This Package Does
- Core Concepts You Must Know
- Platform and Device Requirements
- Installation
- First Working Integration (Step-by-Step)
- Understanding Events and Payloads
- Profile Setup in Depth
- API Guide by Use Case
- Reliable Command Handling Pattern
- Advanced Examples
- Troubleshooting Guide
- License
- Legal and Trademark Notice
- Pub.dev Publishing Checklist
- References
What This Package Does #
Zebra devices use a system service called DataWedge for scanning and data capture. Instead of writing Android broadcast intent code manually, this package gives you:
- A clean Flutter API through
ZebraDataWedge. - Strongly typed constants and request models.
- Generic command methods for future DataWedge APIs.
- A unified event stream for:
- Scan data
- Command results
- Notifications
- Debug messages
In simple terms:
- You send commands from Flutter to DataWedge.
- DataWedge executes them.
- Your app receives scan events and status events.
Core Concepts You Must Know #
Before coding, learn these 4 terms:
-
Profile A DataWedge profile is a configuration set (scanner settings, output mode, app binding).
-
App association The profile must be associated with your app package, or your app will not receive scans.
-
Intent output DataWedge sends scan data as Android intents. This plugin listens and forwards them to Flutter.
-
Command result Most commands can return success/failure info. You should listen to command result events for reliability.
Platform and Device Requirements #
- Android only
- Zebra devices with DataWedge installed
- Flutter SDK >= 3.3.0
- Dart SDK compatible with package constraints
Important:
- Feature availability depends on DataWedge version and hardware model.
- Some APIs (workflow, RFID, scale, scanner switching) are device-specific.
Installation #
Install from Pub.dev (recommended) #
Add this to your app pubspec.yaml:
dependencies:
zebra_datawedge: ^0.1.4
Then run:
flutter pub get
Local path install (for plugin development) #
dependencies:
zebra_datawedge:
path: ../zebra_datawedge
First Working Integration (Step-by-Step) #
This is the simplest production-style setup.
Step 1: Import and create one shared service #
import 'dart:async';
import 'package:zebra_datawedge/zebra_datawedge.dart';
class ZebraScannerService {
ZebraScannerService({required this.androidPackageName});
final String androidPackageName;
final ZebraDataWedge _dataWedge = ZebraDataWedge();
StreamSubscription<DataWedgeEvent>? _subscription;
String? lastBarcode;
String? lastLabelType;
String? lastCommandResult;
Future<void> initialize() async {
final bool available = await _dataWedge.isAvailable();
if (!available) {
throw StateError(
'DataWedge is not available on this device. Use a Zebra device with DataWedge installed.',
);
}
await _dataWedge.configureClassicBarcodeProfile(
profileName: 'MY_APP_PROFILE',
packageName: androidPackageName,
);
await _dataWedge.switchToProfile('MY_APP_PROFILE');
await _dataWedge.registerForDefaultNotifications();
_subscription = _dataWedge.events.listen(_onEvent);
}
void _onEvent(DataWedgeEvent event) {
if (event.isScan) {
lastBarcode = event.scanData;
lastLabelType = event.labelType;
return;
}
if (event.isCommandResult) {
final String command = event.command ?? 'UNKNOWN_COMMAND';
final String result = event.result ?? 'UNKNOWN_RESULT';
lastCommandResult = '$command -> $result';
return;
}
if (event.isNotification) {
final String notificationType = event.notificationType ?? 'UNKNOWN_NOTIFICATION';
final String status = event.scannerStatus ?? 'UNKNOWN_STATUS';
lastCommandResult = 'Notification: $notificationType -> $status';
}
}
Future<void> dispose() async {
await _subscription?.cancel();
}
}
Why this code is structured this way:
androidPackageNamemust match your Android app package (applicationId). It is used to bind the DataWedge profile to your app.ZebraDataWedge _dataWedgeis one shared API instance for all scanner operations.initialize()starts withisAvailable()so you fail fast on unsupported devices.configureClassicBarcodeProfile(...)creates a practical default profile for most barcode apps.switchToProfile(...)ensures the active profile is the one your app expects.registerForDefaultNotifications()helps you observe scanner/profile state._dataWedge.events.listen(_onEvent)is the main event bridge from Android to Flutter.dispose()cancels the stream subscription to prevent memory leaks.
Step 2: Use it from your UI #
late final ZebraScannerService scannerService;
@override
void initState() {
super.initState();
scannerService = ZebraScannerService(
androidPackageName: 'com.example.my_app',
);
scannerService.initialize();
}
@override
void dispose() {
scannerService.dispose();
super.dispose();
}
How to set the package name correctly:
- Open
android/app/build.gradlein your app. - Find
defaultConfigand readapplicationId. - Use that exact value in
androidPackageNameand profile app association.
Step 3: Test the flow #
- Open the app on a Zebra device.
- Trigger scanner (hardware button or soft scan API).
- Confirm scan events arrive.
- Confirm command results show success.
Understanding Events and Payloads #
This package exposes 2 streams:
scanStream: rawMap<String, dynamic>events: typedDataWedgeEvent
Most apps should use events.
Event types #
-
scanTypical keys:data: scanned textlabelType: barcode typeextras: full intent extras map
-
commandResultTypical keys:commandresult(usuallySUCCESSorFAILURE)commandIdresultInforesultInfoText
-
notificationTypical keys:notificationTypestatusprofileNameraw
-
debugTypical keys:message
Recommended event handling strategy #
- Handle
scanin your business logic. - Log
commandResultfor diagnostics and reliability. - Use
notificationto react to scanner/profile state changes.
Profile Setup in Depth #
This package gives you 2 profile approaches.
A) Fast setup with configureClassicBarcodeProfile #
Use this when you want a reliable default profile quickly. It configures:
- BARCODE plugin enabled
- INTENT output enabled (broadcast)
- KEYSTROKE output disabled
- App association set to your package
await ZebraDataWedge().configureClassicBarcodeProfile(
profileName: 'MY_APP_PROFILE',
packageName: 'com.example.my_app',
);
Parameter explanation:
profileName: the DataWedge profile to create or update.packageName: your Android app id that receives scan intents.- Optional arguments (not shown) let you customize intent action, delivery mode, activities, and notification behavior.
B) Advanced setup with DataWedgeProfileBuilder #
Use this for large apps with multiple scanner modes.
final DataWedgeProfileConfiguration profile = DataWedgeProfileBuilder(
profileName: 'WAREHOUSE_PROFILE',
configMode: DataWedgeConfigMode.createIfNotExist,
)
.setProfileEnabled(true)
.addPlugin(
DataWedgePluginConfiguration(
pluginName: DataWedgePluginName.barcode,
resetConfig: true,
paramList: <String, dynamic>{
'scanner_selection': 'auto',
'scanner_selection_by_identifier': DataWedgeScannerIdentifier.auto,
'scanner_input_enabled': 'true',
},
),
)
.addPlugin(
DataWedgePluginConfiguration(
pluginName: DataWedgePluginName.intent,
resetConfig: true,
paramList: <String, dynamic>{
'intent_output_enabled': 'true',
'intent_action': 'com.example.my_app.SCAN',
'intent_category': DataWedgeApi.defaultIntentCategory,
'intent_delivery': DataWedgeIntentDelivery.broadcast,
},
),
)
.addAppAssociation(
const DataWedgeAppAssociation(
packageName: 'com.example.my_app',
activityList: <String>[DataWedgeApi.wildcard],
),
)
.build();
await ZebraDataWedge().setConfig(profile);
Builder chain explanation:
DataWedgeProfileBuilder(...)creates a mutable builder object..setProfileEnabled(true)ensures profile is active.- First
.addPlugin(...)enables BARCODE input settings. - Second
.addPlugin(...)enables INTENT output settings. .addAppAssociation(...)binds profile to app package and activities..build()converts builder state into immutableDataWedgeProfileConfiguration.setConfig(profile)sends final config bundle to DataWedge.
API Guide by Use Case #
1) Availability and setup #
isAvailableconfigureProfileconfigureClassicBarcodeProfileswitchToProfile
2) Profile management #
createProfilecloneProfilerenameProfiledeleteProfilesdeleteAllDeletableProfilessetConfigapplyProfileConfigurationgetConfigsetDefaultProfileresetDefaultProfile
3) Notifications #
registerForNotificationunregisterForNotificationregisterForDefaultNotifications
Notification constants:
DataWedgeNotificationType.scannerStatusDataWedgeNotificationType.profileSwitchDataWedgeNotificationType.configurationUpdateDataWedgeNotificationType.workflowStatus
4) Queries and diagnostics #
getActiveProfilegetProfilesListgetVersionInfogetDataWedgeStatusgetScannerStatusenumerateScannersenumerateTriggersenumerateWorkflowsgetDisabledAppListgetIgnoreDisabledProfiles
5) Runtime scanner control #
startSoftScanstopSoftScantoggleSoftScansoftScanTriggerenableScannerdisableScannersuspendScannerresumeScannersoftRfidTriggersoftVoiceTriggerswitchScannerByIndexswitchScannerByIdentifierswitchScannerParamsswitchDataCapturesetDataWedgeEnabled
6) Import/export and app control #
importConfigexportConfigsetDisabledAppListsetIgnoreDisabledProfiles
7) Scale and Bluetooth notification APIs #
getWeightsetScaleToZeronotifyBluetoothScannercustomNotifyBluetoothScanner
8) Generic future-proof APIs #
sendCommandsendCommandBundlesendIntent
Use these when Zebra introduces a new command that is not yet wrapped by a typed helper.
Reliable Command Handling Pattern #
When sending commands, always think in request/response style:
- Send command with a unique
commandTag. - Keep
requestResult: true. - Listen for
commandResultevents. - Match by
commandIdor command name. - Handle failures with retry or fallback.
Example:
await ZebraDataWedge().sendCommand(
command: DataWedgeApi.getVersionInfo,
value: '',
commandTag: 'GET_VERSION_FOR_STARTUP_CHECK',
requestResult: true,
);
What each argument means:
command: which DataWedge API command you are sending.value: command payload; query commands usually use an empty string.commandTag: your custom tracking id prefix for logs and correlation.requestResult: when true, DataWedge returns acommandResultevent.
Advanced Examples #
Soft scan for a specific scanner #
await ZebraDataWedge().softScanTrigger(
action: DataWedgeSoftScanAction.toggle,
scannerSelectionByIdentifier: DataWedgeScannerIdentifier.bluetoothRs6000,
);
Switch scanner parameters at runtime #
await ZebraDataWedge().switchScannerParams(
scannerSelectionByIdentifier: DataWedgeScannerIdentifier.internalImager,
parameters: <String, dynamic>{
'illumination_mode': 'off',
},
);
Switch data capture to workflow mode #
await ZebraDataWedge().switchDataCapture(
targetPlugin: DataWedgeSwitchDataCaptureTarget.workflow,
paramList: <String, dynamic>{
'workflow_name': DataWedgeWorkflowName.idScanning,
'workflow_input_source': DataWedgeWorkflowInputSource.camera,
},
);
Import and export DataWedge config #
await ZebraDataWedge().exportConfig(
const DataWedgeExportConfigRequest(
folderPath: '/storage/emulated/0/Download/',
exportType: DataWedgeExportType.profileConfig,
profileName: 'MY_APP_PROFILE',
),
);
await ZebraDataWedge().importConfig(
const DataWedgeImportConfigRequest(
folderPath: '/sdcard/configFolder',
fileList: <String>['dwprofile_MY_APP_PROFILE.db'],
),
);
Troubleshooting Guide #
Problem: No scan data arrives #
Checklist:
- Confirm device is Zebra and DataWedge is installed.
- Confirm
isAvailable()returns true. - Confirm profile is associated with your app package.
- Confirm INTENT output is enabled.
- Confirm your app is using the same package name used in profile config.
Problem: Commands seem ignored #
Checklist:
- Keep
requestResult: trueand inspectcommandResultevents. - Check DataWedge status using
getDataWedgeStatus. - Ensure profile exists before switching to it.
- Validate command parameters against Zebra docs.
Problem: Works on one device, fails on another #
Checklist:
- Compare DataWedge versions using
getVersionInfo. - Compare available scanners with
enumerateScanners. - Compare supported workflows using
enumerateWorkflows.
License #
This package is distributed under the MIT License. See LICENSE for full terms.
Legal and Trademark Notice #
- This is an independent open-source project and is not affiliated with or endorsed by Zebra Technologies.
- This package works with Zebra devices and DataWedge APIs; it is not an official Zebra plugin.
- Zebra, DataWedge, and related marks are trademarks of Zebra Technologies Corporation and/or its affiliates.
- This plugin is designed to use public DataWedge APIs exposed on compatible Zebra Android devices.
- You are responsible for following Zebra device software terms, API documentation terms, and any trademark usage rules in your product, docs, or store listing.
References #
- DataWedge Overview: https://techdocs.zebra.com/datawedge/latest/guide/about/
- DataWedge API Reference: https://techdocs.zebra.com/datawedge/latest/guide/api/
- DataWedge Profiles: https://techdocs.zebra.com/datawedge/latest/guide/profiles/
- Feature Matrix: https://techdocs.zebra.com/datawedge/latest/guide/matrix/