Android USB 主机,3.2,HID 报告获取/设置

标签 android usb host

我有一个 HID 设备,特别是 -> Silicon Labs USB-FM radio 引用设计。 此设备公开为 HID。

使用 3.2 USB 主机 API,如何执行 HID_REPORT_GET/SET 或等效的操作?

干杯, 厄伦斯

最佳答案

我刚得到一个 Si470x USB 加密狗,可以在 Android 上运行。我通过围绕 Android 调用编写一个小包装类来解决 HID 部分:

private class HidDevice {
    /** GET_REPORT request code */
    public static final int REQUEST_GET_REPORT = 0x01;
    /** SET_REPORT request code */
    public static final int REQUEST_SET_REPORT = 0x09;
    /** INPUT report type */
    public static final int REPORT_TYPE_INPUT = 0x0100;
    /** OUTPUT report type */
    public static final int REPORT_TYPE_OUTPUT = 0x0200;
    /** FEATURE report type */
    public static final int REPORT_TYPE_FEATURE = 0x0300;

    private Context context;
    private UsbManager manager;
    private UsbDevice device;
    private UsbInterface ifHid = null;
    private UsbEndpoint epIn = null;
    private UsbDeviceConnection connection;

    public HidDevice(Context context, UsbDevice device) throws IOException {
        this.context = context;
        this.device = device;

        for (int i = 0; (this.ifHid == null) && (i < device.getInterfaceCount()); i++)
            if (device.getInterface(i).getInterfaceClass() == UsbConstants.USB_CLASS_HID) {
                this.ifHid = device.getInterface(i);
                for (int j = 0; j < ifHid.getEndpointCount(); j++) {
                    UsbEndpoint ep = ifHid.getEndpoint(j);
                    if ((ep.getDirection() == UsbConstants.USB_DIR_IN) && (ep.getType() == UsbConstants.USB_ENDPOINT_XFER_INT))
                        epIn = ep;
                }
            }
        if (this.ifHid == null)
            throw new IllegalArgumentException("Device has no HID interface");
        else if (this.epIn == null)
            throw new IllegalArgumentException("Device has no INTERRUPT IN endpoint (type USB_ENDPOINT_XFER_INT, direction USB_DIR_IN");

        this.manager = (UsbManager) context.getSystemService(Context.USB_SERVICE);
        this.connection = manager.openDevice(device);
        if (!connection.claimInterface(ifHid, true))
            throw new IOException("Failed to claim HID interface");
    }

    public int getFeatureReport(int reportId, byte[] data, int length) {
        if ((reportId & 0xFF) != reportId)
            throw new IllegalArgumentException("reportId may only set the lowest 8 bits");
        return connection.controlTransfer(
                UsbConstants.USB_DIR_IN | UsbConstants.USB_TYPE_CLASS | UsbConstants.USB_INTERFACE_SUBCLASS_BOOT,
                REQUEST_GET_REPORT,
                reportId | REPORT_TYPE_OUTPUT,
                ifHid.getId(), data, length, 0);
    }

    public int read(byte[] data, int length) {
        return connection.bulkTransfer(epIn, data, length, 0);
    }

    public int sendFeatureReport(int reportId, byte[] data, int length) {
        if ((reportId & 0xFF) != reportId)
            throw new IllegalArgumentException("reportId may only set the lowest 8 bits");
        return connection.controlTransfer(
                UsbConstants.USB_DIR_OUT | UsbConstants.USB_TYPE_CLASS | UsbConstants.USB_INTERFACE_SUBCLASS_BOOT,
                REQUEST_SET_REPORT,
                reportId | REPORT_TYPE_INPUT,
                ifHid.getId(), data, length, 0);
    }
}

请注意,与 HIDAPI 不同,Android 在发送或查询功能报告时有一个单独的报告编号参数。您不需要用它预先填充数据数组。但是,当返回结果时,结果数组的第一个元素是报告编号。

对于高级内容,请查看 Linux driver . hid_open()对应的是HidDevice的构造函数,剩下的就简单了。

请注意,在将来自 byte[] 数组的数据拼凑在一起时,Java 中缺少无符号整数类型可能会产生不需要的副作用。解决方法是使用 (data[i] & 0xFF) 而不是 data[i]

音频不通过此 channel 传输——加密狗为此实现了一个单独的音频设备,这似乎是一个标准的 Linux 音频设备。不过,没有这方面的经验(对于我的项目,我只需要 RDS 数据)。

关于Android USB 主机,3.2,HID 报告获取/设置,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8413260/

相关文章:

android - 在另一个 XML 布局文件中包含现有的 XML 布局文件

android - Termux - 对 USB 笔式驱动器的写入权限

tomcat - 如何启用 tomcat 主机管理器 storeconfig?

c - 打印 inet_ntoa 函数中的段错误

javascript - 是否可以托管在一个文档中编码的网站?

java - 无法在 Android App 中实例化类

java - gridview 项目之间的完美线性间距

Android USB HID 设备

python - 在 Linux 中编写 USB 设备挂载脚本的更好方法

objective-c - 使用 ORSSerialPort 的 arduino/mac 通信问题