美文网首页
Android连接蓝牙打印机

Android连接蓝牙打印机

作者: 辉涛 | 来源:发表于2021-05-18 21:48 被阅读0次

    前言

    在之前写过一篇Android操作蓝牙打印机(上),当时也是因为自己在工作中确实走了许多弯路,所以当时计划着用两篇文章详细阐述蓝牙打印的整个流程,也是对工作的一种总结,其次也可以给蓝牙打印方面感觉困惑的同学做一些参考,后来由于接近年底,任务比较多,所以就暂且搁置了。后来在阅读之前的代码时发现是相当繁琐(甚至感觉有些地方考虑的很复杂),最明显的复杂就是通过广播去监听蓝牙的状态,操作起来相当繁琐,久而久之,随着业务场景的增多,就出了bug,最头疼的就是与业务代码参杂在一起,不够解耦,也包括后来测试也给我提了bug,导致在bug系统挂了很久,前几天的一天早上项目经理也问我什么时候把这个bug处理一下,其实早在五一之前我就对此次重构做了一个大概了,只是一些周边细节未完善,这几天也是抽了许多时间优化,测试,把项目相关模块重构,将蓝牙部分抽取出来以依赖的方式集成在项目中。

    git地址

    传送门https://github.com/zhuhuitao/printer
    在你的app build.gradle 中添加如下代码:

    
    dependencies {
        ...
        implementation "com.github.zhuhuitao:printer:1.0.9"
    }
    

    在上一篇文章之后,有好几个小伙伴私信我,能不能把源码放到git,参考一下,这里我统一回复,当时由于整个蓝牙部分与业务参杂在一起,并没有一个完整的demo,后来也没有上传,所以给之前带来不便的小伙伴,说一声抱歉。

    功能介绍

    在之前的文章中从头到尾是阐述了如何扫描,连接蓝牙,大都与蓝牙相关,此次与之前大为不同,这里我们只需要将相关依赖导入项目中,我们可以将所有精力放到我们业务代码中,不需要在关心蓝牙部分,依赖已将所有蓝牙部分做了封装,我们只管调用接口完成打印就好。并且这次重构简化了许多代码,结构清晰,也去掉了广播监听,等等许多繁琐的地方。

    在阐述使用之前我还是将整个依赖的大体功能做一些介绍:
    1,核心接口IMyBinder类,这个类主要是与我们业务打交道的接口,包括我们连接蓝牙,往蓝牙打印机写入数据,断开蓝牙等相关功能,代码如下:

    /**
     *author  : huitao
     *e-mail  : pig.huitao@gmail.com
     *date    : 2021/4/13 10:42
     *desc    :
     *version :
     */
    interface IMyBinder {
        fun connectBtPort(var1: String, var2: TaskCallback)
    
        fun disconnectCurrentPort(var1: TaskCallback)
    
        fun clearBuffer()
    
        fun checkLinkedState(var1: TaskCallback)
    
        fun onDiscovery(
            var1: Context,
            portType: PrinterDev.PortType,
            callback: DeviceFoundCallback
        ): MutableList<String>?
    
        fun getBtAvailableDevice(): MutableList<String>
    
        fun write(var1: ByteArray?, var2: TaskCallback)
    
        fun writeSendData(var1: TaskCallback, var2: ProcessData)
    
        fun acceptDataFromPrinter(var1: TaskCallback?, var2: Int)
    
        fun readBuffer(): RoundQueue<ByteArray?>?
    
        fun read(var1: TaskCallback)
    }
    

    2,核心服务PrinterService类,在这个类中,实现了上述提到的IMyBinder接口,主要是对上一步IMyBinder接口做了进一步描述,代码如下:

    class PrinterService : Service() {
        private val mMyBinder = MyBinder()
        private lateinit var mPrinterDev: PrinterDev
        private lateinit var mReturnMsg: ReturnMessage
        private var mIsConnected = false
        private var mQueue: RoundQueue<ByteArray>? = null
        private var mDeviceFoundCallback: DeviceFoundCallback? = null
        private fun getInstanceRoundQueue(): RoundQueue<ByteArray> {
            if (this.mQueue == null) {
                mQueue = RoundQueue(500)
            }
            return this.mQueue!!
        }
    
        override fun onCreate() {
            super.onCreate()
            this.mQueue = this.getInstanceRoundQueue()
        }
    
    
        private val mViewModelScope = CoroutineScope(Dispatchers.IO)
        override fun onBind(p0: Intent?): IBinder {
            return this.mMyBinder
        }
    
    
        inner class MyBinder : Binder(), IMyBinder {
            private var mBluetoothAdapter: BluetoothAdapter? = null
            private var mFond: MutableList<String>? = null
            private var mBond: MutableList<String>? = null
            private var mPortType: PrinterDev.PortType? = null
            private val mReceiver = object : BroadcastReceiver() {
                override fun onReceive(p0: Context?, p1: Intent?) {
                    if (p1?.action == "android.bluetooth.device.action.FOUND") {
    
                        val device =
                            p1.getParcelableExtra<BluetoothDevice>("android.bluetooth.device.extra.DEVICE")
                                ?: return
                        if (!device.name.isNullOrEmpty()) {
                            mFond?.forEach {
                                if (it.split("\n").last() == device.address) {
                                    return
                                }
                            }
                            mFond?.add("${device.name}\n${device.address}")
                            mDeviceFoundCallback?.deviceFoundCallback("${device.name} \n ${device.address}")
    
                        }
                    }
                }
            }
    
            override fun connectBtPort(var1: String, var2: TaskCallback) {
                mViewModelScope.launch {
                    mPrinterDev = PrinterDev(PrinterDev.PortType.Bluetooth, var1)
                    mReturnMsg = this@PrinterService.mPrinterDev.open()
                    mPortType = PrinterDev.PortType.Bluetooth
                    mViewModelScope.launch(Dispatchers.Main) {
                        when (mReturnMsg.getErrorCode()) {
                            PrinterDev.ErrorCode.OpenPortSucceed -> {
                                mIsConnected = true
                                var2.onSucceed()
                            }
                            else -> {
                                var2.onFailed()
                            }
                        }
                    }
                }
            }
    
            override fun disconnectCurrentPort(var1: TaskCallback) {
                mViewModelScope.launch {
                    mReturnMsg = mPrinterDev.close()
                    mViewModelScope.launch(Dispatchers.Main) {
                        when (mReturnMsg.getErrorCode()) {
                            PrinterDev.ErrorCode.ClosePortSucceed -> {
                                mIsConnected = false
                                if (mQueue != null) {
                                    mQueue?.clear()
                                }
                                var1.onSucceed()
                            }
                            else -> {
                                var1.onFailed()
                            }
                        }
                    }
                }.start()
            }
    
            override fun clearBuffer() {
                mQueue?.clear()
            }
    
            override fun checkLinkedState(var1: TaskCallback) {
                mViewModelScope.launch {
                    if (mPrinterDev.getPortInfo().isOpened) var1.onSucceed() else var1.onFailed()
                }.start()
            }
    
            override fun onDiscovery(
                var1: Context,
                portType: PrinterDev.PortType,
                callback: DeviceFoundCallback
            ): MutableList<String>? {
                this.mFond = mutableListOf()
                this.mBond = mutableListOf()
                mDeviceFoundCallback = callback
                if (portType == PrinterDev.PortType.Bluetooth) {
                    this.mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter()
                    if (mBluetoothAdapter == null) {
                        Toast.makeText(
                            this@PrinterService,
                            "Device didn't support bluetooth !\n",
                            Toast.LENGTH_SHORT
                        ).show()
                        return null
                    }
                    if (mBluetoothAdapter!!.isEnabled) {
                        if (mBluetoothAdapter!!.enable()) {
                            if (!mBluetoothAdapter!!.isDiscovering) {
                                mBluetoothAdapter!!.startDiscovery()
                            }
                            val filter = IntentFilter("android.bluetooth.device.action.FOUND")
                            registerReceiver(mReceiver, filter)
                            val pairedDevice = mBluetoothAdapter!!.bondedDevices
                            if (!pairedDevice.isNullOrEmpty()) {
                                val it = pairedDevice.iterator()
                                while (it.hasNext()) {
                                    val device = it.next()
                                    mBond?.add("${device.name}\n${device.address}")
                                }
                            } else {
                                Looper.prepare()
                                Toast.makeText(
                                    this@PrinterService,
                                    "no paired device",
                                    Toast.LENGTH_SHORT
                                ).show()
                                Looper.loop()
                            }
                        } else {
                            Toast.makeText(
                                this@PrinterService,
                                "Bluetooth is not enable !\n",
                                Toast.LENGTH_SHORT
                            ).show()
                        }
                    } else {
                        Toast.makeText(
                            this@PrinterService,
                            "Bluetooth adapter is not enabled !\n",
                            Toast.LENGTH_SHORT
                        ).show()
                    }
    
                }
                return this.mBond
            }
    
            override fun getBtAvailableDevice(): MutableList<String> {
                this.mBluetoothAdapter?.cancelDiscovery()
                return this.mFond!!
            }
    
            override fun write(var1: ByteArray?, var2: TaskCallback) {
                if (var1 != null) {
                    mViewModelScope.launch {
                        mReturnMsg = mPrinterDev.write(var1)
                        mViewModelScope.launch(Dispatchers.Main) {
                            when (mReturnMsg.getErrorCode()) {
                                PrinterDev.ErrorCode.WriteDataSucceed -> {
                                    mIsConnected = true
                                    var2.onSucceed()
                                }
                                else -> {
                                    mIsConnected = false
                                    var2.onFailed()
                                }
                            }
                        }
                    }
                }
            }
    
            override fun writeSendData(var1: TaskCallback, var2: ProcessData) {
                val list = var2.processDataBeforeSend()
                if (list == null) {
                    var1.onFailed()
                } else {
                    mViewModelScope.launch {
                        list.forEach {
                            mReturnMsg = mPrinterDev.write(it)
                        }
                        when (mReturnMsg.getErrorCode()) {
                            PrinterDev.ErrorCode.WriteDataSucceed -> {
                                mIsConnected = true
                                var1.onSucceed()
                            }
                            else -> {
                                mIsConnected = false
                                var1.onFailed()
                            }
                        }
                    }.start()
                }
            }
    
            override fun acceptDataFromPrinter(var1: TaskCallback?, var2: Int) {
                val buffer = ByteArray(var2)
                mViewModelScope.launch {
                    kotlin.runCatching {
                        mQueue = getInstanceRoundQueue()
                        mQueue?.clear()
                        mQueue?.addLast(buffer)
                        Log.i("frank", "acceptDataFromPrinter: " + Arrays.toString(mQueue!!.last))
                    }.onSuccess {
    
                    }.onFailure {
    
                    }
                }
            }
    
            override fun readBuffer(): RoundQueue<ByteArray?>? {
                return null
            }
    
            override fun read(var1: TaskCallback) {
                mViewModelScope.launch {
                    val msg = mPrinterDev.read()
                    Log.d("frank", "read: $msg")
                }
            }
    
        }
    }
    

    在我们使用的时候仅和这两个类做了相关调用,由于我主要想讲述如何使用此依赖,所以暂且介绍了这两个类,如果感兴趣可以直接阅读源码,这样更快捷。

    使用

    一般我们都是将蓝牙部分运用在项目中,并不像我们写个demo学习那样简单,我也思考着怎么把demo写的更贴实际,但是终究demo功能还是很单一,没有实际业务那么复杂,所以建议只是做参考。

    1,创建服务MyService类继承android 中的Service,其实为了简单,也可以不创建服务,为了更贴实际项目,所以创建了MyService,这个服务主要是用来启动我们蓝牙模块中的PrinterService,以及启动另外一个辅助服务AncillaryService,辅助服务接下来我再另外介绍,最后也就是与我们业务做交互,比如与Activity做交互发送接收数据。MyService主要是我们业务的Activity与PrintService中间的桥梁,详细代码如下:

    /**
     *author  : huitao
     *e-mail  : pig.huitao@gmail.com
     *date    : 2021/5/17 18:07
     *desc    :
     *version :
     */
    class MyService : Service() {
        private var mIMyBinder: IMyBinder? = null
        private val mServiceConnect = object : ServiceConnection {
            override fun onServiceConnected(name: ComponentName?, service: IBinder?) {
                mIMyBinder = service as IMyBinder
                val mac = ""
                connectByMac(mac, object : TaskCallback {
                    override fun onSucceed() {
    
                    }
    
                    override fun onFailed() {
    
                    }
                })
            }
    
            override fun onServiceDisconnected(name: ComponentName?) {
            }
        }
    
        fun getBondDeviceList(): MutableList<String>? {
            return mIMyBinder?.onDiscovery(
                this,
                PrinterDev.PortType.Bluetooth,
                object : DeviceFoundCallback {
                    override fun deviceFoundCallback(device: String) {
                        //这里接收扫描的周围蓝牙设备
                    }
                })
        }
    
    
        fun writeData(bean: OrderBean, task: TaskCallback) {
            printOrderDetail(mMyBinder = mIMyBinder!!, order = bean, taskCallback = task)
        }
    
        fun connectByMac(mac: String, task: TaskCallback) {
            if (mac.isNotEmpty()) {
                mIMyBinder?.connectBtPort(mac, task)
            }
        }
    
        fun disconnect(task: TaskCallback) {
            mIMyBinder?.disconnectCurrentPort(task)
        }
    
        override fun onCreate() {
            super.onCreate()
            val intent = Intent(this, AncillaryService::class.java)
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
                AncillaryService.startForeground(this)
                startForegroundService(intent)
            } else {
                startService(intent)
            }
    
            val service = Intent(this, PrinterService::class.java)
            bindService(service, mServiceConnect, BIND_AUTO_CREATE)
        }
    
        override fun onBind(p0: Intent?): IBinder {
            return MyBinder()
        }
    
    
        inner class MyBinder : Binder() {
            fun getService(): MyService {
                return this@MyService
            }
        }
    }
    

    2,关于辅助服务AncillaryService,也是继承android Service,这个类主要是用来在手机通知栏弹出一个应用正在运行的功能,因为实际项目中可以尽可能的减少被系统杀死的概率,由于我们主要任务不在此处,包括8.0之前与之后系通知栏的变化,如果你感兴趣,还是建议收集资料详细的了解,比如实际代码中,我在onCreate直接停止了服务 stopSelf(),这个主要是在7.0之前有效,就是可以做一个假象,通知栏不会存在通知。详细代码如下:

    /**
     *author  : huitao
     *e-mail  : pig.huitao@gmail.com
     *date    : 2021/5/17 18:39
     *desc    :
     *version :
     */
    class AncillaryService:Service() {
        override fun onBind(intent: Intent?): IBinder? {
            return null
        }
    
        override fun onCreate() {
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
                startForeground(this)
            }
            stopSelf()
        }
    
        override fun onDestroy() {
            super.onDestroy()
            stopForeground(true)
        }
    
        companion object{
            fun startForeground(ctx: Service) {
                try {
                    val CHANNEL_ONE_ID = "CHANNEL_ONE_ID"
                    val CHANNEL_ONE_NAME = "CHANNEL_ONE_ID"
                    val SERVICE_ID = 802
                    val notificationChannel: NotificationChannel
                    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
                        notificationChannel = NotificationChannel(
                            CHANNEL_ONE_ID, CHANNEL_ONE_NAME, NotificationManager.IMPORTANCE_HIGH
                        )
                        notificationChannel.enableLights(true)
                        notificationChannel.lightColor = R.color.app_them
                        notificationChannel.setShowBadge(true)
                        notificationChannel.lockscreenVisibility = Notification.VISIBILITY_PUBLIC
                        val nm = ctx.getSystemService(NOTIFICATION_SERVICE) as NotificationManager
                        nm.createNotificationChannel(notificationChannel)
                    }
                    val intent = Intent()
                    val className = Class.forName("com.huitao.printerdemo.printer.PrinterActivity")
                    intent.setClassName(ctx, className.name)
                    val pendingIntent = PendingIntent.getActivity(ctx, 0, intent, 0)
                    val builder = NotificationCompat.Builder(ctx, CHANNEL_ONE_ID)
                    builder.setContentTitle(ctx.getString(R.string.pending_title))
                        .setContentText(ctx.getString(R.string.pending_content))
                        .setWhen(System.currentTimeMillis())
                        .setPriority(Notification.PRIORITY_MIN)
                        .setSmallIcon(R.mipmap.ic_launcher)
                        .setContentIntent(pendingIntent)
                        .setAutoCancel(true)
                    val notification = builder.build()
                    ctx.startForeground(SERVICE_ID, notification)
                } catch (e: ClassNotFoundException) {
                    e.printStackTrace()
                }
            }
        }
    }
    

    3,业务层的PrinterActivity,这个类中的主要功能就是绑定我们前面提到的MyService,布局中写了两个textView和一个RecyclerView,用来获取绑定设备,测试打印,以及展示已绑定的设备列表。绑定服务以及列表展示就不做相关详细介绍,重点介绍一下连接,断开,获取设备列表功能。

    a,获取已绑定的设备:

    mBinder?.getService()?.getBondDeviceList()
    

    这行代码就会帮我们返回手机已绑定的蓝牙设备,具体获取是在PrinterService中实现的,前面有相关代码,看到这里我想你大概会存在疑问,如何获取周围的蓝牙设备,这可不必大有担心,也有实现,在PrinterService中,有以下代码:

        fun getBondDeviceList(): MutableList<String>? {
            return mIMyBinder?.onDiscovery(
                this,
                PrinterDev.PortType.Bluetooth,
                object : DeviceFoundCallback {
                    override fun deviceFoundCallback(device: String) {
                        //这里接收扫描的周围蓝牙设备
                    }
                })
        }
    

    我们可以在此处理扫描的周围蓝牙设备,也可以直接将集合回调到Activity层。

    b,连接蓝牙,实际是一个耗时操作,底层已使用协程做了耗时处理,所以此处我们不必关心耗时相关代码,只关心回调给我们的连接状态,处理业务就好,详细代码如下:

         mBinder?.getService()?.connectByMac(mList[obj].name.split("\n").last().trim(),
                        object : TaskCallback {
                            override fun onSucceed() {
                                Toast.makeText(
                                    this@PrinterActivity,
                                    getString(R.string.connect_success),
                                    Toast.LENGTH_SHORT
                                ).show()
                                mIsConnect = true
                                mList[obj].isConnected = true
                                mAdapter.notifyItemChanged(obj)
                            }
    
                            override fun onFailed() {
                                Toast.makeText(
                                    this@PrinterActivity,
                                    getString(R.string.connect_failure),
                                    Toast.LENGTH_SHORT
                                ).show()
                            }
                        })
    

    c,断开连接,实际调用接口和连接一样,详细代码如下,不做过多介绍:

     mBinder?.getService()?.disconnect(object : TaskCallback {
                        override fun onSucceed() {
                            Toast.makeText(
                                this@PrinterActivity,
                                getString(R.string.disconnect_success),
                                Toast.LENGTH_SHORT
                            ).show()
                            mList[obj].isConnected = false
                            mAdapter.notifyItemChanged(obj)
                            mIsConnect = false
                        }
    
                        override fun onFailed() {
                            Toast.makeText(
                                this@PrinterActivity,
                                getString(R.string.disconnect_failure),
                                Toast.LENGTH_SHORT
                            ).show()
                        }
                    })
    

    d,最后介绍以下启动app后自动连接的功能,此方法在MyService中有实现,由于demo中没有使用数据库或者sp等存储功能,所以只写了一个样板,我们可以将上一次连接蓝牙mac,缓存在本地或者数据库中,下次在启动服务时,直接调用连接蓝牙功能连接蓝牙,代码如下:

        private val mServiceConnect = object : ServiceConnection {
            override fun onServiceConnected(name: ComponentName?, service: IBinder?) {
                mIMyBinder = service as IMyBinder
                val mac = ""
                connectByMac(mac, object : TaskCallback {
                    override fun onSucceed() {
    
                    }
    
                    override fun onFailed() {
    
                    }
                })
            }
    
            override fun onServiceDisconnected(name: ComponentName?) {
            }
        }
    

    e,最后就是向蓝牙打印机写入数据,写入数据也是耗时操作,不过我们完全不用关心此问题,我们直接调用writeSendData就可以发送数据,完成打印功能,这里做了一个巧妙的设计,将我们的所有要打印的byte字节装入一个list集合,传给下层服务,可以直接完成打印,并且下层还将打印结果成功或者失败状态返回来,demo中的相关代码如下:

    fun printOrderDetail(mMyBinder: IMyBinder, order: OrderBean, taskCallback: TaskCallback) {
        mMyBinder.writeSendData(taskCallback, object : ProcessData {
            override fun processDataBeforeSend(): MutableList<ByteArray> {
                val list = ArrayList<ByteArray>()
                list.add(DataForSendToPrinter.initializePrinter())
                list.add(DataForSendToPrinter.selectAliment(0x01))
                list.add(DataForSendToPrinter.selectFontSize(0x11))
                list.add(strToBytes("#${order.pickUpCode} 测试外卖")!!)
                list.add(DataForSendToPrinter.printAndFeedLine())
                list.add(DataForSendToPrinter.printAndFeedLine())
    
                list.add(DataForSendToPrinter.initializePrinter())
                list.add(DataForSendToPrinter.selectAliment(0x01))
                list.add(DataForSendToPrinter.selectFontSize(0x01))
                list.add(strToBytes("*${order.shopName}*")!!)
                list.add(DataForSendToPrinter.printAndFeedLine())
                list.add(DataForSendToPrinter.printAndFeedLine())
    
                list.add(DataForSendToPrinter.initializePrinter())
                list.add(DataForSendToPrinter.selectFontSize(0x11))
                list.add(DataForSendToPrinter.selectAliment(0x01))
                list.add(strToBytes("--已在线支付--")!!)
                list.add(DataForSendToPrinter.printAndFeedLine())
                list.add(DataForSendToPrinter.printAndFeedLine())
    
                list.add(DataForSendToPrinter.initializePrinter())
                list.add(DataForSendToPrinter.printBothColumns("配送方式:", order.deliveryTypeStr))
                list.add(DataForSendToPrinter.printAndFeedLine())
                list.add(DataForSendToPrinter.printAndFeedLine())
    
                list.add(DataForSendToPrinter.initializePrinter())
                list.add(DataForSendToPrinter.printBothColumns("下单时间:", order.createTime))
                list.add(DataForSendToPrinter.printAndFeedLine())
                list.add(DataForSendToPrinter.printAndFeedLine())
    
                val onTime = order.receiveTime
                if (onTime != null) {
                    list.add(DataForSendToPrinter.initializePrinter())
                    list.add(DataForSendToPrinter.printBothColumns("预计送达时间:", onTime))
                    list.add(DataForSendToPrinter.printAndFeedLine())
                    list.add(DataForSendToPrinter.printAndFeedLine())
                }
    
                list.add(DataForSendToPrinter.initializePrinter())
                list.add(DataForSendToPrinter.selectOrCancelBoldModel(0x01))
                list.add(strToBytes("客户留言:")!!)
                list.add(DataForSendToPrinter.printAndFeedLine())
                list.add(DataForSendToPrinter.printAndFeedLine())
                if (order.remarks == null) {
                    list.add(DataForSendToPrinter.printAndFeedLine())
                    list.add(DataForSendToPrinter.printAndFeedLine())
                } else {
                    list.add(strToBytes(order.remarks)!!)
                }
                list.add(DataForSendToPrinter.printAndFeedLine())
                list.add(DataForSendToPrinter.printAndFeedLine())
    
                list.add(DataForSendToPrinter.initializePrinter())
                if (order.receiver != null && order.receiver.isNotEmpty()) {
                    list.add(
                        DataForSendToPrinter.printBothColumns(
                            "收货人:",
                            "${order.receiver.substring(0, 1)}**"
                        )
                    )
                    list.add(DataForSendToPrinter.printAndFeedLine())
                    list.add(DataForSendToPrinter.printAndFeedLine())
                }
                if (order.receiverMobile != null) {
                    list.add(DataForSendToPrinter.printBothColumns("电话:", order.receiverMobile))
                    list.add(DataForSendToPrinter.printAndFeedLine())
                    list.add(DataForSendToPrinter.printAndFeedLine())
                }
                if (order.riderName != null) {
                    list.add(DataForSendToPrinter.printBothColumns("骑手:", order.riderName))
                    list.add(DataForSendToPrinter.printAndFeedLine())
                    list.add(DataForSendToPrinter.printAndFeedLine())
                }
                if (order.riderMobile != null) {
                    list.add(DataForSendToPrinter.printBothColumns("电话:", order.riderMobile))
                    list.add(DataForSendToPrinter.printAndFeedLine())
                    list.add(DataForSendToPrinter.printAndFeedLine())
                }
                if (order.address != null) {
                    list.add(strToBytes("收货地址:${order.address}")!!)
                    list.add(DataForSendToPrinter.printAndFeedLine())
                    list.add(DataForSendToPrinter.printAndFeedLine())
                }
                list.add(DataForSendToPrinter.printThreeColumns("名称", "数量", "售价"))
                list.add(DataForSendToPrinter.printAndFeedLine())
                list.add(DataForSendToPrinter.printAndFeedLine())
                order.orderDetailList.forEach {
                    val price = when (it.isDiscount) {
                        1 -> numberFormat(it.amount)
                        else -> numberFormat(it.shopPrice)
                    }
                    list.add(DataForSendToPrinter.initializePrinter())
                    list.add(DataForSendToPrinter.selectOrCancelBoldModel(0x01))
                    list.add(strToBytes(it.goodsName)!!)
                    list.add(DataForSendToPrinter.printAndFeedLine())
                    list.add(DataForSendToPrinter.printThreeColumns("", "${it.buyCount}", "¥$price"))
                    list.add(DataForSendToPrinter.printAndFeedLine())
                    list.add(DataForSendToPrinter.printAndFeedLine())
                }
    
                list.add(DataForSendToPrinter.initializePrinter())
                list.add(
                    DataForSendToPrinter.printBothColumns(
                        "订单原价:",
                        "¥${numberFormat(order.money)}"
                    )
                )
                list.add(DataForSendToPrinter.printAndFeedLine())
                list.add(DataForSendToPrinter.printAndFeedLine())
                list.add(
                    DataForSendToPrinter.printBothColumns(
                        "配送费:",
                        "¥${numberFormat(order.freight)}"
                    )
                )
                list.add(DataForSendToPrinter.printAndFeedLine())
                list.add(DataForSendToPrinter.printAndFeedLine())
                list.add(
                    DataForSendToPrinter.printBothColumns(
                        "实付金额:",
                        "¥${numberFormat(order.payMoney)}"
                    )
                )
                list.add(DataForSendToPrinter.printAndFeedLine())
                list.add(DataForSendToPrinter.printAndFeedLine())
                list.add(DataForSendToPrinter.printBothColumns("订单类型:", order.orderTypeStr))
                list.add(DataForSendToPrinter.printAndFeedLine())
                list.add(DataForSendToPrinter.printAndFeedLine())
                if (order.orderTypeStr.contains("预约")) {
                    list.add(DataForSendToPrinter.printBothColumns("预约时间:", order.appointmentTime))
                    list.add(DataForSendToPrinter.printAndFeedLine())
                    list.add(DataForSendToPrinter.printAndFeedLine())
                }
                list.add(DataForSendToPrinter.printBothColumns("订单号:", order.orderCode))
                list.add(DataForSendToPrinter.printAndFeedLine())
                list.add(DataForSendToPrinter.printAndFeedLine())
                list.add(DataForSendToPrinter.printAndFeedLine())
                return list
            }
    
        })
    }
    

    至此,介绍了整个依赖的详细使用,由于篇幅原因,不能贴入全部代码,如果感兴趣,还是建议直接查看源码。

    总结

    以上仅是对工作的一种总结,我也将一直持续维护此项目,由于个人经验能力不足,可能还存在些许问题,如果你觉得不合理,欢迎留言讨论,或者直接提出你的建议,我直接将你的想法写进项目中。

    相关文章

      网友评论

          本文标题:Android连接蓝牙打印机

          本文链接:https://www.haomeiwen.com/subject/wknyjltx.html