2017-06-02 135 views
1

我正嘗試在Android上與USB OTG設備進行連接。由於代碼是一個有點冗長,我只概述基礎:USB OTG設備在拔出並重新插入後不起作用

  • 有與USB_DEVICE_ATTACHED(過濾的設備ID我感興趣的)意圖過濾器的活動在清單中聲明。
  • 當活動以該特定意圖啓動時,它啓動服務並將USB設備作爲參數傳遞。
  • 當服務啓動時,它爲USB_DEVICE_DETACHED註冊廣播接收器,然後連接到設備並開始與它進行交互(當前生成一些日誌輸出)。
  • 當收到USB斷開廣播時設備是當前正在使用的設備,在USB設備連接上調用close()並停止服務。

該設備是一個Si4701 USB FM調諧器,它表現爲USB HID設備。

當我第一次插入設備時,我看到我的服務連接到它,可以更換頻道並接收RDS數據。但是,當我拔下插頭並重新插入時,我看到服務再次連接到它(並且顯然已成功讀取設備寄存器),但它無法更改頻率,並且我從未看到任何RDS數據。

如果我強迫應用拔出並重新插入設備之間的停止,該設備在geing插回後正常工作。

這表明一些清理工作無法進行,或者一些資源沒有被正確釋放。但是:

  • 我不保留任何數據結構與設備之間的連接。與USB連接相關的所有內容都是在檢測到設備時創建的類實例中,並且這些類的所有靜態成員都是最終的。
  • 有些東西在重新插入設備後有效,例如讀取設備類型和固件版本的寄存器(通過獲取USB HID功能報告來工作)。初始化還會設置一些寄存器(通過發送USB特性報告),該寄存器不會返回錯誤 - 但頻率變化(也涉及設置寄存器)不起作用。
  • 拔出和重新插入之間約15分鐘的間隔不起作用(設備不起作用)。另一方面,如果我拔掉設備,殺掉服務並重新插入服務器,它會立即生效 - 所以問題肯定在Android端,而不是在設備端。

我需要做些什麼才能使USB設備在拔出/重新接通循環後工作?

回答

0

我還沒有完全理解這裏發生了什麼,但它現在似乎工作。

我應該提到該應用程序是多線程的,並且Si470x封裝類正在從多線程中調用。

由於這導致競爭條件(一個線程在另一個線程關閉時訪問設備),我正確地聲明所有方法爲​​,以便兩個線程不能同時訪問tuner類的方法。將設備插入,拔出插頭,插入並觀察,它會改變頻率並按照預期的方式吐出RDS數據。

懷疑:

UsbDeviceConnection#close()可能不是線程安全的。

結論:

  • 總是調用UsbDeviceConnection#close()當你與設備(包括當設備斷開)來完成。
  • 如果您的應用程序是多線程的,請確保訪問USB連接(直接或間接)的所有內容都已正確同步。