2013-04-02 239 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連接器,並且通常在一次或兩次嘗試後運行。我毫無把握地將這種奇怪行爲歸咎於操作系統。