android实现USB通讯

在 Android 上枚举 USB 设备除了使用 UsbManager.getDeviceList() 方法外,还有以下几种常见的方式:

1. 使用 USB 设备过滤器(XML 配置)

通过在 AndroidManifest.xml 中配置 USB 设备过滤器,可以让系统自动检测并通知应用匹配的 USB 设备。

步骤:

  1. 创建 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>
  1. 在 AndroidManifest.xml 中声明过滤器
复制代码
   <activity android:name=".UsbDeviceActivity">
       <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/usb_device_filter" />
   </activity>
  1. 在 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() {
    @Override
    public 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() {
    @Override
    public 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 设备管理功能。

相关推荐
是店小二呀1 小时前
【优选算法 | 字符串】字符串模拟题精选:思维+实现解析
android·c++·算法
奔跑吧 android3 小时前
【android bluetooth 协议分析 12】【A2DP详解 1】【车机侧蓝牙音乐免切源介绍】
android·bluetooth·bt·gd·a2dpsink·免切源·aosp14
飞猿_SIR3 小时前
Android Exoplayer多路不同时长音视频混合播放
android·音视频
jiet_h5 小时前
Android锁
android
teacher伟大光荣且正确13 小时前
Qt Creator 配置 Android 编译环境
android·开发语言·qt
飞猿_SIR16 小时前
Android Exoplayer 实现多个音视频文件混合播放以及音轨切换
android·音视频
HumoChen9916 小时前
GZip+Base64压缩字符串在ios上解压报错问题解决(安卓、PC模拟器正常)
android·小程序·uniapp·base64·gzip
沙振宇20 小时前
【HarmonyOS】ArkTS开发应用的横竖屏切换
android·华为·harmonyos
橙子199110161 天前
Kotlin 中的作用域函数
android·开发语言·kotlin