Android設(shè)備通過數(shù)據(jù)線進行相互通信

具體步驟

發(fā)現(xiàn)設(shè)備

UsbManager usbManager = (UsbManager) context.getSystemService(Context.USB_SERVICE);
Map<String, UsbDevice> usbList = usbManager.getDeviceList();

官方注釋:

This class represents a USB device attached to the android device with the android device
 acting as the USB host.

這個類代表了android所連接的usb設(shè)備尘奏。

打開設(shè)備

需要打開剛剛搜索到的usb設(shè)備饶囚。

一般來說,在沒有定制的android設(shè)備上首次訪問usb設(shè)備的時候唬格,默認我們是沒有訪問權(quán)限的鹃操,因此我們首先要判斷對當前要打開的usbDevice是否有訪問權(quán)限:

if (!usbManager.hasPermission(usbDevice)) {
    usbPermissionReceiver = new UsbPermissionReceiver();
   //申請權(quán)限
   Intent intent = new Intent(ACTION_DEVICE_PERMISSION);
   PendingIntent mPermissionIntent = PendingIntent.getBroadcast(context, 0, intent, 0);
   IntentFilter permissionFilter = new IntentFilter(ACTION_DEVICE_PERMISSION);
   context.registerReceiver(usbPermissionReceiver, permissionFilter);
   usbManager.requestPermission(usbDevice, mPermissionIntent);
}

需要聲明一個廣播UsbPermissionReceiver,當接受到授權(quán)成功的廣播后做一些其他處理抚垃。

private class UsbPermissionReceiver extends BroadcastReceiver {
  public void onReceive(Context context, Intent intent) {
      String action = intent.getAction();
      if (ACTION_DEVICE_PERMISSION.equals(action)) {
          synchronized (this) {
              UsbDevice device = intent.getParcelableExtra(UsbManager.EXTRA_DEVICE);
              if (device.getDeviceName().equals(usbDevice.getDeviceName()) {
                  if (intent.getBooleanExtra(UsbManager.EXTRA_PERMISSION_GRANTED, false)) {
                    //授權(quán)成功,在這里進行打開設(shè)備操作
                  } else {
                    //授權(quán)失敗
                  }
              }
          }
      }
  }
}

接下來喷楣,要找到具有數(shù)據(jù)傳輸功能的接口UsbInterface,從它里面找到數(shù)據(jù)輸入和輸出端口UsbEndpoint鹤树,一般情況下铣焊,一個usbDevice有多個UsbInterface,我們需要的一般是第一個罕伯,所以:

usbInterface=usbDevice.getInterface(0);

同樣的曲伊,一個usbInterface有多個UsbEndpoint,有控制端口和數(shù)據(jù)端口等追他,因此我們需要根據(jù)類型和數(shù)據(jù)流向來找到需要的數(shù)據(jù)輸入和輸出兩個端口:

for (int index = 0; index < usbInterface.getEndpointCount(); index++) {
    UsbEndpoint point = usbInterface.getEndpoint(index);
    if (point.getType() == UsbConstants.USB_ENDPOINT_XFER_BULK) {
        if (point.getDirection() == UsbConstants.USB_DIR_IN) {
            usbEndpointIn = point;
        } else if (point.getDirection() == UsbConstants.USB_DIR_OUT) {
            usbEndpointOut = point;
        }
    }
}

最后坟募,才是真正的打開usb設(shè)備,我們需要和usb外設(shè)建立一個UsbDeviceConnection邑狸,官方注釋:

This class is used for sending and receiving data and control messages to a USB device.

UsbDeviceConnection的獲刃概础:

usbDeviceConnection = usbManager.openDevice(usbDevice);

數(shù)據(jù)傳輸

  • 向usb外設(shè)發(fā)送數(shù)據(jù)

在第二步中,我們已經(jīng)獲取了數(shù)據(jù)的輸出端口usbEndpointIn单雾,我們向外設(shè)發(fā)送數(shù)據(jù)就是通過這個端口來實現(xiàn)的赚哗。

int ret = usbDeviceConnection.bulkTransfer(usbEndpointOut, data, data.length, DEFAULT_TIMEOUT);

bulkTransfer這個函數(shù)用于在給定的端口進行數(shù)據(jù)傳輸,第一個參數(shù)就是此次傳輸?shù)亩丝诠瓒眩@里我們用的輸出端口屿储,第二個參數(shù)是要發(fā)送的數(shù)據(jù),類型為字節(jié)數(shù)組渐逃,第三個參數(shù)代表要發(fā)送的數(shù)據(jù)長度够掠,最后一個參數(shù)是超時,返回值代表發(fā)送成功的字節(jié)數(shù)朴乖,如果返回-1祖屏,那就是發(fā)送失敗了。

  • 接受usb外設(shè)發(fā)送來的數(shù)據(jù)

已經(jīng)找到了數(shù)據(jù)輸入端口usbEndpointIn买羞,因為數(shù)據(jù)的輸入是不定時的袁勺,因此我們可以另開一個線程,來專門接受數(shù)據(jù)畜普。

int inMax = inEndpoint.getMaxPacketSize(); 
ByteBuffer byteBuffer = ByteBuffer.allocate(inMax); 
UsbRequest usbRequest = new UsbRequest(); 
usbRequest.initialize(connection, inEndpoint); 
usbRequest.queue(byteBuffer, inMax); 
if(connection.requestWait() == usbRequest){ 
    byte[] retData = byteBuffer.array(); 
    for(Byte byte1 : retData){ 
        System.err.println(byte1); 
    } 
}

注:理論上設(shè)備之間的連接已經(jīng)建立了期丰,也可以首發(fā)數(shù)據(jù)了,但是,我們大部分情況下還需要對usb串口進行一些配置钝荡,比如波特率,停止位,數(shù)據(jù)控制等街立,不然兩邊配置不同,收到的數(shù)據(jù)會亂碼埠通,具體怎么配置赎离,需要看串口芯片。

測試設(shè)備需求

  • Android版本>3.2的設(shè)備
  • OTG轉(zhuǎn)接線

項目地址端辱, 請戳我

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末梁剔,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子舞蔽,更是在濱河造成了極大的恐慌荣病,老刑警劉巖,帶你破解...
    沈念sama閱讀 217,509評論 6 504
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件渗柿,死亡現(xiàn)場離奇詭異个盆,居然都是意外死亡,警方通過查閱死者的電腦和手機朵栖,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,806評論 3 394
  • 文/潘曉璐 我一進店門颊亮,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人混槐,你說我怎么就攤上這事编兄⌒裕” “怎么了声登?”我有些...
    開封第一講書人閱讀 163,875評論 0 354
  • 文/不壞的土叔 我叫張陵,是天一觀的道長揣苏。 經(jīng)常有香客問我悯嗓,道長,這世上最難降的妖魔是什么卸察? 我笑而不...
    開封第一講書人閱讀 58,441評論 1 293
  • 正文 為了忘掉前任脯厨,我火速辦了婚禮,結(jié)果婚禮上坑质,老公的妹妹穿的比我還像新娘合武。我一直安慰自己,他們只是感情好涡扼,可當我...
    茶點故事閱讀 67,488評論 6 392
  • 文/花漫 我一把揭開白布稼跳。 她就那樣靜靜地躺著,像睡著了一般吃沪。 火紅的嫁衣襯著肌膚如雪汤善。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,365評論 1 302
  • 那天,我揣著相機與錄音红淡,去河邊找鬼不狮。 笑死,一個胖子當著我的面吹牛在旱,可吹牛的內(nèi)容都是我干的摇零。 我是一名探鬼主播,決...
    沈念sama閱讀 40,190評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼桶蝎,長吁一口氣:“原來是場噩夢啊……” “哼遂黍!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起俊嗽,我...
    開封第一講書人閱讀 39,062評論 0 276
  • 序言:老撾萬榮一對情侶失蹤雾家,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后绍豁,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體芯咧,經(jīng)...
    沈念sama閱讀 45,500評論 1 314
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,706評論 3 335
  • 正文 我和宋清朗相戀三年竹揍,在試婚紗的時候發(fā)現(xiàn)自己被綠了敬飒。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 39,834評論 1 347
  • 序言:一個原本活蹦亂跳的男人離奇死亡芬位,死狀恐怖无拗,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情昧碉,我是刑警寧澤英染,帶...
    沈念sama閱讀 35,559評論 5 345
  • 正文 年R本政府宣布,位于F島的核電站被饿,受9級特大地震影響四康,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜狭握,卻給世界環(huán)境...
    茶點故事閱讀 41,167評論 3 328
  • 文/蒙蒙 一闪金、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧论颅,春花似錦哎垦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,779評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至澡谭,卻和暖如春愿题,著一層夾襖步出監(jiān)牢的瞬間损俭,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 32,912評論 1 269
  • 我被黑心中介騙來泰國打工潘酗, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留杆兵,地道東北人。 一個月前我還...
    沈念sama閱讀 47,958評論 2 370
  • 正文 我出身青樓仔夺,卻偏偏與公主長得像琐脏,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子缸兔,可洞房花燭夜當晚...
    茶點故事閱讀 44,779評論 2 354

推薦閱讀更多精彩內(nèi)容