Android 用 libusb 操作 USB 设备,无须 root

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 
[java]  view plain  copy
  在CODE上查看代码片 派生到我的代码片
  1. // get FileDescriptor by Android USB Host API  
  2. UsbManager manager = (UsbManager) mContext.getSystemService(Context.USB_SERVICE);  
  3. final String ACTION_USB_PERMISSION = "com.android.example.USB_PERMISSION";  
  4. HashMap<String, UsbDevice> deviceList = manager.getDeviceList();  
  5. Iterator<UsbDevice> deviceIterator = deviceList.values().iterator();  
  6.    
  7. PendingIntent mPermissionIntent = PendingIntent.getBroadcast(mContext, 0,   
  8.                                                              new Intent(ACTION_USB_PERMISSION), 0);  
  9. IntentFilter filter = new IntentFilter(ACTION_USB_PERMISSION);  
  10. mContext.registerReceiver(mUsbReceiver, filter);  
  11.    
  12. int fd = -1;  
  13. while(deviceIterator.hasNext()){  
  14.     UsbDevice device = deviceIterator.next();  
  15.     Log.i(TAG, device.getDeviceName() + " " + Integer.toHexString(device.getVendorId()) +   
  16.                " " + Integer.toHexString(device.getProductId()));  
  17.    
  18.     manager.requestPermission(device, mPermissionIntent);  
  19.     UsbDeviceConnection connection = manager.openDevice(device);  
  20.     if(connection != null){  
  21.        fd = connection.getFileDescriptor();  
  22.     } else  
  23.        Log.e(TAG, "UsbManager openDevice failed");  
  24.     break;  
  25. }  

接着修改 libusb,我用的是libusbx-1.0.17, 主要工作是增加一个 libusb_open_fd 函数,替代原来的 libusb_open,将上一步的 fd 传入即可。
libusbx\libusb\core.c 中在 libusb_open 后面增加 libusb_open_fd 函数
[cpp]  view plain  copy
  在CODE上查看代码片 派生到我的代码片
  1. #ifdef ANDROID  
  2. int LIBUSB_CALL libusb_open_fd(libusb_device *dev, libusb_device_handle **handle, int fd)  
  3. {  
  4. struct libusb_context *ctx = DEVICE_CTX(dev);  
  5. struct libusb_device_handle *_handle;  
  6. size_t priv_size = usbi_backend->device_handle_priv_size;  
  7. int r;  
  8. usbi_dbg("open %d.%d", dev->bus_number, dev->device_address);  
  9.    
  10. _handle = malloc(sizeof(*_handle) + priv_size);  
  11. if (!_handle)  
  12. return LIBUSB_ERROR_NO_MEM;  
  13.    
  14. r = usbi_mutex_init(&_handle->lock, NULL);  
  15. if (r) {  
  16. free(_handle);  
  17. return LIBUSB_ERROR_OTHER;  
  18. }  
  19.    
  20. _handle->dev = libusb_ref_device(dev);  
  21. _handle->claimed_interfaces = 0;  
  22. memset(&_handle->os_priv, 0, priv_size);  
  23.    
  24. r = usbi_backend->open_fd(_handle, fd);  
  25. if (r < 0) {  
  26. usbi_dbg("open %d.%d returns %d", dev->bus_number, dev->device_address, r);  
  27. libusb_unref_device(dev);  
  28. usbi_mutex_destroy(&_handle->lock);  
  29. free(_handle);  
  30. return r;  
  31. }  
  32.    
  33. usbi_mutex_lock(&ctx->open_devs_lock);  
  34. list_add(&_handle->list, &ctx->open_devs);  
  35. usbi_mutex_unlock(&ctx->open_devs_lock);  
  36. *handle = _handle;  
  37.    
  38. /* At this point, we want to interrupt any existing event handlers so 
  39.  * that they realise the addition of the new device's poll fd. One 
  40.  * example when this is desirable is if the user is running a separate 
  41.  * dedicated libusb events handling thread, which is running with a long 
  42.  * or infinite timeout. We want to interrupt that iteration of the loop, 
  43.  * so that it picks up the new fd, and then continues. */  
  44. usbi_fd_notification(ctx);  
  45.    
  46. return 0;  
  47. }  
  48. #endif  

libusbx\libusb\libusb.h中找到libusb_open函数的声明,在其下面添加libusb_open_fd声明:
[cpp]  view plain  copy
  在CODE上查看代码片 派生到我的代码片
  1. int LIBUSB_CALL libusb_open_fd(libusb_device *dev, libusb_device_handle **handle, int fd);  
libusbx\libusb\libusbi.h中找到结构体usbi_os_backend,在其内部成员open下面添加
[cpp]  view plain  copy
  在CODE上查看代码片 派生到我的代码片
  1. int (*open_fd)(struct libusb_device_handle *handle, int fd);  
libusbx\libusb\os\linux_usbfs. c 中在 op_open 后面增加 op_open_fd 函数
[cpp]  view plain  copy
  在CODE上查看代码片 派生到我的代码片
  1. #ifdef ANDROID//可以去掉,否则要到config.h中去定义才能是同  
  2. static int op_open_fd(struct libusb_device_handle *handle, int fd) {  
  3. struct linux_device_handle_priv *hpriv = _device_handle_priv(handle);  
  4.    
  5. hpriv->fd = fd;  
  6.    
  7. return usbi_add_pollfd(HANDLE_CTX(handle), hpriv->fd, POLLOUT);  
  8. }  
  9. #endif  
libusbx\libusb\os\linux_usbfs.c 中在 结构体 linux_usbfs_backend 中 .open = op_open 一行后面增加一行
[cpp]  view plain  copy
  在CODE上查看代码片 派生到我的代码片
  1. #ifdef ANDROID//可以去掉,否则要到config.h中去定义才能是同  
  2.     .open_fd = op_open_fd,  
  3. #endif  
转载至:
http://blog.csdn.net/hubbybob1/article/details/52101356
  • 0
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值