http://www.freehum.com/2014/06/operate-usb-device-under-android-by-libusb-without-root.html

对原作者做了一定的改进

之前有段时间在 Android 下调用我们自己开发的 USB 摄像头,在 CSDN 上讨论了一番,发现感兴趣的人蛮多了,不断网友发邮件来问,干脆放到博客上吧

基本思路:

利用 Android (3.1版本以上)的 USB HOST API 获得 USB 设备的 FileDescriptor,然后libusb 使用 FileDescriptor 打开 USB 设备,当然 libusb 需要做少量修改,后面有代码。

总体的效果就是,用户插入USB 设备,或者启动 Android 系统,你的 App 会根据事先设定的 device filter 自动启动。如果是第一次启动,会询问用户是否授权使用该USB设备。

关键代码(如何使用libusb,请参考官方文档):

获取 FileDescriptor
// get FileDescriptor by Android USB Host APIUsbManager manager = (UsbManager) mContext.getSystemService(Context.USB_SERVICE);final String ACTION_USB_PERMISSION = "com.android.example.USB_PERMISSION";HashMap deviceList = manager.getDeviceList();Iterator deviceIterator = deviceList.values().iterator(); PendingIntent mPermissionIntent = PendingIntent.getBroadcast(mContext, 0,                                                              new Intent(ACTION_USB_PERMISSION), 0);IntentFilter filter = new IntentFilter(ACTION_USB_PERMISSION);mContext.registerReceiver(mUsbReceiver, filter); int fd = -1;while(deviceIterator.hasNext()){    UsbDevice device = deviceIterator.next();    Log.i(TAG, device.getDeviceName() + " " + Integer.toHexString(device.getVendorId()) +                " " + Integer.toHexString(device.getProductId()));     manager.requestPermission(device, mPermissionIntent);    UsbDeviceConnection connection = manager.openDevice(device);    if(connection != null){       fd = connection.getFileDescriptor();    } else       Log.e(TAG, "UsbManager openDevice failed");    break;}

接着修改 libusb,我用的是libusbx-1.0.17,主要工作是增加一个 libusb_open_fd 函数,替代原来的 libusb_open,将上一步的 fd 传入即可。 libusbx\libusb\core.c 中在 libusb_open 后面增加 libusb_open_fd 函数
#ifdef ANDROIDint 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;}#endif

libusbx\libusb\libusb.h中找到libusb_open函数的声明,在其下面添加libusb_open_fd声明:
int LIBUSB_CALL libusb_open_fd(libusb_device *dev, libusb_device_handle **handle, int fd);
libusbx\libusb\libusbi.h中找到结构体usbi_os_backend,在其内部成员open下面添加
int (*open_fd)(struct libusb_device_handle *handle, int fd);
libusbx\libusb\os\linux_usbfs.c 中在 op_open 后面增加 op_open_fd 函数
#ifdef ANDROID//可以去掉,否则要到config.h中去定义才能是同static int op_open_fd(struct libusb_device_handle *handle, int fd) {struct linux_device_handle_priv *hpriv = _device_handle_priv(handle); hpriv->fd = fd; return usbi_add_pollfd(HANDLE_CTX(handle), hpriv->fd, POLLOUT);}#endif
libusbx\libusb\os\linux_usbfs.c 中在 结构体 linux_usbfs_backend 中 .open = op_open 一行后面增加一行
#ifdef ANDROID//可以去掉,否则要到config.h中去定义才能是同    .open_fd = op_open_fd,#endif



更多相关文章

  1. Android 自定义Toast
  2. android UI学习 -- 设置界面的布局(包括style的使用,selector的
  3. Android SDK自定义更新
  4. Android Bluetooth蓝牙开发:Bluetooth蓝牙设备之间数据传输(4)
  5. 安卓自定义interpolator
  6. [置顶] 定义一个ImageVIew出现警告的去除办法
  7. 可自定义 View 的 Toast

随机推荐

  1. 申请GoogleMap apikey
  2. ViewModel、ViewModelProviders、ViewMod
  3. Android中代码混淆
  4. 关于android UDP 客户端与delphi UDP服务
  5. Android Exported service does not requ
  6. android 状态栏和导航栏(status and navi
  7. 无标题文章
  8. Android中改变Dialog背景透明度
  9. android 文本框实现搜索和清空效果
  10. 【Android不太基础】换个思路来监听home