Android Usb的研究
USB為什么復(fù)雜,因?yàn)閁SB標(biāo)準(zhǔn)內(nèi)容太多了.
Android上的USB外圍設(shè)備.我見(jiàn)過(guò)指紋,鼠標(biāo),觸摸屏,U盤.大部分人用USB充充電.USB的介紹網(wǎng)上已經(jīng)很多了,我以移植一個(gè)USB觸摸屏來(lái)說(shuō)明我的理解.
Android上USB的API android.hardware.usb.UsbManager,函數(shù)也不多,就是不好用,一個(gè)涉及到權(quán)限,另外一個(gè)涉及到協(xié)議.
權(quán)限:
先解決表面上的問(wèn)題,這和android權(quán)限機(jī)制有關(guān)系.
第一步:
在AndroidManifest.xml加入
?
<uses-permission android:name="android.hardware.usb.host" />
<uses-permission android:name="android.hardware.usb.accessory" />
第二步:
?
怎么找到我的設(shè)備呢?
?
mManager = (UsbManager) c.getSystemService(Context.USB_SERVICE);
HashMap<String, UsbDevice> list = mManager.getDeviceList();
for (UsbDevice usb : list.values()) {
int pid = usb.getProductId();
int vid = usb.getVendorId();
}
遍歷list,打印出pid和vid號(hào),看和你實(shí)際對(duì)應(yīng)pid,vid號(hào)是不是一樣呢?
?
如果你沒(méi)看到usb設(shè)備呢?我想大部分人會(huì)遇到,有人會(huì)說(shuō)你沒(méi)把vid,pid號(hào)加入usbfilter.xml文件里.不要被誤導(dǎo),這只和熱插拔設(shè)備彈出應(yīng)用有關(guān),系統(tǒng)檢測(cè)熱插拔,和getDeviceList無(wú)關(guān),getDeviceList會(huì)獲取所有usb設(shè)備.
參考這篇文章基本能解決,因?yàn)閍ndroid很多版本都不完善.
?
http://blog.csdn.net/trbbadboy/article/details/8929673第三步:
?
打開(kāi)設(shè)備:
?
mDeviceIntf = mDevice.getInterface(0);
mDeviceConnect = mManager.openDevice(mDevice);
mDeviceConnect.claimInterface(mDeviceIntf, true);
初步完成.
第四步(可選):
google這點(diǎn)做的不厚道,什么東西都要求權(quán)限,上個(gè)廁所都得申請(qǐng),雖然可以記住用戶選擇,可別忘了usb是熱插拔設(shè)備,你拔完之后,從新插入又是一個(gè)新設(shè)備,又得申請(qǐng)權(quán)限,而且申請(qǐng)過(guò)程中遇到卡死的情況.怎么避免requestPermission()帶來(lái)的提示呢?
答案在這里,修改所有的申請(qǐng)都為通過(guò).
?
frameworks/base/services/java/com/android/server/usb/UsbSettingsManager.java這是得修改系統(tǒng)源碼.
協(xié)議
協(xié)議是復(fù)雜的問(wèn)題,controlTransfer參數(shù)搞不懂,什么意思?所以得參考usb協(xié)議,不能自己瞎想.
一個(gè)命令格式:bmRequestType + bRequest + wValue + wIndex + wLength ,總共8個(gè)字節(jié)
當(dāng)然命令+=數(shù)據(jù)
可以這么簡(jiǎn)單理解.
bmRequest代表方向,主機(jī)->從設(shè)備或者從設(shè)備到主機(jī)
bRequest 命令,參考表2
wValue 參數(shù)1,得仔細(xì)看協(xié)議標(biāo)準(zhǔn),太多了
wIndex 參數(shù)2,得仔細(xì)看協(xié)議標(biāo)準(zhǔn),太多了
wLength:接收或者發(fā)送數(shù)據(jù)的大小,不包括命令本身(8字節(jié))
data;數(shù)據(jù),根據(jù)實(shí)際情況
命令格式表9-2
命令表9-4
?
?
例子:
我拿一幀數(shù)據(jù)舉個(gè)例子,我用BusHound抓取獲取描述符的命令,IN是接收到的數(shù)據(jù)
?
命令格式:81 06 02 03 09 04 02 02
bmRequestType = 0x80; 從設(shè)備到主機(jī)
bRequest = 0x06; 參考表9-4,GET_DESCRIPTOR
wValue = 0x0302;參數(shù)1,高位代表類型(String類型),低位代表索引值
wIndex = 0x0409;參數(shù)2
wLength = 0x0202;接收長(zhǎng)度0x0202字節(jié)
手冊(cè)里抓出來(lái)的說(shuō)明
那在android上怎么用呢?這是UsbDeviceConnection的一個(gè)標(biāo)準(zhǔn)函數(shù),這里面的參數(shù)就是上面所說(shuō)的參數(shù).
?
* <p>
* This method transfers data starting from index 0 in the buffer.
* To specify a different offset, use
* {@link #controlTransfer(int, int, int, int, byte[], int, int, int)}.
* </p>
*
* @param requestType request type for this transaction
* @param request request ID for this transaction
* @param value value field for this transaction
* @param index index field for this transaction
* @param buffer buffer for data portion of transaction,
* or null if no data needs to be sent or received
* @param length the length of the data to send or receive
* @param timeout in milliseconds
* @return length of data transferred (or zero) for success,
* or negative value for failure
*/
public int controlTransfer(int requestType, int request, int value,
int index, byte[] buffer, int length, int timeout) {
return controlTransfer(requestType, request, value, index, buffer, 0, length, timeout);
}
我們?cè)囍l(fā)送一下上面抓取的數(shù)據(jù)
?
?
void test()
{
byte [] rcv = new byte[0x0202];
int r = mDeviceConnect.controlTransfer(
0x80,
0x06,
0x3 << 8 | 0x2,
0x4 << 8 | 0x9,
rcv,
0x0202,
1000);
ComFunc.log("is test log", rcv, 64);
}
得到結(jié)果:
?
?
/Timeline( 762): Timeline: Activity_windows_visible id: ActivityRecord{419df0c8 u0 com.ou.usbtp/com.ou.ui.DemoActivity
t24} time:16355386
I/MLog ( 4562): is test log{
I/MLog ( 4562): 2c,03,49,00,6e,00,66,00,72,00,61,00,72,00,65,00,
I/MLog ( 4562): 64,00,20,00,54,00,6f,00,75,00,63,00,68,00,20,00,
I/MLog ( 4562): 53,00,63,00,72,00,65,00,65,00,6e,00,00,00,00,00,
I/MLog ( 4562): 00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,};
V/RenderScript( 4562): Application requested CPU execution
和bushound抓取結(jié)果一樣.
當(dāng)然我們不會(huì)只做獲取描述符簡(jiǎn)單的問(wèn)題,我們還需要設(shè)計(jì)到配置信息和讀取信息的功能.
?
和上面類似,只是換了命令類型,
這是我配置USB觸摸屏使用到的配置信息片段,大家可以參考.
Device Length Phase Data Description Cmd.Phase.Ofs(rep) Time
------ -------- ----- -------------------------------------------------- ---------------- ------------------ ------------
37.0 CTL 21 09 05 03 02 00 40 00 SET REPORT 1.1.0 10:08:02.852
37.0 64 OUT 05 03 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ 1.2.0 10:08:02.852
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ 1.2.16
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ 1.2.32
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ 1.2.48
37.0 CTL a1 01 06 03 02 00 40 00 GET REPORT 2.1.0 10:08:02.872
37.0 64 IN 06 03 00 00 fc 00 00 80 00 00 00 00 00 00 00 00 ................ 2.2.0 10:08:02.872
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ 2.2.16
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ 2.2.32
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ 2.2.48
另外一些相關(guān)涉及的方面
android usb-touchscreen驅(qū)動(dòng):
?
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/drivers/input/touchscreen/usbtouchscreen.c?h=v4.12-rc4usb 2.0協(xié)議標(biāo)準(zhǔn)(英文):
?
http://www.usb.org/developers/docs/usb20_docs/有興趣一起討論.
總結(jié)
以上是生活随笔為你收集整理的Android Usb的研究的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: 调试扫描头
- 下一篇: AndroidStuido编译relea