Android Question BroadCastReceiver and Usb RequestPermission

Dane du Plooy

Member
Licensed User
I have a project where I am connecting to a USB slave device (Android is the USB host). Before connecting however, permission is required (UsbManager.HasPermission / UsbManager.RequestPermission). Currently I have a scheme whereby permission is requested if necessary, and the user response to the Android permission request dialog is checked using the following method:

1. Set a flag that USB permission is being requested.
2. RequestPermission
3. In Activity_Resume (called when focus returns to the app after the Android permission request dialog has been handled by the user), check for the USB permission flag; if set, then check if USB permission has been granted, and thus deduce the user response to the dialog.

The above seems to work great on one device which I am testing with (phone), but not on a second device (tablet). Strangely, both devices are of the same Android version (6.0) and build (3.18.19).

Because the scheme is not working on the tablet, I am trying alternatives. One thing which I am currently trying is to use BroadCastReceiver to detect the response to the Android USB Permission Dialog (as per https://developer.android.com/guide/topics/connectivity/usb/host#using-intents, "Obtain permission to communicate with a device"). I am currently trying to implement https://www.b4x.com/android/forum/threads/broadcastreceiver.12493/#content, however am not managing to get the "OnReceive" sub to fire. If anybody has any advice then that would be appreciated! :)

Here is the BroadCastReceiver code which I am currently using:
B4X:
Sub Process_Globals
    Dim bcr As BroadCastReceiver
End Sub

Sub Service_Create
    bcr.Initialize("bcr")
End Sub

Sub Service_Start (StartingIntent As Intent)
    bcr.addAction("za.dizzy.usbtest.USB_PERMISSION")
    bcr.registerReceiver("")
End Sub

Sub bcr_OnReceive(Action As String)
    ToastMessageShow(Action, True)
End Sub
In the Android documentation "com.android.example.USB_PERMISSION" is used - I assume that replacing this with "za.dizzy.usbtest.USB_PERMISSION" is correct (where "za.dizzy.usbtest" is the package name)?
 

DonManfred

Expert
Licensed User
registerReceiver (Action As String)
Registers a Broadcast Receiver.
Action: the intent to listen for.
GoAsync: Allow it to keep the broadcast active after returning from onreceive
So you should set the Action here. What is the action your Device is Broadcasting? Try to add this action in the call to registerreceiver
 

Dane du Plooy

Member
Licensed User
What is the action your Device is Broadcasting?
I have no idea... I think that Android should broadcast something when the USB Permission dialog has been handled by the user? I'm a bit in the deep end here at the moment to be honest :-D.
 

Dane du Plooy

Member
Licensed User
I am now testing on a 2nd tablet (completely different model - Android 5.1.1, Kernel 3.10.65-7415172) and it is exhibiting the same behavior; even 2.5s (I have implemented a timeout loop) after the user has tapped "OK" in order to grant permission on the Android USB Permission dialog, UsbManager.HasPermission is still returning "False" (frustrating!!). Trying to get the BroadCastReceiver going seems like the best idea right now, to see if that perhaps works better... (?)
 

Dane du Plooy

Member
Licensed User
Looking through the Java example code at https://stuff.mit.edu/afs/sipb/proj...opics/connectivity/usb/host.html#permission-d ("Obtain permission to communicate with a device"), I see that UsbManager.RequestPermission is called with two parameters - one of them being a "PendingIntent":
B4X:
mUsbManager.requestPermission(device, mPermissionIntent);
UsbManager.RequestPermission in B4A only accepts one parameter however - is this sort of functionality perhaps not supported in B4A?
 

Erel

Administrator
Staff member
Licensed User

Dane du Plooy

Member
Licensed User
Why aren't you using a static intent filter for the device?
That's pretty much what I've ended up with, thank-you, and it seems to be working much better.

I've added a dummy activity to act as the target for the intent, which just closes as soon as it is run, because I do not actually want to jump to a specific activity when the USB device is inserted.

The static intent filter seems like a much better option - once permission has been granted it is not asked for again, whereas with the runtime permission it is asked for every time the device is removed and inserted (except on the one phone I have here, which never seems to ask for permission ever - weird).

I have manually created the usb device xml file in the manifest:
B4X:
CreateResource(xml, usb_device_filter.xml,
<resources>
  <usb-device vendor-id="1234" product-id="5678" />
</resources>
)
 

DonManfred

Expert
Licensed User
I've added a dummy activity to act as the target for the intent, which just closes as soon as it is run, because I do not actually want to jump to a specific activity when the USB device is inserted.
create a service and configure the intent filter to start this service (do not use the starter service for this). No need to open an activity. even if it just quits as it runs.
 

Dane du Plooy

Member
Licensed User
Thanks Manfred :).
I think I read somewhere that the USB intent has to target an Activity for some reason, rather than a service. A little experimenting would confirm that.
 

Dane du Plooy

Member
Licensed User
Top