Suatu hari, saya membutuhkan satu perangkat yang dikendalikan melalui USB dari program desktop untuk juga dikontrol melalui aplikasi Android. Keunikannya adalah bahwa HID, CDC dan kelas perangkat standar lainnya tidak digunakan. Transfer data dilakukan melalui transfer Massal dan titik akhir. Dasar bekerja dengan usb adalah perpustakaan libusb.
Kami akan membuat aplikasi pengujian yang memungkinkan untuk mentransfer dan menerima data sewenang-wenang dari perangkat.
Saya akan menyentuh pada poin-poin penting, dan tautan ke kode lengkap akan ada di akhir.
Untuk memulainya, kami bertindak sesuai dengan dokumentasi resmi untuk bekerja dengan UsbHost.
Tambahkan baris ke manifes
<uses-feature android:name="android.hardware.usb.host"/>
Jika kita ingin perangkat terdeteksi secara otomatis dan aplikasi dimulai, maka dalam manifes untuk aktivitas utama kita menulis yang berikut ini.
<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"/>
Tentukan untuk perangkat kami VID dan PID-nya di file dengan resources device_filter.xml
<resources> <usb-device product-id="0037" vendor-id="8742"/> </resources>
Kami mendapatkan manajer usb dalam metode onCreate.
mUsbManager = (UsbManager) getSystemService(Context.USB_SERVICE)
Selanjutnya, kita mendapatkan daftar perangkat yang terhubung ke USB, dan di antaranya kita mencari perangkat kelas USB_CLASS_PER_INTERFACE yang kita butuhkan.
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; }
Selanjutnya, kita menemukan antarmuka yang kita butuhkan, jangan lupa untuk memeriksa izin, beralih ke semua titik kontrolnya, di antaranya kita pilih titik baca dan tulis, dan akhirnya terhubung.
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(); }
Untuk bekerja dengan I / O, buffering data, asinkron, dan hal-hal praktis lainnya, kelas manajer tambahan digunakan, tetapi pada dasarnya, pertukaran data dikurangi menjadi kode berikut.
Membaca:
mConnection.bulkTransfer(mInEndpoint, data, size, READ_TIMEOUT);
Rekam:
int bytesWritten = mConnection.bulkTransfer(mOutEndpoint, Arrays.copyOfRange(data, offset, offset + size), size, WRITE_TIMEOUT);
Dengan cara ini, paket-paket BulkTransfer ditransmisikan dan diterima.
Akibatnya, aplikasi sederhana kami dapat mengirim dan menerima data sewenang-wenang.


Itu berhasil!
Proyek
aplikasi tes ini
di GitHubTautan yang bermanfaat:
- Perpustakaan untuk bekerja dengan FT232 dan perangkat CDC lainnya di Android.
- Dokumentasi Android resmi untuk bekerja dengan UsbHost.