尝试访问USB设备时,libusb_open_device_with_vid_pid失败

我试图让USB设备连接到Android 5.1.1设备。 以前我一直在使用常规的libusb KitKat,但棒棒糖增加了安全性,这不再起作用。

这是有据可查的,需要root来设置SELinux的级别。 我不想根设备来让USB设备连接到它。

环顾四周,我碰到这个答案 ,我已经试过这个libusb叉 ,但是现在我得到一个新的错误

libusb_open_device_with_vid_pid (29c2) failed. Failed to setup USB usb_setup: -1 

我没有改变任何代码,只有库。

这仍然是一个权限问题,或者有什么我错过,将使这项工作?

Solutions Collecting From Web of "尝试访问USB设备时,libusb_open_device_with_vid_pid失败"

以下步骤可以用来解决您提到的问题。

将设备安装为USB大容量存储器的过程在设备和制造商特定的设备之间是不一致的。 当您通过USB电缆将设备连接到桌面时,某些设备(如Nexus S)提供“打开USB存储设备”。 其他设备(如Galaxy S3)现在需要一个应用程序来将该设备作为大容量存储器启动。 无论哪种方式,Android设备通常都会提供这样的function,您必须创build一个与设备制造商规格相匹配的文件。

在使用USB主机API之前,您需要添加到应用程序的清单文件中:

  • 由于并非所有基于Android的设备都能保证支持USB主机API,因此包含一个声明应用程序使用android.hardware.usb.hostfunction的元素。
  • 如果您希望向应用程序通知连接的USB设备,请在您的主要活动中为android.hardware.usb.action.USB_DEVICE_ATTACHED意图指定一个元素对。

将USB_DEVICE_ATTACHED添加到您的manisfest文件中:

 <manifest ...> <uses-feature android:name="android.hardware.usb.host" /> <uses-sdk android:minSdkVersion="12" /> ... <application> <activity ...> ... <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/device_filter" /> </activity> </application> </manifest> 

为了帮助您的APP发现特定的USB设备,您可以使用意图filter:

 <activity ...> ... <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/device_filter" /> </activity> 

您还需要指定您的设备和供应商ID:

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

这应该足以处理您的USB主机连接。 现在拨打USB:

 int LIBUSB_CALL libusb_open2(libusb_device *dev, libusb_device_handle **handle, int fd); 

使用描述符打开连接到USB设备 – 例如:

 UsbManager myUsbManager = (UsbManager) getSystemService(Context.USB_SERVICE); UsbAccessory myUsbAccessory = (myUsbManager.getAccessoryList())[0]; ParcelFileDescriptor pfd = myUsbManager.openAccessory(myUsbAccessory); FileDescriptor fileDescriptor = pfd.getFileDescriptor(); FileInputStream myFileInputStream = new FileInputStream(fileDescriptor); FileOutputStream myFileOutputStream = new FileOutputStream(fileDescriptor); 

如果您仍然遇到SELinux级别的问题,那么您可以使用一些编辑来使程序顺利运行:

 // default.prop ro.secure=1 -----------------> ro.secure=0 ro.adb.secure=1 -----------------> ro.adb.secure=0 //init.rc setsebool debugfs 1 --------> setsebool debugfs 0 setenforce 0 setprop selinux.reload_policy 1 -------> setprop selinux.reload_policy 0 // init.target.rc setprop selinux.reload_policy 1 -----> setprop selinux.reload_policy 0 

由于SELinux默认设置为强制执行最高安全性,并且您希望授予客户端通过USB访问您的Android设备的权限。

在这里输入图像说明

根据您的Android制造商和型号,尝试拔下连接设备和桌面的USB电缆,然后重新插入。应提示您“打开USB”存储。 如果是这种情况,请在Android上尝试浏览至设置→更多… ,然后查找USB大容量存储选项。

http://www.pocketables.com/images/old/6a00d83451c9ec69e201675f40c44a970b-500wi.png

或者,查找设备制造商推荐的USB大容量存储过程。 当你打开USB存储设备,让你知道一些应用程序将停止,继续并确定。 现在转到您的桌面计算机,浏览到您的USB大容量存储介质,如果您没有重命名,通常称为NO NAME。 点击您的大容量存储设备,然后在脚本文件夹中find一个名为data.tsv的文件。

在这里输入图像说明

您也可以通过在您最喜欢的文本编辑器中打开它来检查data.tsv。 你会发现两列整齐地分开一个标签; 在每一行中,您将find一对整数值。 这对我们的项目来说已经足够了。 更复杂的数据项目通常需要每行的唯一标识符,一个表中的行指向另一个表中的特定logging。

在这里输入图像说明

根据你的开发环境 ,你也必须相应地调整你的设置。 如果您正在Windows上开发,请按照可用的USB驱动程序安装说明进行操作 。 如果您正在Linux上开发,请按照说明设置您的设备进行开发。

在这里输入图像说明

此外,值得一提的是,以前发布的许多Android设备只能作为USB设备使用,不能启动与外部USB设备的连接。 Android开放配件(AOA)支持克服了这一限制,允许您通过允许附件启动连接来构build可与各种Android设备进行交互的配件。 在项目中可以findAndroid Open Accessory的常见使用示例:使用USB主机模式录制和播放audio – 这当然需要USB模式启动并运行。

在这里输入图像说明

让Android通过USB与Arduino微控制器进行通信也是一种实现方式,最近显得非常成功,因为它允许您通过多设备解决scheme来扩展您的Androidfunction,集成更多function。 一个典型的Arduino Sketch允许设备与您的Android USB通信如下所示:

 // the USB Host libraries #include <Max3421e.h> #include <Usb.h> // the AOA library #include <AndroidAccessory.h> void setup(); void loop(); void setup() { // start serial debugging Serial.begin(115200); Serial.print("\r\nADK has run setup()."); Serial.println("Ready to start USB communication..."); } void loop() { // example - read the voltage from a sensor uint16_t val; val = analogRead(TEMP_SENSOR); // or any sort of input Serial.println(val,HEX); Serial.write(val); // Delay for 100 milliseconds. delay(100); } 

所有的Arduino项目都必须有一个setup()和一个loop()方法声明,否则你的Android将不能正确通信。

还要记住使用AOA所需的最低要求清单:

  • 与AOA兼容的Android设备。 要在尝试此示例之前testing兼容性,请参阅“支持的Android设备”部分,以获取有关Google Play上提供的Microchip AOA演示应用程序的链接。
  • 兼容的微控制器板 如果您不确定,Arduino Mega ADK将是一个简单的select。

在这里输入图像说明

使用USB的Android设备的可能性是惊人的,而能够充分利用这些function的创新APP的需求将显着增长。

你的错误与权限是无关的,与I / O有关, -1错误相当于

 LIBUSB_ERROR_IO - Input/output error. 

你可以修改JNI接口 ,把libusbdebugging到debugging模式libusb_set_debug() ,我认为这是知道真正发生的唯一方法。

无论如何,首先检查您的VID / PID,以确保它在连接的设备列表中。

在Android上,不能使用没有root的libusb_open_device_with_vid_pid。 要访问USB设备,您必须使用UsbDeviceManager Android API。

我所知道的将libusb连接到Android的公共源代码的唯一例子是: https : //github.com/martinmarinov/rtl_tcp_andro-/

你永远不会读/写/ dev / bus / usb / xxx / yyy。 Android的做法是,系统服务通过活页夹向您发送已请求的特定/ dev / bus / usb / xxx / yyy设备上已打开的文件描述符。

现在已经有很多关于如何在Android中处理Java中的UsbHost的文档,所以我将指出之后的东西。

  • 你需要一个打补丁的libusb(rtl_tcp_andro-将会这样做),它可以取一个文件描述符而不是一个设备名/ pid / vid
  • 你需要调用libusb_open2(这是如何用fd在rtl_tcp_andro的libusb中调用这个新函数)与您将使用UsbDeviceConnection.getFileDescriptor()检索的fd

编辑:我看到rtl_tcp_andro-也添加了一个libusb_init2,我不明白为什么ATM,但提交说,这是为L的支持,所以我想这也是需要的。

这个提到的USB补丁在下一个方面起作用:

  1. 你必须通过UsbManager打开设备
  2. 由libusb打开
  3. closureslibusb
  4. closuresUsbManager

正是这个顺序将工作。