urovo_pos 0.2.0
urovo_pos: ^0.2.0 copied to clipboard
Flutter plugin for Urovo POS (Android) with printer and scanner APIs, designed for modular feature expansion.
Urovo POS #
Standalone Flutter plugin for Urovo POS devices, designed for incremental feature delivery.
v0.2.0 implements printing + scanner and keeps a modular structure for future additions (beeper, pinpad) in the same package.
Tested on Urovo SDK version v1.0.13.
v0.2.0 scope #
- Runtime SDK availability check (
isUrovoSdkAvailable) - Printer lifecycle
printerInitprinterCloseprinterGetStatusprinterGetStatusDetailprinterSetGrayprinterStartPrint
- Print job pipeline
printerRunJob(UrovoPrintJob)
- Print primitives exposed via
UrovoPrintJobtextblackLinetextLeftRighttextLeftCenterRightbarcodeqrimageBytesfeedLinepaperFeed
- Built-in demo helper:
printSample()printSample()only builds/runs the sample job; it does not auto-callprinterInit/printerClose.
- Scanner APIs
scannerStart(...)scannerStop()scannerEvents(typed event stream)scannerDecodedStream(decoded payload stream)
Upcoming features (roadmap) #
v0.3.0: beeper APIs + shared device status utilitiesv0.4.0: pinpad wrappers (non-sensitive operations only)v0.5.0: capability registry (isPrinterAvailable,isScannerAvailable,isPinpadAvailable)v1.0.0: stabilized printing + scanning contract
Legal and licensing #
This package does not include Urovo proprietary SDK binaries. You must obtain Urovo SDK files under your own license agreement and add them to your Android app module. You are responsible for complying with Urovo licensing and distribution terms.
Android setup (add Urovo SDK AAR) #
-
Copy Urovo AAR into your app module:
android/app/libs/urovoSDK-v1.0.13.aar -
In
android/app/build.gradle:
dependencies {
implementation fileTree(dir: "libs", include: ["*.jar", "*.aar"])
// optional explicit:
// implementation(name: "urovoSDK-v1.0.13", ext: "aar")
}
- In
android/app/build.gradle.kts:
dependencies {
implementation(fileTree(mapOf("dir" to "libs", "include" to listOf("*.jar", "*.aar"))))
// optional explicit:
// implementation(files("libs/urovoSDK-v1.0.13.aar"))
}
- Optional (if your Gradle setup needs it):
repositories {
flatDir {
dirs "libs"
}
}
Run example on real POS (feature test) #
-
Put the vendor AAR in the example app:
example/android/app/libs/urovoSDK-v1.0.13.aar -
Connect your Urovo POS and confirm Flutter sees it:
flutter devices
- Run the example app on the POS:
cd example
flutter pub get
flutter run
-
In the example UI, use this test flow:
Check SDKInit PrinterGet StatusPrint Sample TextPrint Table DemoPrint Demo ReceiptClose PrinterStart Scan(scan a barcode/QR and observe logs)Stop Scan
-
Confirm logs show successful operations and printed output matches commands.
Quick usage #
import 'package:urovo_pos/urovo_pos.dart';
Future<void> printReceipt() async {
final available = await UrovoPos.isUrovoSdkAvailable();
if (!available) {
throw Exception('Urovo SDK not found.');
}
final job = UrovoPrintJob()
..setGray(8)
..text(
'UROVO POS',
style: const UrovoTextStyle(
align: UrovoAlign.center,
bold: true,
font: UrovoFont.large,
),
)
..blackLine()
..textLeftCenterRight('Item A', 'x1', '100,000')
..barcode('123456789012')
..qr('https://urovo.example/receipt/1')
..feedLine(2);
await UrovoPos.printerInit();
try {
await UrovoPos.printerRunJob(job);
} finally {
await UrovoPos.printerClose();
}
}
Using a custom Persian font #
UrovoTextStyle supports fontAsset for custom printing fonts.
final job = UrovoPrintJob()
..text(
'سلام',
style: const UrovoTextStyle(
align: UrovoAlign.right,
font: UrovoFont.normal,
fontAsset: 'assets/fonts/Vazirmatn-Regular.ttf',
),
);
Important notes:
- Flutter
pubspec.yamlfont registration is only for Flutter UI rendering. - Printing runs in native Android (Urovo SDK), so the printer can only use fonts the native SDK/device can resolve.
- The plugin resolves
fontAssetinto a native cached file and passes that path to Urovo SDK automatically.
Step-by-step tutorial #
- Add the font file to your app (example:
assets/fonts/RaviFaNum-Regular.ttf). - Register the font file in
pubspec.yamlunderflutter.assets. - Build your print job and set
UrovoTextStyle(fontAsset: 'assets/fonts/...'). - Run printer lifecycle as usual:
await UrovoPos.printerInit();await UrovoPos.printerRunJob(job);await UrovoPos.printerClose();
Scanner usage (v0.2.0) #
import 'dart:async';
import 'package:urovo_pos/urovo_pos.dart';
late final StreamSubscription<UrovoScannerEvent> sub;
Future<void> startScanFlow() async {
sub = UrovoPos.scannerEvents.listen((event) {
switch (event.type) {
case UrovoScannerEventType.decoded:
print('Decoded: ${event.result?.data}');
break;
case UrovoScannerEventType.timeout:
print('Scan timeout');
break;
case UrovoScannerEventType.error:
print('Scanner error: ${event.errorCode} ${event.message}');
break;
case UrovoScannerEventType.canceled:
print('Scan canceled');
break;
case UrovoScannerEventType.unknown:
print('Unknown scanner event');
break;
}
});
await UrovoPos.scannerStart(timeout: const Duration(seconds: 10));
}
Future<void> stopScanFlow() async {
await UrovoPos.scannerStop();
await sub.cancel();
}
Scanner callbacks are delivered through scannerEvents, and decoded payloads only are available via scannerDecodedStream.
Lifecycle contract (manual) #
This plugin uses manual lifecycle control. It does not auto-open or auto-close printer sessions.
Required sequence for printer transactions:
printerInit()- One or more operations:
printerGetStatusDetail()printerSetGray(...)printerRunJob(...)printerStartPrint()
printerClose()
printSample() also requires an opened session:
await UrovoPos.printerInit();
try {
await UrovoPos.printSample();
} finally {
await UrovoPos.printerClose();
}
Status mapping #
Public Dart API does not expose raw Urovo status integers.
Mapped printer status enum:
okpaperEndedhardErroroverheatlowVoltagemotorErrorbusyunknown
Troubleshooting #
sdk_not_found: AAR is missing from app moduleandroid/app/libs.not_initialized: callprinterInitbeforeprinterGetStatusDetail,printerSetGray,printerStartPrint,printerRunJob, orprintSample.device_unavailable: printer init/status failed (paper, voltage, hardware, busy).print_failed:startPrintfailed. Check status detail message and recommendation.invalid_argument: malformed job payload or invalid gray/input values.- Scanner errors/timeouts/cancel events are delivered via
scannerEventsinstead of throwing exceptions.