1. 程式人生 > >Android有兩種方法檢測USB裝置插入

Android有兩種方法檢測USB裝置插入

  OTG線一條, USB介面轉換器, 可以把XOOM下面的USB口轉成USB母口,可以插USB鍵盤,Joystick之類

         PS3遊戲手柄, 測試成功的有 北通,Logitech, 手柄.

檢測手柄的插入與拔出

根據Android文件介紹, 有兩種方法檢測USB裝置插入

第一種, 在Manifest 裡面加入

<manifest<span style="COLOR: #000000"> ...</span>><span style="COLOR: #000000">
    </span><uses-feature<span style="COLOR: #000000"> </span><span style="COLOR: #882288">android:name</span>="android.hardware.usb.host"<span style="COLOR: #000000"> </span>/><span style="COLOR: #000000">
    </span><uses-sdk<span style="COLOR: #000000"> </span><span style="COLOR: #882288">android:minSdkVersion</span>="12"<span style="COLOR: #000000"> </span>/><span style="COLOR: #000000">
    ...
    </span><application><span style="COLOR: #000000">
        </span><activity<span style="COLOR: #000000"> ...</span>><span style="COLOR: #000000">
            ...
            </span><intent-filter><span style="COLOR: #000000">
                </span><action<span style="COLOR: #000000"> </span><span style="COLOR: #882288">android:name</span>="android.hardware.usb.action.USB_DEVICE_ATTACHED"<span style="COLOR: #000000"> </span>/><span style="COLOR: #000000">
            </span></intent-filter><span style="COLOR: #000000">

            </span><meta-data<span style="COLOR: #000000"> </span><span style="COLOR: #882288">android:name</span>="android.hardware.usb.action.USB_DEVICE_ATTACHED"<span style="COLOR: #000000">
                </span><span style="COLOR: #882288">android:resource</span>="@xml/device_filter"<span style="COLOR: #000000"> </span>/><span style="COLOR: #000000">
        </span></activity><span style="COLOR: #000000">
    </span></application><span style="COLOR: #000000">
</span></manifest>

對應的device_filter.mxl

<?<span style="COLOR: #000000">xml version</span>="1.0"<span style="COLOR: #000000"> encoding</span>="utf-8"?><span style="COLOR: #000000">

</span><resources><span style="COLOR: #000000">
    </span><usb-device<span style="COLOR: #000000"> </span><span style="COLOR: #882288">vendor-id</span>="1234"<span style="COLOR: #000000"> </span><span style="COLOR: #882288">product-id</span>="5678"<span style="COLOR: #000000"> </span>/><span style="COLOR: #000000">
</span></resources>

其中, vendor-id 和 product-id 每個不同型號的手柄得到的值都是不一樣的.具體獲取方法下面會提到.

做好以上配置以後, 當裝置插入的時候, 系統會彈出一個提示框, 詢問你是否要開啟這個程式.點選確定的話就會啟動你的APP.

第二種方法. 遍歷USB Device

UsbManager<span style="COLOR: #000000"> manager </span>=<span style="COLOR: #000000"> </span>(UsbManager)<span style="COLOR: #000000"> getSystemService</span>(Context.<span style="COLOR: #000000">USB_SERVICE</span>);<span style="COLOR: #000000">
</span>...<span style="COLOR: #000000">
</span>HashMap<String,<span style="COLOR: #000000"> </span>UsbDevice><span style="COLOR: #000000"> deviceList </span>=<span style="COLOR: #000000"> manager</span>.<span style="COLOR: #000000">getDeviceList</span>();<span style="COLOR: #000000">
</span>Iterator<UsbDevice><span style="COLOR: #000000"> deviceIterator </span>=<span style="COLOR: #000000"> deviceList</span>.<span style="COLOR: #000000">values</span>().<span style="COLOR: #000000">iterator</span>();<span style="COLOR: #000000">
</span>while(<span style="COLOR: #000000">deviceIterator</span>.<span style="COLOR: #000000">hasNext</span>()){<span style="COLOR: #000000">
    </span>UsbDevice<span style="COLOR: #000000"> device </span>=<span style="COLOR: #000000"> deviceIterator</span>.next()<span style="COLOR: #000000">
    int vendorId = device.getVendorId(); int productIt = device.getProductId();  如果是用第一種方法檢測的話device_filter.mxl裡面的兩個值要填這兩個</span><span style="COLOR: #000000">
</span>}

用這種遍歷方法我是程式啟動的時候起一條執行緒隔三秒檢測一次, 檢測到手柄後根據各自需求處理.

檢測USB裝置拔出:

usb裝置拔出的時候會丟擲一個action值為UsbManager.ACTION_USB_DEVICE_DETACHED的廣播, 註冊一個廣播接收即可.

其實UsbManager還有一個UsbManager.ACTION_USB_ACCESSORY_ATTACHED的值,從文件上看意思是usb裝置插入時候會有這個廣播丟擲,但是實際上卻沒有收到這個廣播

事件捕獲

按鈕事件可以通過重寫OnKeyDown和OnKeyUp捕獲這些事件

if(event.getDevice() != null && event.getDevice().getSources() == 0x1000511){

     // 該事件來自Joystick

}

掃描碼: int scanCode = event.getScanCode();

如果是Joystick的上下左右事件, scanCode 的值為0, 測試過10幾款手柄,得到的數值都是

keyCode == 19   // 上

keyCode == 20   // 下

keyCode == 21   // 左

keyCode == 22   // 右

遊戲手柄上左邊蘑菇頭的事件可以通過重寫onGenericMotionEvent獲得,

float x = event.getX(), float y = event.getY();   這些得到的資料都是座標,具體數值是精確到小數點後9位

測試程式碼是抽離出來的, 暫時沒有裝置可以測試,不過大致的程式碼是沒錯的,希望對大家有幫助。

另外我再說明一下, 我這個程式只用過遊戲手柄測試過,資料都能拿到, 其他usb如果android是有支援的應該也是可以拿到的,

之前有朋友加我的QQ說我的程式拿不到資料, 最後查出來是因為android不支援他的usb裝置。如有問題,歡迎討論。

2012/6/18更新:  因為有很多說裝置拿不到資料. 目前通過加QQ溝通的朋友拿不到的主要有兩個原因。

1. android 系統本身不支援特殊的裝置,有時候雖然能夠識別到,但不一定能夠拿到productID和vectorId, 所以大家的測試的建議使用一些官方有說明支援的,我用遊戲手柄測試的運氣比較好,所有的手柄都是能拿到資料的。

2. android 裝置和版本也有一定要求,有個朋友也說是拿不到資料,那個時候他用的平板是國產的某平板,後來他買了XOOM再測試的時候發現就能拿到了,所以這裡建議大家使用一些官方的裝置來做測試,xoom或者galaxy Tab(7寸除外,7寸GT不支援3.x) 都是不錯的選擇。