Android 用 libusb 操作 USB 設備,無須 root

基本思路:

利用 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 API
    UsbManager manager = (UsbManager) mContext.getSystemService(Context.USB_SERVICE);
    final String ACTION_USB_PERMISSION = "com.android.example.USB_PERMISSION";
    HashMap<String, UsbDevice> deviceList = manager.getDeviceList();
    Iterator<UsbDevice> 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 函數

    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;
    }

在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 函數

    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);
    }

libusbx\libusb\os\linux_usbfs.c 中在 結構體 linux_usbfs_backend 中 .open = op_open 一行後面增加一行

        .open_fd = op_open_fd,


————————————————
版權聲明:本文爲CSDN博主「葫蘆娃二娃」的原創文章,遵循 CC 4.0 BY-SA 版權協議,轉載請附上原文出處鏈接及本聲明。
原文鏈接:https://blog.csdn.net/hubbybob1/article/details/52101356

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章