Android连接蓝牙打印机

时间:2021-7-20 作者:qvyue

前言

这几天,我一直在构思怎么写这篇文章,很多时候写一篇博客往往要想很久,代码也许一会就写完了。在之前写过一篇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?

    fun getBtAvailableDevice(): MutableList

    fun write(var1: ByteArray?, var2: TaskCallback)

    fun writeSendData(var1: TaskCallback, var2: ProcessData)

    fun acceptDataFromPrinter(var1: TaskCallback?, var2: Int)

    fun readBuffer(): RoundQueue?

    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? = null
    private var mDeviceFoundCallback: DeviceFoundCallback? = null
    private fun getInstanceRoundQueue(): RoundQueue {
        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? = null
        private var mBond: MutableList? = 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("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? {
            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 {
            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? {
            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? {
        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? {
        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 {
            val list = ArrayList()
            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
        }

    })
}

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

总结

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

声明:本文内容由互联网用户自发贡献自行上传,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任。如果您发现有涉嫌版权的内容,欢迎发送邮件至:qvyue@qq.com 进行举报,并提供相关证据,工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。