Android之USB转串口通信-基本流程

Android之USB转串口通信-基本流程,第1张

概述背景:近期公司一个项目对接第三方支付设备(类似平板的设备外接usb转串口设备),需要使用usb转串口,实现通信和交互,今天记下过程。有引用这个库 https://github.com/mik3y/usb-serial-for-android,感谢开源的大佬。这个库已经集合了一般的芯片协议,就不需要自己再配置了。我们设备是

背景:近期公司一个项目对接第三方支付设备(类似平板的设备外接usb转串口设备),需要使用usb转串口,实现通信和交互,今天记下过程。

有引用这个库 https://github.com/mik3y/usb-serial-for-android,感谢开源的大佬。

这个库已经集合了一般的芯片协议,就不需要自己再配置了。我们设备是用的ProlificSerialDriver.

唯一要注意的是配置设备的参数:波特率,数据位,体制位,奇偶校验等。其中我就在奇偶校验的参数配置上坑了一把。

只需要按照流程,注意些细节就能跑。

贴下核心的几段代码:

import androID.harDWare.usb.UsbDeviceimport androID.harDWare.usb.UsbDeviceConnectionimport androID.harDWare.usb.UsbManagerimport com.hoho.androID.usbserial.driver.UsbSerialPortimport com.hoho.androID.usbserial.driver.UsbSerialProberclass ZYDataSource(){    var mUsbSeriaPortManager: USBSerialPortManager? = null    private var usbDeviceConnection: UsbDeviceConnection? = null    private var mDevice: UsbDevice? = null    private var mUsbSerialPort: UsbSerialPort? = null    private var usbPermissionReceiver: UsbPermissionReceiver? = null    private var mUsbManager: UsbManager? = null        /**    * 初始化    */    overrIDe fun initCompletable(context: Context): Completable {        return Completable.create() {            mUsbManager = context.getSystemService(Context.USB_SERVICE) as UsbManager            //查找所有设备            val driversList = UsbSerialProber.getDefaultProber().findAllDrivers(mUsbManager)            if (driversList == null || driversList.size == 0) {                throw Exception("未找到设备")            }            //直接取第一个.            mDevice = driversList.first().device            if (!mUsbManager?.hasPermission(mDevice)!!) {                usbPermissionReceiver = UsbPermissionReceiver()                //申请权限                val intent = Intent(ACTION_DEVICE_PERMISSION)                val mPermissionIntent = PendingIntent.getbroadcast(context, 0, intent, 0)                val permissionFilter = IntentFilter(ACTION_DEVICE_PERMISSION)                context.registerReceiver(usbPermissionReceiver, permissionFilter)                mUsbManager?.requestPermission(mDevice, mPermissionIntent)            } else {                this.openDeviceConnection(device = mDevice!!)            }            it.onComplete()        }    }    inner class UsbPermissionReceiver : broadcastReceiver() {        overrIDe fun onReceive(p0: Context?, intent: Intent?) {            val action = intent?.getAction()            if (ACTION_DEVICE_PERMISSION.equals(action)) {                synchronized(this) {                    val device = intent.getParcelableExtra<UsbDevice>(UsbManager.EXTRA_DEVICE)                    openDeviceConnection(device)                }            }        }    }        /**    * 打开连接    */    fun openDeviceConnection(device: UsbDevice) {        synchronized(this) {            //授权成功,在这里进行打开设备 *** 作            val availableDrivers = UsbSerialProber.getDefaultProber().findAllDrivers(mUsbManager)            if (availableDrivers.isEmpty()) {                return            }            // Open a connection to the first available driver.            val driver = availableDrivers[0]            // Read some data! Most have just one port (port 0).            mUsbSerialPort = driver.ports[0]            try {                mUsbSeriaPortManager = USBSerialPortManager(mUsbSerialPort!!)                usbDeviceConnection = mUsbManager?.openDevice(device)                mUsbSerialPort?.open(usbDeviceConnection)                mUsbSerialPort?.setParameters(9600, 8, UsbSerialPort.StopBITS_1, UsbSerialPort.PARITY_EVEN)            } catch (e: Exception) {                XLog.tag(TAG).e(e.message)                throw Exception("设备初始化失败")            }        }    }    /**    * 实际通信调用方法-找卡    */    overrIDe fun searchCardSingle(requestData: ByteArray): Single<ByteArray>                     {        return Single.just(requestData)            .flatMap { data ->                val command = USBSerialPortManager.Command(data, data.size)                //通信                mUsbSeriaPortManager!!.execute(command)            }            .flatMap {                Single.just(it.rxBytes)            }    }}

下面这个是USBSerialPortManager工具类

import com.hoho.androID.usbserial.driver.UsbSerialPortimport io.reactivex.Singleimport io.reactivex.schedulers.Schedulersclass USBSerialPortManager(private val usbSerialPort: UsbSerialPort,                           private val writeTimeout: Int = 100,                           private val readTimeout: Int = 50) {    open class Command(val hex: String, var rxLength: Int = 0, var rx: String = "") {        val bytes: ByteArray            get() = hex.hexStringToByteArray()        val rxBytes: ByteArray            get() = rx.hexStringToByteArray()        constructor(bytes: ByteArray, rxLength: Int) : this(bytes.toHex(), rxLength, "")    }    private fun runOnceSingle(command: Command, timeoutInMillis: Int = 2000): Single<Command> {        return Single.create {            XLog.tag(TAG).i("send data=${command.hex} to $usbSerialPort")            val txBytes = command.hex.hexStringToByteArray()            usbSerialPort.write(txBytes, writeTimeout)            if (command.rxLength <= 0) {                command.rx = ""                it.onSuccess(command)                return@create            }            var times = 0L            val interval = 2L            val bytes = ByteArray(command.rxLength)            var totalLength = 0            while (totalLength < command.rxLength) {                val bytesToRead = ByteArray(command.rxLength - totalLength)                val n = usbSerialPort.read(bytesToRead, readTimeout)                if (n > 0) {                    for (i in 0 until n) {                        bytes[totalLength + i] = bytesToRead[i]                    }                    totalLength += n                }                Thread.sleep(interval)                times += interval                if (times > timeoutInMillis) {                    XLog.tag(TAG).e("read data from $usbSerialPort timeout, expect ${command.rxLength} bytes")                    it.onError(Exception("read data from $usbSerialPort timeout, expect ${command.rxLength} bytes"))                    return@create                }            }            command.rx = bytes.toHex()            XLog.tag(TAG).i("recv data=${command.rx} from $usbSerialPort")            it.onSuccess(command)        }    }    fun execute(command: Command, retryTimes: Long = 0L): Single<Command> {        return runOnceSingle(command).retry(retryTimes).subscribeOn(Schedulers.single())    }    companion object {        const val TAG = "USBSerialPortManager"    }}

代码是kotlin语言,没有写注释,目前项目已上线。工具类基本可以通用。

总结

以上是内存溢出为你收集整理的Android之USB转串口通信-基本流程全部内容,希望文章能够帮你解决Android之USB转串口通信-基本流程所遇到的程序开发问题。

如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/web/1117228.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-05-29
下一篇 2022-05-29

发表评论

登录后才能评论

评论列表(0条)

保存