Я только что получил USB-ключ Si470x для работы на Android.Я решил часть HID, написав небольшой класс-оболочку для вызовов Android:
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 .hid_open()
соответствует конструктору HidDevice
, остальное должно быть простым.
Имейте в виду, что отсутствие целочисленных типов без знака в Java может иметь нежелательные побочные эффекты при объединении данных из массива byte[]
,Обходной путь должен использовать (data[i] & 0xFF)
вместо data[i]
.
Аудио не передается по этому каналу - ключ использует отдельное аудиоустройство для этого, которое кажется стандартным аудиоустройством Linux.Впрочем, опыта в этом нет (для моего проекта мне нужны только данные RDS).