• Android 中USB-HID协议实现


    前言

    所有通过USB连接android设备进行通讯的步骤都是大同小异:查询usb设备列表 ——>匹配对应的设备类型(如productid , vendorId)等——>连接usb设备,找到连接通讯的节点——>配置通讯信息,进行通讯。以上是通常的连接usb设备进行通讯的步骤和特点。

    下面来说一下usb-hid的连接机制和步骤

    首先讲讲hid是什么?

    (Human Interface devices)指的是人机交互接口设备,通常是指我们日常用到的键盘鼠标等设备。

    USB描述符的内容

    标准的USB设备总共包括五种USB描述符:设备描述符,配置描述符,接口描述符,端点描述符,字符串描述符。HID设备除了需要标准的USB描述符还需要HID报告描述符,HID物理描述符可选。HID是一种USB通信协议,无需安装驱动就能进行交互。

    有些场景下,我们会用到复合usb-hid,比如在usb camera中我们需要在摄像头硬件里增加物理按键来实现相关的功能,这种情况下就会涉及到复合usb'-hid的场景,这种情况下,我们需要找到相关的接口描述符,然后进行与硬件按钮进行协议交互。

    步骤:
    一,查找列表,匹配对应的设备
    UsbManager manager = (UsbManager) getSystemService(Context.USB_SERVICE);
    //找到对应的设备列表,然后与已知的productId和vendorID进行匹配找到对应的设备。
    UsbDevice device = (UsbDevice) manager.getDeviceList().valuse().toArray()[0];
    
    二、请求设备权限
    PendingIntent pendingIntent = PendingIntent.getBroadcast(
            Application.getBaseApp().getApplicationContext(), 0, new Intent(ACTION_USB_PERMISSION), PendingIntent.FLAG_IMMUTABLE
    );
    
    IntentFilter filter = new IntentFilter(ACTION_USB_PERMISSION);
    filter.addAction(UsbManager.ACTION_USB_DEVICE_ATTACHED);
    filter.addAction(UsbManager.ACTION_USB_DEVICE_DETACHED);
    Application.getBaseApp().getApplicationContext().registerReceiver(mUsbReceiver, filter);
    manager.requestPermission(device, pendingIntent);
    三、连接设备并进行通信
    if (device != null) {
        connection = manager.openDevice(device);
        if (connection == null) {
            return;
        }
        interfacesList = new LinkedList();
        for (int i = 0; i < device.getInterfaceCount(); i++) {
            UsbInterface intf = device.getInterface(i);
            interfacesList.add(intf);
        }
        usbThreadDataReceiver = new USBThreadDataReceiver();
        usbThreadDataReceiver.start();
    
    }
    

    //循环接收消息

    for (UsbInterface intf : interfacesList) {
        if (intf.getInterfaceClass() != 0x0E) {  //非视频流接口描述
            for (int i = 0; i < intf.getEndpointCount(); i++) {
                UsbEndpoint endPointRead = intf.getEndpoint(i);
                connection.claimInterface(intf, true);
                if (UsbConstants.USB_DIR_IN == endPointRead.getDirection()) {
                    while (!isStopped) {
                        final byte[] buffer = new byte[endPointRead.getMaxPacketSize()];
                        int status = connection.bulkTransfer(endPointRead, buffer, buffer.length, 100);
                        if (status > 0) {
                            if (listener != null) {
                                listener.recevie(bytes2HexString(buffer));
                            }
                        }
    }
    }
    这里需要注意的是:设备中每一个接口描述都是对应的HID 设备支持的一种功能。可以参考对应的文献资料:USB-HID设备中的复合设备_usb interface number-CSDN博客

  • 相关阅读:
    Avalonia 初学笔记(2):简单了解与WPF的区别
    Oracle rac环境的数据库导入操作记录
    SGI STL 二级空间配置源码刨析
    字符串思维题练习 DAY1(CF691B , CF706C , CF1555D)
    HTTP(三)HTTP常见的状态码
    图纸管理制度《二》
    跨境电商背后的业务逻辑集运+代购系统
    剑指 Offer 06. 从尾到头打印链表
    在医疗影像领域,生成式模型可以做些什么?用什么平台快速实现?使用MONAI框架进行生成式模型开发
    从零开始学习嵌入式----Linux系统中shell脚本
  • 原文地址:https://blog.csdn.net/easonguolong/article/details/139625595