溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊(cè)×
其他方式登錄
點(diǎn)擊 登錄注冊(cè) 即表示同意《億速云用戶服務(wù)條款》

Android應(yīng)用中怎么將USB裝換為串口通信

發(fā)布時(shí)間:2020-12-02 17:01:28 來(lái)源:億速云 閱讀:292 作者:Leah 欄目:移動(dòng)開(kāi)發(fā)

Android應(yīng)用中怎么將USB裝換為串口通信?很多新手對(duì)此不是很清楚,為了幫助大家解決這個(gè)難題,下面小編將為大家詳細(xì)講解,有這方面需求的人可以來(lái)學(xué)習(xí)下,希望你能有所收獲。

 Android USB轉(zhuǎn)串口通信開(kāi)發(fā)實(shí)例詳解

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

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

通過(guò)UsbManager這個(gè)系統(tǒng)提供的類,我們可以枚舉出當(dāng)前連接的所有usb設(shè)備,我們主要需要的是UsbDevice對(duì)象,關(guān)于UsbDevice這個(gè)類,官方是這樣注釋的:

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

是的,這個(gè)類就代表了Android所連接的usb設(shè)備。

2.打開(kāi)設(shè)備

接下來(lái),我們需要打開(kāi)剛剛搜索到的usb設(shè)備,我們可以將平板與usb外設(shè)之間的連接想象成一個(gè)通道,只有把通道的門打開(kāi)后,兩邊才能進(jìn)行通信。

一般來(lái)說(shuō),在沒(méi)有定制的android設(shè)備上首次訪問(wèn)usb設(shè)備的時(shí)候,默認(rèn)我們是沒(méi)有訪問(wèn)權(quán)限的,因此我們首先要判斷對(duì)當(dāng)前要打開(kāi)的usbDevice是否有訪問(wèn)權(quán)限:

if (!usbManager.hasPermission(usbDevice)) {
    usbPermissionReceiver = new UsbPermissionReceiver();
    //申請(qǐng)權(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);
    }

這里我們聲明一個(gè)廣播UsbPermissionReceiver,當(dāng)接受到授權(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)成功,在這里進(jìn)行打開(kāi)設(shè)備操作
            } else {
             //授權(quán)失敗
            }
          }
        }
      }
    }
  }

接下來(lái),我們要找到具有數(shù)據(jù)傳輸功能的接口UsbInterface,從它里邊兒找到數(shù)據(jù)輸入和輸出端口UsbEndpoint,一般情況下,一個(gè)usbDevice有多個(gè)UsbInterface,我們需要的一般是第一個(gè),所以:

usbInterface=usbDevice.getInterface(0);

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

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;
          }
        }
      }

最后,才是真正的打開(kāi)usb設(shè)備,我們需要和usb外設(shè)建立一個(gè)UsbDeviceConnection,它的注釋很簡(jiǎn)介的說(shuō)明了它的用途:

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

它的獲取也很簡(jiǎn)單,就一句代碼:

usbDeviceConnection = usbManager.openDevice(usbDevice);

到這里,理論上平板和usb外設(shè)之間的連接已經(jīng)建立了,也可以首發(fā)數(shù)據(jù)了,但是,我們大部分情況下還需要對(duì)usb串口進(jìn)行一些配置,比如波特率,停止位,數(shù)據(jù)控制等,不然兩邊配置不同,收到的數(shù)據(jù)會(huì)亂碼。具體怎么配置,就看你使用的串口芯片是什么了,目前流行的有pl2303,ch440等,由于篇幅問(wèn)題,需要具體配置串口代碼的朋友私信我我發(fā)給你。

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

到這里,我們已經(jīng)可以與usb外設(shè)進(jìn)行數(shù)據(jù)傳輸了,首先來(lái)看怎么向usb設(shè)備發(fā)送數(shù)據(jù)。

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

在第二步中,我們已經(jīng)獲取了數(shù)據(jù)的輸出端口usbEndpointIn,我們向外設(shè)發(fā)送數(shù)據(jù)就是通過(guò)這個(gè)端口來(lái)實(shí)現(xiàn)的。來(lái)看怎么用:

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

bulkTransfer這個(gè)函數(shù)用于在給定的端口進(jìn)行數(shù)據(jù)傳輸,第一個(gè)參數(shù)就是此次傳輸?shù)亩丝?,這里我們用的輸出端口,第二個(gè)參數(shù)是要發(fā)送的數(shù)據(jù),類型為字節(jié)數(shù)組,第三個(gè)參數(shù)代表要發(fā)送的數(shù)據(jù)長(zhǎng)度,最后一個(gè)參數(shù)是超時(shí),返回值代表發(fā)送成功的字節(jié)數(shù),如果返回-1,那就是發(fā)送失敗了。

2.接受usb外設(shè)發(fā)送來(lái)的數(shù)據(jù)

同理,我們已經(jīng)找到了數(shù)據(jù)輸入端口usbEndpointIn,因?yàn)閿?shù)據(jù)的輸入是不定時(shí)的,因此我們可以另開(kāi)一個(gè)線程,來(lái)專門接受數(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); 
  } 
}

看完上述內(nèi)容是否對(duì)您有幫助呢?如果還想對(duì)相關(guān)知識(shí)有進(jìn)一步的了解或閱讀更多相關(guān)文章,請(qǐng)關(guān)注億速云行業(yè)資訊頻道,感謝您對(duì)億速云的支持。

向AI問(wèn)一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI