You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Android USB_STATE广播检测异常:连接断开均提示设备已断开

USB设备连接/断开状态检测异常问题排查

我使用以下代码检测USB设备的连接与断开状态:

IntentFilter filter = new IntentFilter();
filter.addAction("android.hardware.usb.action.USB_STATE");
context.registerReceiver(new BroadcastReceiver() {
    @Override
    public void onReceive(Context context, Intent intent) {
        String action = intent.getAction();
        if(action.equalsIgnoreCase("android.hardware.usb.action.USB_STATE")) {
            //Check if change in USB state
            if (intent.getExtras().getBoolean("connected")) {
                Toast.makeText(context, "connect USB", Toast.LENGTH_SHORT).show();
            } else {
                Toast.makeText(context, "Disconnect!", Toast.LENGTH_SHORT).show();
            }
        }
    }
}, filter);

但连接数码钢琴键盘后再断开,两种操作均提示“Disconnect!”,请问问题出在哪里?


问题原因

android.hardware.usb.action.USB_STATE 广播的connected字段,仅标识USB数据连接状态(比如USB调试、MTP文件传输这类数据交互场景),而非USB设备的物理连接状态。数码钢琴属于USB HID类设备(输入设备),连接后不会触发系统的USB数据连接状态变更,因此无论设备连接还是断开,connected字段始终返回false,导致你看到统一的“Disconnect!”提示。

解决方案

要检测USB HID设备(如数码钢琴键盘)的物理连接/断开,需使用专门的设备插拔广播:android.hardware.usb.action.USB_DEVICE_ATTACHED 和 android.hardware.usb.action.USB_DEVICE_DETACHED,具体实现步骤如下:

1. 配置Manifest权限与广播接收器

在AndroidManifest.xml中添加USB相关权限及静态广播注册:

<uses-feature android:name="android.hardware.usb.host" />
<uses-permission android:name="android.permission.USB_PERMISSION" />

<receiver android:name=".UsbDeviceReceiver">
    <intent-filter>
        <action android:name="android.hardware.usb.action.USB_DEVICE_ATTACHED" />
        <action android:name="android.hardware.usb.action.USB_DEVICE_DETACHED" />
    </intent-filter>
    <meta-data
        android:name="android.hardware.usb.action.USB_DEVICE_ATTACHED"
        android:resource="@xml/usb_device_filter" />
</receiver>

2. 创建设备过滤规则

在res/xml目录下新建usb_device_filter.xml,配置你的数码钢琴的VID(厂商ID)和PID(产品ID),可通过adb shell dumpsys usb命令查看设备的VID/PID:

<?xml version="1.0" encoding="utf-8"?>
<resources>
    <usb-device vendor-id="你的设备VID" product-id="你的设备PID" />
</resources>

3. 编写广播接收器代码

实现自定义广播接收器处理设备插拔事件:

public class UsbDeviceReceiver extends BroadcastReceiver {
    @Override
    public void onReceive(Context context, Intent intent) {
        String action = intent.getAction();
        if (action == null) return;
        
        switch (action) {
            case UsbManager.ACTION_USB_DEVICE_ATTACHED:
                Toast.makeText(context, "USB设备已连接", Toast.LENGTH_SHORT).show();
                break;
            case UsbManager.ACTION_USB_DEVICE_DETACHED:
                Toast.makeText(context, "USB设备已断开", Toast.LENGTH_SHORT).show();
                break;
        }
    }
}

如果偏好动态注册广播(适合临时监听场景),可在Activity/Fragment中添加如下代码,但需注意动态注册的广播在App退至后台时可能被系统回收:

IntentFilter filter = new IntentFilter();
filter.addAction(UsbManager.ACTION_USB_DEVICE_ATTACHED);
filter.addAction(UsbManager.ACTION_USB_DEVICE_DETACHED);
registerReceiver(new UsbDeviceReceiver(), filter);

内容的提问来源于stack exchange,提问作者M. Feyz

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.13 17:33:17