How to grant permission to open usb device with usb manager? openDevice() always returns null
Asked Answered
L

1

9

I want to use a usb device in the following code. It successfully lists the usb devices and iterates over them. In the following code the object "device" is the usbdevice that i need to open. Everything seems Ok except the OpenDevice() method that always returns a null value!

[Activity(Label = "TestApp", MainLauncher = true, Icon = "@drawable/icon")]
[IntentFilter(new[] {UsbManager.ActionUsbDeviceAttached})]
[MetaData(UsbManager.ActionUsbDeviceAttached, Resource = "@xml/device_filter")]

public class MainActivity : Activity
{
    int count = 1;
   {
       base.OnCreate(bundle);

        // Set our view from the "main" layout resource
        SetContentView(Resource.Layout.Main);
        UsbManager manager = (UsbManager)GetSystemService(Context.UsbService);
        UsbDevice device = null;
        foreach (var dev in manager.DeviceList)
        {
            if (dev.Value.VendorId == 5401)
            {
                device = dev.Value;
            }
        }
        var connection = manager.OpenDevice(device);
        // Read some data! Most have just one port (port 0).
    }

The device_filter.xml contains the following lines:

<?xml version="1.0" encoding="utf-8" ?>
<resources>
   <usb-device product-id="8704" vendor-id="5401" />
</resources>

When I tried bool hasPermision = manager.HasPermission(device); I saw that hasPermission is false. Could anybody tell me How can I grant permission for opening a usb device in xamarin? Thanks for any help.

Lyrist answered 25/1, 2015 at 14:7 Comment(0)
L
14

At last I fixed it after trying several suggestions. I found that adding the intent filter in manifest does not solve the permission issue for unknown reasons. It's sounds like a bug of the Xamarin. To tell the truth, It seems that Xamarin usb namespace is too naive, and its better you do not waste your time to use that for USB management and connection. It also has some other annoying limitations. For example look at here. (So I suggest to write low level usb communication codes in java and import the jar file in xamarin by JNI, I tired it and I should say It's a lot easier than it seemed at first time)

To grant the permission of opening the usb device, you have to use the grantPermission() method. The following code shows how to use the method and BroadcastReceiver to pop up a dialog asking the user to let the usb usage.

 public class MainActivity : Activity
{
    private static String ACTION_USB_PERMISSION = "com.android.example.USB_PERMISSION";
    UsbDevice device; 
    protected override void OnCreate(Bundle bundle)
    {
        base.OnCreate(bundle);

        // Set our view from the "main" layout resource
        SetContentView(Resource.Layout.Main);
        UsbManager manager = (UsbManager)GetSystemService(Context.UsbService);

        UsbReciever usbReciever = new UsbReciever();
        PendingIntent mPermissionIntent = PendingIntent.GetBroadcast(this, 0, new Intent(
            ACTION_USB_PERMISSION), 0);
        IntentFilter filter = new IntentFilter(ACTION_USB_PERMISSION);
        RegisterReceiver(usbReciever, filter);

        foreach (var dev in manager.DeviceList)
        {
            if (dev.Value.VendorId == 8192)
            {
                device = dev.Value;
            }
        }
        manager.RequestPermission(device, mPermissionIntent);
        bool hasPermision = manager.HasPermission(device);

        UsbDeviceConnection connection = manager.OpenDevice(device);
        if (connection == null)
        {
            return;
        }
        Button button = FindViewById<Button>(Resource.Id.MyButton);
    }
    class UsbReciever : BroadcastReceiver
    {
        public override void OnReceive(Context context, Intent intent)
        {
            String action = intent.Action;
            if (ACTION_USB_PERMISSION.Equals(action))
            {
                lock (this)
                {
                    UsbDevice device = (UsbDevice)intent
                            .GetParcelableExtra(UsbManager.ExtraDevice);

                    if (intent.GetBooleanExtra(
                            UsbManager.ExtraPermissionGranted, false))
                    {
                        if (device != null)
                        {
                            // call method to set up device communication
                        }
                    }
                    else
                    {

                    }
                }
            }
        }
    }


}
Lyrist answered 29/1, 2015 at 15:13 Comment(6)
What is the use of thiscom.android.example.USB_PERMISSION?Raffo
@i-Droid Before communicating with the USB device, your application must have permission from your users. Note: If your application uses an intent filter to discover USB devices as they're connected, it automatically receives permission if the user allows your application to handle the intent. If not, you must request permission explicitly in your application before connecting to the device. Refer to : developer.android.com/guide/topics/connectivity/usb/host.htmlLyrist
This is not popping up the Permission dialog for me :/ I'm REALLY new to Xamarin.Android and I was tasked with creating an application that takes photos from a Logitech C270 Webcam. Could you please help me with the first steps?Bullins
So you find in MainActivity that you need permission, so you ask for it, and then you end up in UsbReceiver. But you cant set up device communication there because you need the Device inside MainActivity -- a different class? How after asking for permission can you pass control back to MainActivity to complete the setup??Entomology
If you use the manually request permission from the UsbManager, your app will never remember the user choice. The user will have to confirm each time the device is plugged and unplugged.Schuck
@RichardBarraclough he is getting the device in the receiver class using UsbDevice device = (UsbDevice)intent .GetParcelableExtra(UsbManager.ExtraDevice);Faria

© 2022 - 2024 — McMap. All rights reserved.