在android通過Genymotion模擬器枚舉U盤設(shè)備(一)中膝宁,我們已經(jīng)可以枚舉設(shè)備和獲得通信權(quán)限趟咆,實(shí)際上在獲得通信權(quán)限進(jìn)行通信之前螟炫,一般會(huì)根據(jù)USB設(shè)備的描述信息來判斷程序是否支持當(dāng)前設(shè)備的通信涧偷。
如下示例為判斷是否為大容量存儲(chǔ)設(shè)備(U盤):
for (int i = 0; i < usbDevice.getInterfaceCount(); i++) {
UsbInterface usbInterface = usbDevice.getInterface(i);
// 1吃引、類為:USB_CLASS_MASS_STORAGE 0x08
// 2戈钢、子類為:0x06 (大部分U盤使用)
// 3涝桅、協(xié)議為:0x50 (Bulk-Only協(xié)議 批量傳輸)
if (usbInterface.getInterfaceClass() == UsbConstants.USB_CLASS_MASS_STORAGE
&& usbInterface.getInterfaceSubclass() == 0x06
&& usbInterface.getInterfaceProtocol() == 0x50) {
//每個(gè)存儲(chǔ)設(shè)備一定有兩個(gè)端點(diǎn):in 和 out
UsbEndpoint outEndpoint = null, inEndpoint = null;
for (int j = 0; j < usbInterface.getEndpointCount(); j++) {
UsbEndpoint endpoint = usbInterface.getEndpoint(j);
if (endpoint.getType() == UsbConstants.USB_ENDPOINT_XFER_BULK) {
if (endpoint.getDirection() == UsbConstants.USB_DIR_OUT) {
outEndpoint = endpoint;
} else {
inEndpoint = endpoint;
}
}
}
}
}
1、數(shù)據(jù)傳輸
在完成設(shè)備枚舉后峻汉,選定UsbDevice
對(duì)象并獲取權(quán)限后贴汪,接下來就可以與之進(jìn)行數(shù)據(jù)交互。在USB通信過程中主要有四種數(shù)據(jù)傳輸方式:Control Transaction(控制傳輸)休吠、Interrupt Transaction(中斷傳輸)扳埂、Bulk Transaction(批量傳輸)和Isochronous Transaction(等時(shí)傳輸)。
控制傳輸:
所有USB設(shè)備與主機(jī)必須支持的方式瘤礁,特點(diǎn)是數(shù)據(jù)量小阳懂、正確性高,一般用于信息獲取、命令控制與參數(shù)配置等岩调。在獲取設(shè)備描述符階段采用此方式巷燥。
中斷傳輸:
中斷傳輸是一種保證查詢頻率的傳輸,主機(jī)會(huì)保證在小于這個(gè)時(shí)間間隔的范圍內(nèi)安排一次傳輸号枕,常用于數(shù)據(jù)量不大缰揪,但是對(duì)時(shí)間要求嚴(yán)格的設(shè)備,比如鍵盤按一個(gè)鍵值堕澄,鼠標(biāo)移動(dòng)的位移量邀跃。
批量傳輸:
主要用于傳輸大量的,但是對(duì)時(shí)間無(wú)要求的數(shù)據(jù)蛙紫,比如讀取U盤的數(shù)據(jù)拍屑。
等時(shí)傳輸:
適用于數(shù)據(jù)量大且恒定的數(shù)據(jù),比如USB攝像頭坑傅。
Android提供使用 批量傳輸bulkTransfer()
與控制傳輸 controlTransfer()
在端點(diǎn)上傳輸數(shù)據(jù)僵驰。
如果要完成中斷與等時(shí)傳輸可以借助后面介紹的第三方C庫(kù):libusb。
在進(jìn)行傳輸之前唁毒,首先需要獲得設(shè)備對(duì)應(yīng)的UsbDeviceConnection
對(duì)象:
deviceConnection = usbManager.openDevice(usbDevice);
//鎖定此接口UsbInterface (其實(shí)就是鎖定端口蒜茴,同時(shí)只能一處使用)
deviceConnection.claimInterface(usbInterface, true);
// 控制傳輸
byte[] maxLun = new byte[1];
deviceConnection.controlTransfer(requestType,
request, value, index, bytes, bytes.length, TIMEOUT);
// 批量傳輸
deviceConnection.bulkTransfer(endpoint, bytes, bytes.length, TIMEOUT);
android使用控制傳輸,等時(shí)傳輸需要使用libusb
https://github.com/libusb/libusb
4浆西、關(guān)閉通信
當(dāng)完成與設(shè)備的通信后粉私,需要調(diào)用 releaseInterface()
和 close()
來關(guān)閉 UsbInterface
和 UsbDeviceConnection
。
deviceConnection.releaseInterface(usbInterface);
deviceConnection.close();
而如果是設(shè)備斷開連接近零,可以通過廣播監(jiān)聽:
BroadcastReceiver usbReceiver = new BroadcastReceiver() {
public void onReceive(Context context, Intent intent) {
String action = intent.getAction();
//某個(gè)USB設(shè)備斷開連接
if (UsbManager.ACTION_USB_DEVICE_DETACHED.equals(action)) {
UsbDevice device = intent.getParcelableExtra(UsbManager.EXTRA_DEVICE);
if (device != null && //當(dāng)前通信設(shè)備) {
deviceConnection.releaseInterface(usbInterface);
deviceConnection.close();
}
}
}
};
USB網(wǎng)站
USB基礎(chǔ)知識(shí)總結(jié)
https://blog.csdn.net/qq_41483419/article/details/128788133