1. 程式人生 > >Android USB Host 使用詳解(U盤)(一)

Android USB Host 使用詳解(U盤)(一)

首先說一下為什麼要寫關於Android USB Host通訊的介紹,對於Android程式原來說不懂硬體做USB通訊確實開頭比較難,但是Google API介紹還是很詳細的,而且網上也有很多例子,不過網上的基本把介紹和例子分開,光介紹不給例子,給個例子又不知道它是幹什麼的或者執行不了。那麼我把自己通過閱讀別人的部落格和USB通訊協議等來做下面的介紹,並給出一個通用的例子。

Android USB Host分以下三部份介紹:

Android USB Host使用詳解之一:檢視USB裝置資訊

Android USB有兩種模式Host  Mode和Accessory Mode:

在Host Mode下,Android手機作為主裝置,如通過OTG線連線的HID裝置或者U盤為從裝置;在Accessory Mode下,Android手機作為從裝置,如通過USB資料線連線的電腦為主裝置。

本文主要介紹在Host Mode下,Android手機與USB裝置之間的通訊。Android USB Host的介紹可參見Google 官方文件:Android USB Host介紹

關於Android USB相關類的介紹留在下面慢慢展開,先編寫一個Android程式:

1)在AndroidManifest.xml檔案中新增

<uses-feature android:name="android.hardware.usb.host" />
<uses-sdk android:minSdkVersion="12" />
有可能你在其它地方看見這樣的寫法
<uses-feature android:name="android.hardware.usb.host" android:required="true"/>
本人建議不要這樣寫,因為這樣寫的話可能在/system/etc/permissions目錄下不能自動建立android.hardware.usb.host.xml檔案,而需要手動建立。

2)在<activity ...>新增

<intent-filter>
     <action android:name="android.hardware.usb.action.USB_DEVICE_ATTACHED" />
</intent-filter>
<meta-data android:name="android.hardware.usb.action.USB_DEVICE_ATTACHED"
     android:resource="@xml/device_filter" />
在res/xml資料夾下新建device_filter.xml
<resources>
    <usb-device vendor-id="3544" product-id="8199" />
    <usb-device vendor-id="5251" product-id="4608" />
</resources>
 其中vendor-id和product-id為插入USB裝置的生產廠家號和產品號,但插入(attached)上面列出的裝置之一時就會彈出選擇開啟應用程式的對話方塊。注:上面的id為10進位制的,而通過電腦上檢視的id為16進位制的。

3)獲取所有已連線上的USD裝置的資訊

public class MainActivity extends ActionBarActivity {
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        UsbManager mManager = (UsbManager) getSystemService(Context.USB_SERVICE);
        HashMap<String, UsbDevice> deviceList = mManager.getDeviceList();
        Iterator<UsbDevice> deviceIterator = deviceList.values().iterator();
        
        String info = new String();
        while (deviceIterator.hasNext())
        {
        	UsbDevice device = deviceIterator.next();
        	info += "Device Name:" + device.getDeviceName() + "\n";
        	info += "Device ID:" + device.getDeviceId() + "\n";
        	info += "Device Class:" + device.getDeviceClass() + "\n";
        	info += "Device Protocl:" + device.getDeviceProtocol() + "\n";
        	info += "Device Vendor ID:" + device.getVendorId() + "\n";
        	info += "Device Product ID:" + device.getProductId() + "\n";
        	info += "Device Interface Count:" + device.getInterfaceCount() + "\n\n";
            // Get interface details
            for (int index = 0; index < device.getInterfaceCount(); index++)
            {
            	UsbInterface mUsbInterface = device.getInterface(index);
            	info += "Interface " + index + ":\n";
            	info += "Interface ID:" + mUsbInterface.getId() + "\n";
            	info += "Inteface class:" + mUsbInterface.getInterfaceClass() + "\n";
            	info += "Interface protocol:" + mUsbInterface.getInterfaceProtocol() + "\n";
            	info += "Endpoint count:" + mUsbInterface.getEndpointCount() + "\n\n";
            	// Get endpoint details 
            	for (int epi = 0; epi < mUsbInterface.getEndpointCount(); epi++)
            	{
            		UsbEndpoint mEndpoint = mUsbInterface.getEndpoint(epi);
            		info += "Endpoint " + epi + ":\n";
            		info += "Attributes: " + mEndpoint.getAttributes() + "\n";
            		info += "Direction: " + mEndpoint.getDirection() + "\n";
            		info += "Number: " + mEndpoint.getEndpointNumber() + "\n";
            		info += "Interval: " + mEndpoint.getInterval() + "\n";
            		info += "Packet size: " + mEndpoint.getMaxPacketSize() + "\n";
            		info += "Type: " + mEndpoint.getType() + "\n\n";
            	}
            }
        }        
        TextView textView = (TextView)findViewById(R.id.info);
        textView.setText(info);
    }
}

通過上面這段程式碼可以獲得USB裝置的所有資訊,包括介面(interface)和端點(endpoint)的資訊,只有瞭解裝置的型別才能在後面進行通訊。注:本人在測試時即使沒有連線裝置也會有顯示一個裝置,這個裝置即使刪除它後系統也會自動生成,這裡不用管它,之後把它過濾掉就可以了。

測試結果如下:

上面左圖為第一個裝置(無對應裝置,懂的大神可以解釋一下),右圖為連線的U盤。Device Name 的值是一個檔案路徑,在路徑下可以看到相應的檔案,插入裝置時自動生成,拔出時自動刪除,懂Linux的應該明白原理,我是不懂,所以就不解釋了。

原始碼下載連結:原始碼連結