2013-04-02 57 views
6

我有一个Android应用程序需要检测何时USB外设已连接或分离。当外设首次连接时它可以正常工作,但是当它随后被分离时,我没有收到任何通知(即,我没有收到其行为是ACTION_USB_DEVICE_DETACHEDIntent)。检测Android设备上的USB设备何时分离

这里是我的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

嗨看看这篇文章http://stackoverflow.com/a/9814826/760489 – Pratik

回答

10

USB_DEVICE_DETACHED是一个广播意图,因此您可能希望声明BroadcastReceiver清单与适当的意图过滤器分离行动,也与附加的元数据。 USB_ACCESSORY_DETACHED同样适用于感兴趣的人。

总结:
USB_XXX_ATTACHED是一种活动意图
USB_XXX_DETACHED是广播意图

(其中XXX = DEVICE | ACCESSORY)

参见:http://developer.android.com/guide/components/intents-filters.html

“有这些消息系统中没有重叠:广播意图仅传送给广播接收者,从来没有活动或服务“

+0

这是不正确的。 'DEVICE'动作都是广播。对于'ACCESSORY',附件是一个活动动作,但是在广播动作中被分离。 –

+0

USB_XXX_ATTACHED意图也可以用作广播意图,我试了一下,它对我来说工作得很好。 –

3

所以,我从来没有得到ACTION_USB_DEVICE_DETACHEDIntentLauncherActivity;我不知道那里有什么交易,可能是我没有正确理解意向过滤器或生命周期回调。

我最终使用的解决方案来自Pratik链接的帖子。我基本上把所有关于USB_DEVICE_DETACHED的内容全部从AndroidManifest.xml中删除。然后,在ServiceonCreate方法,我注册了一个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_DETACHEDLauncherActivity<intent-filter>没有工作,但它做我所需要的。

+0

伟大的作品。我的诀窍是从AndroidManifest.xml中移除USB_DEVICE_DETACHED。 – Frank

6

尝试使用USB_STATE如下。

它会触发连接和分离到相同的接收器,并在接收器中,您可以识别是否是连接或detatched事件。

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 
     } 
    } 
} 
+0

工程就像一个魅力!谢谢 –

+0

谢谢。但我总是得到错误。我会检查它。 – Herman

0

对于它的价值,我有同样的问题,因为活动被暂停则当设备断开连接恢复。
由于在收到ACTION_USB_DEVICE_DETACHED之前接收方在OnPause()方法中未注册,因此您的应用永远不会收到通知。

+0

如果您发布了解决此问题的方法,那将会非常棒。 –

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); 
} 

然而,尽管应用程序似乎是一个始终接收分离事件,一次是当它没有得到ATTACHED事件。然后,我需要插入并拔出USB连接器,并且通常在一次或两次尝试后运行。我毫无把握地将这种奇怪行为归咎于操作系统。