fix: declare receiver exported-ness for Android 14, isolate USB init - #10
Open
yash-vrundaz wants to merge 2 commits into
Open
fix: declare receiver exported-ness for Android 14, isolate USB init#10yash-vrundaz wants to merge 2 commits into
yash-vrundaz wants to merge 2 commits into
Conversation
registerReceiver() was called without RECEIVER_EXPORTED / RECEIVER_NOT_EXPORTED in USBPrinterService.init and USBPrinterAdapter.init. Both filters add the plugin's own ACTION_USB_PERMISSION alongside ACTION_USB_DEVICE_DETACHED, so they are not exclusively protected system broadcasts — from Android 14 (targetSdk 34) that throws SecurityException. NOT_EXPORTED is correct: the permission broadcast returns via the plugin's own PendingIntent, and protected system broadcasts are still delivered to a non-exported receiver. onAttachedToActivity also called adapter.init(context) immediately before assigning the bluetoothService lateinit. Every Bluetooth entry point reads that field, so anything throwing during USB setup left it unassigned and took Bluetooth printing down too — the next print failed with UninitializedPropertyAccessException instead of a USB error. Bluetooth is now initialised first and USB init is isolated.
Context.RECEIVER_NOT_EXPORTED and VERSION_CODES.TIRAMISU do not exist in compileSdk 31, so the receiver fix would not compile. targetSdkVersion is left at 31 — compileSdk only governs which APIs are visible, and the runtime guard keeps older devices on the two-argument overload.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
On Android 14+ (
targetSdk34 or higher) the plugin throwsSecurityExceptionduring initialisation, and the failure takes Bluetooth printing down with it.The receiver registration
USBPrinterService.init()andUSBPrinterAdapter.init()both do:ACTION_USB_PERMISSIONis the plugin's own action, so the filter is not exclusively for protected system broadcasts. Since Android 14, registering such a receiver without passingRECEIVER_EXPORTEDorRECEIVER_NOT_EXPORTEDthrows:RECEIVER_NOT_EXPORTEDis the correct choice: the permission broadcast comes back via the plugin's ownPendingIntent, and protected system broadcasts such asACTION_USB_DEVICE_DETACHEDare still delivered to a non-exported receiver. The flag is guarded on API 33, where it was introduced.Why Bluetooth breaks too
onAttachedToActivityhad:Every Bluetooth entry point (
scanBluDevice,onStartConnection,sendDataByte,bluetoothDisconnect) reads thebluetoothServicelateinit. When USB init throws, that field is never assigned and the next Bluetooth call fails withUninitializedPropertyAccessException— so a USB-only problem presents as total printer failure, with a misleading exception.This PR initialises Bluetooth first and wraps USB init, so a device without USB host support (or an OS that rejects the receiver) no longer disables the rest of the plugin.
compileSdk
Context.RECEIVER_NOT_EXPORTEDandVERSION_CODES.TIRAMISUdo not exist undercompileSdkVersion 31, so the module moves to 34.targetSdkVersionis left at 31 —compileSdkonly controls which APIs are visible, and the runtime guard keeps older devices on the two-argument overload.Verification
Built and run on a OnePlus CPH2767 (Android 16, app
targetSdk36):USBPrinterService.initnow runs to completion —ESC/POS Printer initializedis loggedSecurityException, noError registering plugin flutter_pos_printer_platform_image_3Happy to adjust the flag choice or the guard level if you'd prefer
ContextCompat.registerReceiverinstead — that would add anandroidx.coredependency, which is why I used the platform API directly.