Um dia, eu precisava de um dispositivo controlado via USB a partir de um programa de desktop para também ser controlado por um aplicativo Android. A peculiaridade foi que o HID, CDC e outras classes de dispositivos padrão não foram utilizados. A transferência de dados foi realizada por meio de transferência em massa e endpoints. A base do trabalho com o usb foi a biblioteca libusb.
Criaremos um aplicativo de teste com o qual será possível transferir e receber dados arbitrários do dispositivo.
Vou tocar nos pontos principais, e o link para o código completo estará no final.
Para começar, agimos de acordo com a documentação oficial para trabalhar com o UsbHost.
Adicionar uma linha ao manifesto
<uses-feature android:name="android.hardware.usb.host"/>
Se queremos que o dispositivo seja detectado automaticamente e o aplicativo inicie, no manifesto da atividade principal, escrevemos o seguinte.
<intent-filter> <action android:name="android.hardware.usb.action.USB_DEVICE_ATTACHED"/> </intent-filter> <meta-data android:name="android.hardware.usb.action.USB_DEVICE_ATTACHED" android:resource="@xml/device_filter"/>
Especifique para o nosso dispositivo seu VID e PID no arquivo com recursos device_filter.xml
<resources> <usb-device product-id="0037" vendor-id="8742"/> </resources>
Obtemos o gerenciador usb no método onCreate.
mUsbManager = (UsbManager) getSystemService(Context.USB_SERVICE)
Em seguida, obtemos uma lista de dispositivos conectados ao USB e, entre eles, procuramos um dispositivo da classe USB_CLASS_PER_INTERFACE que precisamos.
UsbDevice findDevice(UsbManager usbManager) { for (UsbDevice usbDevice : usbManager.getDeviceList().values()) { if (usbDevice.getDeviceClass() == UsbConstants.USB_CLASS_PER_INTERFACE) { return usbDevice; } else { UsbInterface usbInterface = findInterface(usbDevice); if (usbInterface != null) return usbDevice; } } return null; } UsbInterface findInterface(UsbDevice usbDevice) { for (int nIf = 0; nIf < usbDevice.getInterfaceCount(); nIf++) { UsbInterface usbInterface = usbDevice.getInterface(nIf); if (usbInterface.getInterfaceClass() == UsbConstants.USB_CLASS_PER_INTERFACE) { return usbInterface; } } return null; }
Em seguida, encontramos a interface de que precisamos, não se esqueça de verificar as permissões, iterar sobre todos os seus pontos de controle, entre eles, selecionamos os pontos de leitura e gravação e, finalmente, conectamos.
private void initUsbDevice() { PendingIntent mPermissionIntent = PendingIntent.getBroadcast(this, 0, new Intent(ACTION_USB_PERMISSION), 0); IntentFilter filter = new IntentFilter(ACTION_USB_PERMISSION); registerReceiver(mUsbReceiver, filter); mUsbManager.requestPermission(mUsbDevice, mPermissionIntent); mUsbInterface = findInterface(mUsbDevice); for (int nEp = 0; nEp < mUsbInterface.getEndpointCount(); nEp++) { UsbEndpoint tmpEndpoint = mUsbInterface.getEndpoint(nEp); if (tmpEndpoint.getType() != UsbConstants.USB_ENDPOINT_XFER_BULK) continue; if ((mOutEndpoint == null) && (tmpEndpoint.getDirection() == UsbConstants.USB_DIR_OUT)) { mOutEndpoint = tmpEndpoint; } else if ((mInEndpoint == null) && (tmpEndpoint.getDirection() == UsbConstants.USB_DIR_IN)) { mInEndpoint = tmpEndpoint; } } if (mOutEndpoint == null) { Toast.makeText(this, "no endpoints", Toast.LENGTH_LONG).show(); } mConnection = mUsbManager.openDevice(mUsbDevice); if (mConnection == null) { Toast.makeText(this, "can't open device", Toast.LENGTH_SHORT).show(); return; } mConnection.claimInterface(mUsbInterface, true); startIoManager(); }
Para trabalhar com E / S, buffer de dados, assincronia e outras coisas convenientes, uma classe de gerenciador auxiliar é usada, mas, em essência, a troca de dados é reduzida ao código a seguir.
Leitura:
mConnection.bulkTransfer(mInEndpoint, data, size, READ_TIMEOUT);
Registro:
int bytesWritten = mConnection.bulkTransfer(mOutEndpoint, Arrays.copyOfRange(data, offset, offset + size), size, WRITE_TIMEOUT);
Dessa maneira, os pacotes BulkTransfer são transmitidos e recebidos.
Como resultado, nosso aplicativo simples pode transmitir e receber dados arbitrários.


Isso funciona!
O projeto deste
aplicativo de teste no GitHubLinks úteis:
- Biblioteca para trabalhar com o FT232 e outros dispositivos CDC no Android.
- A documentação oficial do Android para trabalhar com o UsbHost.