Cash drawer reliability & service binding fixes
- Breaking:
openDrawer()now completes only once the printer firmware confirms the kick. It previously resolved as soon as the AIDL call was dispatched, so a drawer that never opened still reported success. It now throws aPlatformExceptionwith codeOPERATION_FAILED,PRINTER_EXCEPTION,UNAVAILABLEorTIMEOUT. - Breaking:
drawerStatus()anddrawerTimesOpen()no longer returnfalse/0when the printer service is unreachable — they throw aPlatformExceptionwith codeUNAVAILABLE. A dead binding used to be indistinguishable from a drawer that is simply not attached. - Fixed: Added the
<queries>declaration forwoyou.aidlservice.jiuiv5to the plugin manifest. On Android 11+ withtargetSdk >= 30, package visibility filtering made the Sunmi service invisible, sobindService()returnedfalseand the printer was reported as "not found" even when installed. Host apps no longer need to declare this themselves. - Fixed:
BIND_SERVICEcould never resolve. The pendingResultwas only completed fromonServiceConnected, so a refused or failed bind left the Dart future awaiting forever — which froze app startup for any host that awaited it beforerunApp(). Every exit path now settles the result, including afalsereturn frombindService(),onNullBindingandonBindingDied. - Fixed: The connection is now re-established after
onBindingDied, and commands that find the service missing schedule a reconnect. Previously a service restart left the plugin permanently broken until the host app was restarted. - Fixed:
unbindService()now releases a connection that was requested but never completed, and the plugin cleans up when the Flutter engine detaches. - In-flight AIDL callbacks are held with a strong reference so they cannot be garbage collected before the printer replies, and are bounded by a 5s timeout.
Major Architecture Refactor & Modernization
-
Native Android Overhaul:
- Migrated the Android build system from legacy Groovy to Gradle Kotlin DSL (
build.gradle.kts). - Bumped
compileSdkto 36 and updated Java compatibility to Java 17. - Completely refactored
SunmiTaskPrinterMethodto use non-blocking asynchronous calls. Hardware operations now run on a dedicated background executor, preventing Flutter UI thread freezes and ANR (Application Not Responding) crashes. - Resolved transaction buffer deadlocks by cleanly decoupling
MethodChannel.Resultresolution from physical hardware callbacks. - New Feature: Implemented an
EventChannel(hardwareErrorStream) to broadcast real-time hardware mechanical failures (e.g., out of paper, overheating, cutter jams) directly to Dart.
- Migrated the Android build system from legacy Groovy to Gradle Kotlin DSL (
-
Dart & Plugin Enhancements:
- Optimized
printRowdata parsing: Removed heavy JSON string serialization overhead in favor of passing nativeList<Map<String, dynamic>>. - Improved service binding and unbinding logic to properly queue, wait for, and resolve pending connection results.
- Printer status codes are now accurately mapped to human-readable string values for easier debugging.
- Hardened the codebase with strict typings to ensure maximum compatibility and zero warnings on
pub.devstatic analysis.
- Optimized
-
Example App & Tooling:
- Completely overhauled the Example App UI into clean, categorized testing cards for easier debugging on physical Sunmi POS terminals.
- Introduced fully automated GitHub Actions workflows for CI/CD, including code analysis, test coverage tracking, and secure OIDC automated publishing to pub.dev.
- Refactoring for matching Dart formatter.
- Refactoring
- First release, with the implemented task manager