我有一个Android应用程序,需要检测USB外围设备何时连接或分离。首次连接外围设备时它可以正常工作,但是当它随后被分离时,我没有收到任何通知(即,我没有收到Intent
的动作为ACTION_USB_DEVICE_DETACHED
)。
以下是我AndroidManifest.xml
的相关部分:
<activity android:name=".LauncherActivity">
<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/device_filter" />
<meta-data android:name="android.hardware.usb.action.USB_DEVICE_DETACHED" android:resource="@xml/device_filter" />
</activity>
值得注意的是,LauncherActivity
仅在连接设备时启动Service
,并在分离时停止服务。在任何一种情况下,LauncherActivity
都会立即finish
。所有这些都发生在LauncherActivity.onCreate
。
有什么想法吗?
答案 0 :(得分:13)
USB_DEVICE_DETACHED是一个广播意图,因此您可能希望在清单中声明BroadcastReceiver,并使用适当的intent-filter进行分离操作,同时附加元数据。 对于感兴趣的人,USB_ACCESSORY_DETACHED也是如此。
要点:
USB_XXX_ATTACHED 是活动意图
USB_XXX_DETACHED 是广播意图
(其中XXX = DEVICE | ACCESSORY)
请参阅:http://developer.android.com/guide/components/intents-filters.html
“这些消息传递系统中没有重叠:广播意图仅传递给广播接收者,而不传递给活动或服务”
答案 1 :(得分:8)
尝试使用USB_STATE,如下所示。
它会同时接收和分离到同一个接收器和接收器,你可以识别是附加还是分离事件。
IntentFilter filter = new IntentFilter();
filter.addAction("android.hardware.usb.action.USB_STATE");
接收器:
public class USBReceiver extends BroadcastReceiver {
public void onReceive(Context context, Intent intent) {
if (intent.getExtras().getBoolean("connected")) {
//do your stuff
}
}
}
答案 2 :(得分:4)
所以,我从未让ACTION_USB_DEVICE_DETACHED
Intent
转到LauncherActivity
;我不知道那里有什么交易,可能是我没有正确理解意图过滤器或Activity
生命周期回调。
我最终使用的解决方案来自Pratik链接的帖子。我基本上从USB_DEVICE_DETACHED
中取出AndroidManifest.xml
的所有内容。然后,在onCreate
的{{1}}方法中,我注册了Service
,如下所示:
BroadcastReceiver
有点笨重,我仍然很好奇为什么只将@Override
public void onCreate() {
detachReceiver = new BroadcastReceiver() {
public void onReceive(Context context, Intent intent) {
if(intent.getAction().equals(UsbManager.ACTION_USB_DEVICE_DETACHED))
stopSelf();
}
};
IntentFilter filter = new IntentFilter();
filter.addAction(UsbManager.ACTION_USB_DEVICE_DETACHED);
registerReceiver(detachReceiver, filter);
}
添加到USB_DEVICE_DETACHED
的{{1}}无法正常工作,但它能满足我的需求。
答案 3 :(得分:0)
对于它的价值,我遇到了同样的问题,因为活动暂停,然后在设备断开连接时恢复。
由于在收到OnPause()
之前,ACTION_USB_DEVICE_DETACHED
方法中的接收方未注册,因此您的应用永远不会得到通知。
答案 4 :(得分:0)
对我有用的修正方法是在onPause()
取消注册,然后再次在onResume()
注册:
@Override
public void onPause()
{
super.onPause();
stopIOManager();
if(m_UsbReceiver!=null) unregisterReceiver(m_UsbReceiver);
}
@Override
public void onResume()
{
super.onResume();
startIOManager();
IntentFilter filter = new IntentFilter(ACTION_USB_PERMISSION);
filter.addAction(UsbManager.ACTION_USB_DEVICE_ATTACHED);
filter.addAction(UsbManager.ACTION_USB_DEVICE_DETACHED);
registerReceiver(m_UsbReceiver, filter);
}
然而,尽管应用程序似乎总是收到DETACH事件,但偶尔它不会获得ATTACHED事件。然后,我需要插入并拔下USB连接器,它通常在一两次尝试后工作。我毫不确定地将这种奇怪的行为归咎于操作系统。