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

相关推荐
q***577436 分钟前
MySql的慢查询(慢日志)
android·mysql·adb
JavaNoober1 小时前
Android 前台服务 "Bad Notification" 崩溃机制分析文档
android
城东米粉儿2 小时前
关于ObjectAnimator
android
zhangphil3 小时前
Android渲染线程Render Thread的RenderNode与DisplayList,引用Bitmap及Open GL纹理上传GPU
android
火柴就是我4 小时前
从头写一个自己的app
android·前端·flutter
lichong9515 小时前
XLog debug 开启打印日志,release 关闭打印日志
android·java·前端
用户69371750013845 小时前
14.Kotlin 类:类的形态(一):抽象类 (Abstract Class)
android·后端·kotlin
火柴就是我5 小时前
NekoBoxForAndroid 编译libcore.aar
android
Kaede66 小时前
MySQL中如何使用命令行修改root密码
android·mysql·adb
明君879978 小时前
Flutter 图纸标注功能的实现:踩坑与架构设计
android·ios