在 Android 上枚舉 USB 設備除了使用?UsbManager.getDeviceList()
?方法外,還有以下幾種常見的方式:
1.?使用 USB 設備過濾器(XML 配置)
通過在 AndroidManifest.xml 中配置 USB 設備過濾器,可以讓系統自動檢測并通知應用匹配的 USB 設備。
步驟:
- 創建 USB 設備過濾器 XML 文件(例如?
res/xml/usb_device_filter.xml
):
-
<?xml version="1.0" encoding="utf-8"?> <resources><usb-device vendor-id="1234" product-id="5678" /> <!-- 指定具體 VID/PID --><!-- 或使用通配符匹配所有設備 --><!-- <usb-device /> --> </resources>
- 在 AndroidManifest.xml 中聲明過濾器:
-
<activity android:name=".UsbDeviceActivity"><intent-filter><action android:name="android.hardware.usb.action.USB_DEVICE_ATTACHED" /></intent-filter><meta-dataandroid:name="android.hardware.usb.action.USB_DEVICE_ATTACHED"android:resource="@xml/usb_device_filter" /> </activity>
- 在 Activity 中處理 USB 設備連接:
@Override
protected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);Intent intent = getIntent();String action = intent.getAction();if (UsbManager.ACTION_USB_DEVICE_ATTACHED.equals(action)) {UsbDevice device = intent.getParcelableExtra(UsbManager.EXTRA_DEVICE);if (device != null) {// 處理連接的 USB 設備}}
}
2.?使用廣播接收器監聽 USB 設備插拔事件
通過注冊廣播接收器,可以實時監聽 USB 設備的插入和拔出事件。
示例代碼:
// 注冊廣播接收器
private final BroadcastReceiver usbReceiver = new BroadcastReceiver() {@Overridepublic void onReceive(Context context, Intent intent) {String action = intent.getAction();if (UsbManager.ACTION_USB_DEVICE_ATTACHED.equals(action)) {UsbDevice device = intent.getParcelableExtra(UsbManager.EXTRA_DEVICE);if (device != null) {// 處理新連接的 USB 設備}} else if (UsbManager.ACTION_USB_DEVICE_DETACHED.equals(action)) {UsbDevice device = intent.getParcelableExtra(UsbManager.EXTRA_DEVICE);if (device != null) {// 處理斷開連接的 USB 設備}}}
};// 注冊廣播接收器
IntentFilter filter = new IntentFilter();
filter.addAction(UsbManager.ACTION_USB_DEVICE_ATTACHED);
filter.addAction(UsbManager.ACTION_USB_DEVICE_DETACHED);
registerReceiver(usbReceiver, filter);// 記得在 Activity 銷毀時取消注冊
@Override
protected void onDestroy() {super.onDestroy();unregisterReceiver(usbReceiver);
}
3.?使用 Android USB Host API(API 級別 12+)
通過 USB Host API,可以主動枚舉和管理連接的 USB 設備。
示例代碼:
UsbManager usbManager = (UsbManager) getSystemService(Context.USB_SERVICE);
HashMap<String, UsbDevice> deviceList = usbManager.getDeviceList();// 遍歷設備列表
for (UsbDevice device : deviceList.values()) {Log.d(TAG, "Device: " + device.getProductId() + ", VID: " + device.getVendorId());// 請求設備權限PendingIntent permissionIntent = PendingIntent.getBroadcast(this, 0, new Intent(ACTION_USB_PERMISSION), PendingIntent.FLAG_IMMUTABLE);usbManager.requestPermission(device, permissionIntent);
}
4.?使用 USB 設備類過濾
可以根據設備類(如 HID、CDC、MIDI 等)來過濾和枚舉特定類型的 USB 設備。
示例代碼:
for (UsbDevice device : deviceList.values()) {// 獲取設備類int deviceClass = device.getDeviceClass();// 根據設備類過濾(例如,查找 HID 設備)if (deviceClass == UsbConstants.USB_CLASS_HID) {// 處理 HID 設備}
}
5.?使用 USB 設備接口過濾
通過檢查設備的接口(Interface)和端點(Endpoint),可以進一步篩選出符合條件的 USB 設備。
示例代碼:
for (UsbDevice device : deviceList.values()) {// 遍歷設備的所有接口for (int i = 0; i < device.getInterfaceCount(); i++) {UsbInterface usbInterface = device.getInterface(i);// 根據接口類過濾(例如,查找串口設備)if (usbInterface.getInterfaceClass() == UsbConstants.USB_CLASS_CDC_DATA) {// 處理 CDC 數據接口}}
}
6.?使用 USB 設備權限管理
在訪問 USB 設備前,需要獲取用戶權限:
private static final String ACTION_USB_PERMISSION = "com.example.USB_PERMISSION";// 請求權限
PendingIntent permissionIntent = PendingIntent.getBroadcast(this, 0, new Intent(ACTION_USB_PERMISSION), PendingIntent.FLAG_IMMUTABLE);
usbManager.requestPermission(device, permissionIntent);// 處理權限回調
private final BroadcastReceiver permissionReceiver = new BroadcastReceiver() {@Overridepublic void onReceive(Context context, Intent intent) {String action = intent.getAction();if (ACTION_USB_PERMISSION.equals(action)) {synchronized (this) {UsbDevice device = intent.getParcelableExtra(UsbManager.EXTRA_DEVICE);if (intent.getBooleanExtra(UsbManager.EXTRA_PERMISSION_GRANTED, false)) {if (device != null) {// 權限已授予,可以訪問設備}} else {Log.e(TAG, "USB 權限被拒絕");}}}}
};
總結
以上方法各有適用場景:
- XML 過濾器:適合靜態匹配特定 VID/PID 的設備。
- 廣播接收器:適合實時監聽設備插拔事件。
- USB Host API:適合主動枚舉和管理設備。
- 設備類 / 接口過濾:適合篩選特定類型的 USB 設備。
實際開發中,通常需要結合多種方法來實現完整的 USB 設備管理功能。