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 设备管理功能。

相关推荐
xzkyd outpaper24 分钟前
onSaveInstanceState() 和 ViewModel 在数据保存能力差异
android·计算机八股
CYRUS STUDIO2 小时前
FART 脱壳某大厂 App + CodeItem 修复 dex + 反编译还原源码
android·安全·逆向·app加固·fart·脱壳
WAsbry2 小时前
现代 Android 开发自定义主题实战指南
android·kotlin·material design
xzkyd outpaper2 小时前
Android动态广播注册收发原理
android·计算机八股
唐墨1232 小时前
android与Qt类比
android·开发语言·qt
林林要一直努力3 小时前
Android Studio 向模拟器手机添加照片、视频、音乐
android·智能手机·android studio
AD钙奶-lalala3 小时前
Mac版本Android Studio配置LeetCode插件
android·ide·android studio
散人10245 小时前
Android Test3 获取的ANDROID_ID值不同
android·unit testing
雨白5 小时前
实现动态加载布局
android
帅得不敢出门5 小时前
Android设备推送traceroute命令进行网络诊断
android·网络