有2种方法:
1.chmod 666 dev/bus/usb/*
2.如果没有android root权限那就麻烦一点,描述个大概
AndroidManifest.xml中添加:
<uses-feature android:name="android.hardware.usb.host" android:required="true"/>
...
<uses-permission android:name="android.hardware.usb.host" />
<uses-permission android:name="ANDROID.PERMISSION.HARDWARE_TEST" />
...
<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" />
device_filter.xml内容:
<?xml version="1.0" encoding="utf-8"?>
<resources>
<usb-device vendor-id="1204" product-id="34323" />
<usb-device vendor-id="1204" product-id="241" />
</resources>
//确认需要通信的usb devide的vid和pid。确认这里是十进制。
代码中用usbManager open你需要open的设备然后获取fd。这个fd是关键,通过jni把fd传进libusb:
UsbDeviceConnection usbDeviceC = manager.openDevice(mUsbDevice);
int fd = usbDeviceC.getFileDescriptor();
--------------------jni------------------------传递fd进libusb,修改libusb接口
ibusb_device_handle *h = NULL;
h = libusb_open_device_with_vid_pid(p_ctx, vid, pid, fd);
libusb_control_transfer(h, 0x40, vendor_command, address, 0x00, dbuf, num_bytes, 1000);
.....
libusb 在core.c中添加
DEFAULT_VISIBILITY
libusb_device_handle * LIBUSB_CALL libusb_open_device_with_vid_pid(
libusb_context *ctx, uint16_t vendor_id, uint16_t product_id,int fd)
{
struct libusb_device **devs;
struct libusb_device *found = NULL;
struct libusb_device *dev;
struct libusb_device_handle *handle = NULL;
size_t i = 0;
int r;
if (libusb_get_device_list(ctx, &devs) < 0)
return NULL;
while ((dev = devs[i++]) != NULL) {
struct libusb_device_descriptor desc;
r = libusb_get_device_descriptor(dev, &desc);
if (r < 0)
goto out;
if (desc.idVendor == vendor_id && desc.idProduct == product_id) {
found = dev;
break;
}
}
if (found) {
r = libusb_open_fd(found, &handle,fd);
if (r < 0)
handle = NULL;
}
out:
libusb_free_device_list(devs, 1);
return handle;
}
int LIBUSB_CALL libusb_open_fd(libusb_device *dev, libusb_device_handle **handle, int fd)
{
struct libusb_context *ctx = DEVICE_CTX(dev);
struct libusb_device_handle *_handle;
size_t priv_size = usbi_backend->device_handle_priv_size;
int r;
usbi_dbg("open %d.%d", dev->bus_number, dev->device_address);
_handle = malloc(sizeof(*_handle) + priv_size);
if (!_handle)
return LIBUSB_ERROR_NO_MEM;
r = usbi_mutex_init(&_handle->lock, NULL);
if (r) {
free(_handle);
return LIBUSB_ERROR_OTHER;
}
_handle->dev = libusb_ref_device(dev);
_handle->claimed_interfaces = 0;
memset(&_handle->os_priv, 0, priv_size);
r = usbi_backend->open_fd(_handle, fd);
if (r < 0) {
usbi_dbg("open %d.%d returns %d", dev->bus_number, dev->device_address, r);
libusb_unref_device(dev);
usbi_mutex_destroy(&_handle->lock);
free(_handle);
return r;
}
usbi_mutex_lock(&ctx->open_devs_lock);
list_add(&_handle->list, &ctx->open_devs);
usbi_mutex_unlock(&ctx->open_devs_lock);
*handle = _handle;
/* At this point, we want to interrupt any existing event handlers so
* that they realise the addition of the new device's poll fd. One
* example when this is desirable is if the user is running a separate
* dedicated libusb events handling thread, which is running with a long
* or infinite timeout. We want to interrupt that iteration of the loop,
* so that it picks up the new fd, and then continues. */
usbi_fd_notification(ctx);
return 0;
}
在linux_usbfs.c中添加
const struct usbi_os_backend linux_usbfs_backend = {
...
.open_fd = op_open_fd,
...
}
static int op_open_fd(struct libusb_device_handle *handle,int fd)
{
struct linux_device_handle_priv *hpriv = _device_handle_priv(handle);
int r;
hpriv->fd = fd;
if (hpriv->fd < 0) {
if (hpriv->fd == LIBUSB_ERROR_NO_DEVICE) {
/* device will still be marked as attached if hotplug monitor thread
* hasn't processed remove event yet */
usbi_mutex_static_lock(&linux_hotplug_lock);
if (handle->dev->attached) {
usbi_dbg("open failed with no device, but device still attached");
linux_device_disconnected(handle->dev->bus_number,
handle->dev->device_address, NULL);
}
usbi_mutex_static_unlock(&linux_hotplug_lock);
}
return hpriv->fd;
}
r = ioctl(hpriv->fd, IOCTL_USBFS_GET_CAPABILITIES, &hpriv->caps);
if (r < 0) {
if (errno == ENOTTY)
usbi_dbg("getcap not available");
else
usbi_err(HANDLE_CTX(handle), "getcap failed (%d)", errno);
hpriv->caps = 0;
if (supports_flag_zero_packet)
hpriv->caps |= USBFS_CAP_ZERO_PACKET;
if (supports_flag_bulk_continuation)
hpriv->caps |= USBFS_CAP_BULK_CONTINUATION;
}
return usbi_add_pollfd(HANDLE_CTX(handle), hpriv->fd, POLLOUT);
}
libusb.h libusbi.h中添加
int LIBUSB_CALL libusb_open_fd(libusb_device *dev, libusb_device_handle **handle, int fd);
libusb_device_handle * LIBUSB_CALL libusb_open_device_with_vid_pid(
libusb_context *ctx, uint16_t vendor_id, uint16_t product_id,int fd);
int (*open_fd)(struct libusb_device_handle *handle, int fd);
总结一句关键hpriv->fd = _get_usbfs_fd(handle->dev, O_RDWR, 0);变成了hpriv->fd=fd从上层传递下来的fd,这样android应用就可以操作ioctl了。