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

Android应用无法接收UsbManager.ACTION_USB_DEVICE_DETACHED事件求助

问题分析与解决方案

核心问题

Android系统对USB_DEVICE_DETACHED事件的处理逻辑和USB_DEVICE_ATTACHED不同:

  • USB_DEVICE_ATTACHED可以通过Manifest中的intent-filter直接唤起Activity
  • USB_DEVICE_DETACHED仅会发送给已持有对应设备权限且动态注册了广播接收器的组件,Manifest注册的该事件intent-filter无法自动唤起Activity

解决方案:后台Service监听+动态广播

通过后台Service持续监听USB分离事件,收到事件后主动唤起SetupPrinterActivity,具体步骤如下:

1. 调整AndroidManifest配置

移除Activity中无效的USB_DEVICE_DETACHED相关配置,新增后台Service:

<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools">

    <!-- 原有权限、Feature配置保留 -->

    <application>
        <!-- 修改SetupPrinterActivity配置 -->
        <activity
            android:name=".ui.setupprinter.SetupPrinterActivity"
            android:exported="true"
            android:launchMode="singleInstance"
            android:screenOrientation="landscape"
            android:theme="@style/Theme.MyApp.NoActionBar">

            <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/device_filter" />
        </activity>

        <!-- 添加USB监控Service -->
        <service
            android:name=".service.USBMonitorService"
            android:exported="false"
            android:foregroundServiceType="specialUse" />
    </application>
</manifest>

2. 创建USB监控Service

实现后台监听USB分离事件的Service:

class USBMonitorService : Service() {
    private lateinit var usbReceiver: BroadcastReceiver
    private lateinit var usbManager: UsbManager

    override fun onCreate() {
        super.onCreate()
        usbManager = getSystemService(USB_SERVICE) as UsbManager
        initReceiver()
        // 可选:启动为前台服务,避免被系统后台回收
        startForeground(1, NotificationCompat.Builder(this, "USB_MONITOR_CHANNEL")
            .setContentTitle("USB设备监控")
            .setContentText("正在监听USB状态变化")
            .setSmallIcon(R.mipmap.ic_launcher)
            .build())
    }

    private fun initReceiver() {
        usbReceiver = object : BroadcastReceiver() {
            override fun onReceive(context: Context?, intent: Intent?) {
                when (intent?.action) {
                    UsbManager.ACTION_USB_DEVICE_DETACHED -> {
                        val device = intent.getParcelableExtra<UsbDevice>(UsbManager.EXTRA_DEVICE)
                        device?.let {
                            // 唤起SetupPrinterActivity
                            val launchIntent = Intent(context, SetupPrinterActivity::class.java).apply {
                                flags = Intent.FLAG_ACTIVITY_NEW_TASK or Intent.FLAG_ACTIVITY_SINGLE_TOP
                            }
                            context?.startActivity(launchIntent)
                        }
                    }
                }
            }
        }

        val filter = IntentFilter().apply {
            addAction(UsbManager.ACTION_USB_DEVICE_DETACHED)
        }
        registerReceiver(usbReceiver, filter)
    }

    override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int {
        return START_STICKY // 服务被系统杀死后自动重启
    }

    override fun onDestroy() {
        super.onDestroy()
        unregisterReceiver(usbReceiver)
    }

    override fun onBind(intent: Intent?): IBinder? {
        return null
    }
}

3. 在SetupPrinterActivity中启动Service

确保USB设备连接后启动监控Service,同时处理权限请求(必须持有设备权限才能收到分离事件):

class SetupPrinterActivity : AppCompatActivity() {
    private lateinit var usbManager: UsbManager
    private var usbReceiver: BroadcastReceiver? = null
    private val permissionReceiver = object : BroadcastReceiver() {
        override fun onReceive(context: Context?, intent: Intent?) {
            if ("com.your.package.USB_PERMISSION" == intent?.action) {
                val device = intent.getParcelableExtra<UsbDevice>(UsbManager.EXTRA_DEVICE)
                if (intent.getBooleanExtra(UsbManager.EXTRA_PERMISSION_GRANTED, false)) {
                    device?.let {
                        // 权限获取成功,启动监控服务
                        startService(Intent(context, USBMonitorService::class.java))
                        onUSBAttach(it.deviceName)
                    }
                }
            }
        }
    }

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        usbManager = getSystemService(USB_SERVICE) as UsbManager
        initReceiver()
        registerReceiver(permissionReceiver, IntentFilter("com.your.package.USB_PERMISSION"))

        // 处理USB设备连接事件的权限请求
        intent.getParcelableExtra<UsbDevice>(UsbManager.EXTRA_DEVICE)?.let { device ->
            val permissionIntent = PendingIntent.getBroadcast(this, 0, 
                Intent("com.your.package.USB_PERMISSION"), PendingIntent.FLAG_IMMUTABLE)
            usbManager.requestPermission(device, permissionIntent)
        }
    }

    // 原有initReceiver方法保留,仅处理Activity存活时的事件回调
    private fun initReceiver() {
        usbReceiver = object : BroadcastReceiver() {
            override fun onReceive(context: Context?, intent: Intent?) {
                try {
                    when (intent?.action) {
                        UsbManager.ACTION_USB_DEVICE_ATTACHED -> {
                            val device = intent.getParcelableExtra<UsbDevice>(UsbManager.EXTRA_DEVICE)
                            device?.let { onUSBAttach(it.deviceName) }
                        }
                        UsbManager.ACTION_USB_DEVICE_DETACHED -> {
                            val device = intent.getParcelableExtra<UsbDevice>(UsbManager.EXTRA_DEVICE)
                            device?.let { onUSBDetach(it.deviceName) }
                        }
                    }
                } catch (e: Exception) {
                    Log.e("CHKI", "BroadcastReceiver异常: ${e.message}")
                    e.printStackTrace()
                }
            }
        }

        val filter = IntentFilter().apply {
            addAction(UsbManager.ACTION_USB_DEVICE_ATTACHED)
            addAction(UsbManager.ACTION_USB_DEVICE_DETACHED)
        }
        registerReceiver(usbReceiver, filter)
    }

    override fun onDestroy() {
        super.onDestroy()
        usbReceiver?.let { unregisterReceiver(it) }
        unregisterReceiver(permissionReceiver)
    }

    // 原有onUSBAttach、onUSBDetach方法保留
    private fun onUSBAttach(deviceName: String) { /* ... */ }
    private fun onUSBDetach(deviceName: String) { /* ... */ }
}

关键说明

  • 必须获取对应USB设备的访问权限,否则Service无法收到该设备的USB_DEVICE_DETACHED广播
  • 前台服务模式可根据需求调整,若不需要持续监控,可在设备分离后停止服务
  • 启动Activity时使用FLAG_ACTIVITY_NEW_TASK和FLAG_ACTIVITY_SINGLE_TOP确保页面正确唤起且不重复创建

内容的提问来源于stack exchange,提问作者ankushlokhande

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.04 06:25:01