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

相关推荐
android_xc3 小时前
Android Studio国内仓库配置
android·ide·android studio
alexhilton3 小时前
runBlocking实践:哪里该使用,哪里不该用
android·kotlin·android jetpack
2501_915106324 小时前
iOS 使用记录和能耗监控实战,如何查看电池电量消耗、App 使用时长与性能数据(uni-app 开发调试必备指南)
android·ios·小程序·uni-app·cocoa·iphone·webview
雨白4 小时前
深入解析 Android 多点触摸:从原理到实战
android
曾经的三心草5 小时前
Python2-工具安装使用-anaconda-jupyter-PyCharm-Matplotlib
android·java·服务器
Jerry6 小时前
Compose 设置文字样式
android
飞猿_SIR6 小时前
android定制系统完全解除应用安装限制
android
索迪迈科技7 小时前
影视APP源码 SK影视 安卓+苹果双端APP 反编译详细视频教程+源码
android·影视app源码·sk影视
孔丘闻言7 小时前
python调用mysql
android·python·mysql
萧雾宇9 小时前
Android Compose打造仿现实逼真的烟花特效
android·flutter·kotlin