altera2015 / usbserial

Flutter Android USB Serial plugin
BSD 3-Clause "New" or "Revised" License
121 stars 83 forks source link

Android 12 "Failed to acquire USB device." #63

Closed ChaseGuru closed 11 months ago

ChaseGuru commented 2 years ago

Trying to connect to a device fails throws a platform exception with the message "Failed to acquire USB device.".

Only occurs on Android 12.

This looks to suggest something went wrong between in android/src/main/java/dev/bessems/usbserial/UsbSerialPlugin.java lines 145-166.

final devices = await UsbSerial.listDevices();
if (devices.isNotEmpty) {
    devices.first.create();
}
ChaseGuru commented 2 years ago

If maintainers aren't able to get to it first I'll debug the library to see what exception is being thrown in java. That may give more details on what is causing the issue.

ChaseGuru commented 2 years ago

I believe I stepped to UsbSerialPlugin line 121 before the throw but the stack trace was prior to that.

2022-02-24 15:37:58.607 20657-20657/com.red_wolf.mobile E/UsbManager: exception in UsbManager.openDevice
    java.lang.SecurityException: User has not given 10573/com.red_wolf.mobile permission to access device /dev/bus/usb/001/002
        at android.os.Parcel.createExceptionOrNull(Parcel.java:2437)
        at android.os.Parcel.createException(Parcel.java:2421)
        at android.os.Parcel.readException(Parcel.java:2404)
        at android.os.Parcel.readException(Parcel.java:2346)
        at android.hardware.usb.IUsbManager$Stub$Proxy.openDevice(IUsbManager.java:1208)
        at android.hardware.usb.UsbManager.openDevice(UsbManager.java:1094)
        at dev.bessems.usbserial.UsbSerialPlugin.openDevice(UsbSerialPlugin.java:145)
        at dev.bessems.usbserial.UsbSerialPlugin.createTyped(UsbSerialPlugin.java:186)
        at dev.bessems.usbserial.UsbSerialPlugin.onMethodCall(UsbSerialPlugin.java:288)
        at io.flutter.plugin.common.MethodChannel$IncomingMethodCallHandler.onMessage(MethodChannel.java:262)
        at io.flutter.embedding.engine.dart.DartMessenger.invokeHandler(DartMessenger.java:296)
        at io.flutter.embedding.engine.dart.DartMessenger.lambda$dispatchMessageToQueue$0$DartMessenger(DartMessenger.java:320)
        at io.flutter.embedding.engine.dart.-$$Lambda$DartMessenger$TsixYUB5E6FpKhMtCSQVHKE89gQ.run(Unknown Source:12)
        at android.os.Handler.handleCallback(Handler.java:938)
        at android.os.Handler.dispatchMessage(Handler.java:99)
        at android.os.Looper.loopOnce(Looper.java:226)
        at android.os.Looper.loop(Looper.java:313)
        at android.app.ActivityThread.main(ActivityThread.java:8582)
        at java.lang.reflect.Method.invoke(Native Method)
        at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:563)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1133)
     Caused by: android.os.RemoteException: Remote stack trace:
        at com.android.server.usb.UsbUserPermissionManager.checkPermission(UsbUserPermissionManager.java:712)
        at com.android.server.usb.UsbHostManager.openDevice(UsbHostManager.java:539)
        at com.android.server.usb.UsbService.openDevice(UsbService.java:375)
        at android.hardware.usb.IUsbManager$Stub.onTransact(IUsbManager.java:518)
        at android.os.Binder.execTransactInternal(Binder.java:1215)
2022-02-24 15:38:23.249 20657-20657/com.red_wolf.mobile D/CompatibilityChangeReporter: Compat change id reported: 160794467; UID 10573; state: ENABLED
vishalideastoimpact commented 2 years ago

Hi, I'm facing same issue for android 12 the pop-up for permission is not show up and this shows up

D/UsbSerialPortAdapter(13482): ACTION_USB_ATTACHED E/UsbManager(13482): exception in UsbManager.openDevice E/UsbManager(13482): java.lang.SecurityException: User has not given 10364/package_name permission to access device /dev/bus/usb/001/002 E/UsbManager(13482): at android.os.Parcel.createExceptionOrNull(Parcel.java:2441) E/UsbManager(13482): at android.os.Parcel.createException(Parcel.java:2425) E/UsbManager(13482): at android.os.Parcel.readException(Parcel.java:2408) E/UsbManager(13482): at android.os.Parcel.readException(Parcel.java:2350) E/UsbManager(13482): at android.hardware.usb.IUsbManager$Stub$Proxy.openDevice(IUsbManager.java:1022) E/UsbManager(13482): at android.hardware.usb.UsbManager.openDevice(UsbManager.java:734) E/UsbManager(13482): at dev.bessems.usbserial.UsbSerialPlugin.openDevice(UsbSerialPlugin.java:145) E/UsbManager(13482): at dev.bessems.usbserial.UsbSerialPlugin.createTyped(UsbSerialPlugin.java:186) E/UsbManager(13482): at dev.bessems.usbserial.UsbSerialPlugin.onMethodCall(UsbSerialPlugin.java:288) E/UsbManager(13482): at io.flutter.plugin.common.MethodChannel$IncomingMethodCallHandler.onMessage(MethodChannel.java:262) E/UsbManager(13482): at io.flutter.embedding.engine.dart.DartMessenger.invokeHandler(DartMessenger.java:296) E/UsbManager(13482): at io.flutter.embedding.engine.dart.DartMessenger.lambda$dispatchMessageToQueue$0$io-flutter-embedding-engine-dart-DartMessenger(DartMessenger.java:320)E/UsbManager(13482): at io.flutter.embedding.engine.dart.DartMessenger$$ExternalSyntheticLambda0.run(Unknown Source:12) E/UsbManager(13482): at android.os.Handler.handleCallback(Handler.java:938) E/UsbManager(13482): at android.os.Handler.dispatchMessage(Handler.java:99) E/UsbManager(13482): at android.os.Looper.loopOnce(Looper.java:233) E/UsbManager(13482): at android.os.Looper.loop(Looper.java:344) E/UsbManager(13482): at android.app.ActivityThread.main(ActivityThread.java:8204) E/UsbManager(13482): at java.lang.reflect.Method.invoke(Native Method) E/UsbManager(13482): at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:589) E/UsbManager(13482): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1071)

realrk95 commented 2 years ago

This is a permissions problem. You need to add device id and product id along with some changes to the manifest. Here's a link on how: https://community.appinventor.mit.edu/t/usb-permission-popup-every-time-serial-component/12596

mikes222 commented 2 years ago

To summarize the "how":

Find out the vendor ID and the product ID of your device. The class UsbDevice provides both.

In your androidmanifest.xml add the following section:

        <intent-filter>
            <action android:name="android.hardware.usb.action.USB_DEVICE_ATTACHED" />
        </intent-filter>
        <meta-data android:name="android.hardware.usb.action.USB_DEVICE_ATTACHED" android:resource="@xml/usb_device_filter" />

Create a directory android/app/src/main/res/xml if not already existing and add a new file usb_device_filter.xml into it.

Fill the usb_device_filter.xml with the following content and replace product-id and vendor-id with your own ids:

    <?xml version="1.0" encoding="utf-8"?>

    <resources>
        <usb-device vendor-id="1027" product-id="24577" />
        <usb-device vendor-id="1155" product-id="22339" />
        <usb-device vendor-id="6943" product-id="49184" />
    </resources>

That's it.

kbessemer commented 2 years ago

@mikes222

I am still unable to get this to work on my Android 12 device (Pixel 6) even with the changes you mentioned. It works fine on an Android 11 Lenovo tablet.

Other usb serial apps do not detect my serial device on my android 12 phone as well.

Rexios80 commented 2 years ago

It works if I set the targetSdkVersion to 30. I cannot get it to work with targets above 30, even with the recommended manifest changes.

kbessemer commented 2 years ago

@Rexios80 I can confirm changing targetSdkVersion to 30 solved an issue on Android 12 on a colleague's device, however on my Pixel 6 the problem continues.

I even went as far as unlocking my Pixel 6 and manually enabling UART in the boot loader, the device is still not detected. I am thinking Google has put something extra in Pixel 6 for this type of connectivity.

altera2015 commented 11 months ago

Fix merged.