MUI蓝牙打印(Android)
来源:互联网 发布:李云龙 赵刚 知乎 编辑:程序博客网 时间:2024/06/06 08:25
MUI蓝牙打印(Android)
使用MUI开发手机APP时使用蓝牙打印功能可能较少使用,MUI官方并为集成蓝牙打印功能,而且似乎对iPhone蓝牙打印的类库支持也不够完善。忙完一阶段后回顾下之前的工作,想想蓝牙打印功能折腾了够长时间了,写这篇文章既是自己做个总结,也希望能给遇到同样为蓝牙打印功能挣扎的人带来一点帮助。
感谢以下几篇文章给予的帮助。
- Android 蓝牙连接 ESC/POS 热敏打印机打印(ESC/POS指令篇)
安卓Native.js蓝牙连接票据打印机完整代码已测试修改
以下打印的代码中使用了一些NativeJS的方法,如果对NativeJS没有了解的朋友,建议自行Google一下。我们直接上代码。
页面HTML
<!DOCTYPE html><html> <head> <meta charset="UTF-8"> <meta name="apple-mobile-web-app-capable" content="yes"> <meta name="apple-mobile-web-app-status-bar-style" content="black"> <!--标准mui.css--> <link rel="stylesheet" href="../../css/mui.min.css"> <link rel="stylesheet" href="../../css/wg-common.css"> <link rel="stylesheet" href="../../css/iconfont.css"> <!--App自定义的css--> <link rel="stylesheet" type="text/css" href="../../css/app.css" /> <title></title> </head> <style> .wg-info-title { background-color: white; color: #007AFF; } .mui-btn { font-size: 16px; padding: 8px; margin: 3px; } </style> <body> <header class="mui-bar mui-bar-nav" style="padding-top: 2px;"> <div style="float: left;padding-right: 8px;"> <a class="mui-action-back mui-icon mui-icon-left-nav mui-pull-left"></a> </div> <h1 id="title" class="mui-title">打印</h1> <div style="float: right;padding-right: 8px;"> <a class="mui-icon mui-icon-refreshempty" id="btnRefresh"></a> </div> </header> <div class="mui-content mui-content-padded"> <h5 class="mui-content-padded">点击设备开始连接</h5> <ul id="list1" class="mui-table-view mui-table-view-chevron"> </ul> <br /> <h5 class="mui-content-padded">点击设备开始打印</h5> <ul id="list2" class="mui-table-view mui-table-view-chevron"> </ul> </div> </body></html>
页面JS代码
// 导入的java包 var Context, BluetoothAdapter, BluetoothDevice; // 蓝牙服务与适配 var BManager, BAdapter, BluetoothSocket, mDevice, receiver; var mMain, mUUID; var vlist1 = document.getElementById('list1'); //注册容器用来显示未配对设备 var vlist2 = document.getElementById('list2'); //注册容器用来显示未配对设备 var buttonRefresh = document.getElementById('btnRefresh'); document.addEventListener('plusready', function(event) { var self = plus.webview.currentWebview(); // 打开蓝牙设备并扫描 if (mui.os.android) { // 打开蓝牙 openAndroidBluetooth(); // 设置延时,防止蓝牙未完全开启时调用 CommonUtil.WaitFor( function() { return BAdapter.isEnabled(); }, function() { // 获取已连接设备列表 getConnectedDevices(); }, 3000); } }); // 刷新(重新扫描) buttonRefresh.addEventListener('tap', function(event) { buttonRefresh.disabled = true; if (mui.os.android) { // 扫描 searchDevices(); } buttonRefresh.disabled = false; }); // list1/list2的监听事件只能用on绑定,如果使用 // li2.addEventListener('tap', function(event) { // print(li2.getAttribute('id')); // }); // 会导致打印时socket超时,具体原因不明 mui('#list1').on('tap', 'li', function() { connect(this.id); }) mui('#list2').on('tap', 'li', function() { print(this.id); }) /** *打开蓝牙(Android) */ function openAndroidBluetooth() { mMain = plus.android.runtimeMainActivity(); Context = plus.android.importClass("android.content.Context"); BManager = mMain.getSystemService(Context.BLUETOOTH_SERVICE); plus.android.importClass(BManager); //引入相关的method函数 BAdapter = BManager.getAdapter(); plus.android.importClass(BAdapter); //引入相关的method函数,这样之后才会有isEnabled函数支持 if (!BAdapter.isEnabled()) { BAdapter.enable(); } } /** * 获取已配对的蓝牙设备列表 */ function getConnectedDevices() { // var main = plus.android.runtimeMainActivity(); // var BluetoothAdapter = plus.android.importClass("android.bluetooth.BluetoothAdapter"); // var BAdapter = BluetoothAdapter.getDefaultAdapter(); //获得本机蓝牙适配器 if (!BAdapter.isEnabled()) { plus.nativeUI.toast('请先打开蓝牙'); return; } var lists = BAdapter.getBondedDevices(); //获取配对的设备列表 plus.android.importClass(lists); var iterator = lists.iterator(); plus.android.importClass(iterator); var vlist2 = document.getElementById('list2'); //注册容器用来显示未配对设备 while (iterator.hasNext()) { var d = iterator.next(); plus.android.importClass(d); var li2 = genLi(d); vlist2.appendChild(li2); } } /** *扫描蓝牙设备 */ function searchDevices() { //console.log("开始搜索设备"); if (!BAdapter.isEnabled()) { plus.nativeUI.toast('请先打开蓝牙'); return; } plus.nativeUI.showWaiting('正在搜索设备,请稍后...', { back: 'none' // 可取值"none"表示截获处理返回键,但不做任何响应;"close"表示截获处理返回键并关闭等待框;"transmit"表示不截获返回键,向后传递给Webview窗口继续处理(与未显示等待框的情况一致)。 }); vlist1.innerHTML = ''; //清空容器 vlist2.innerHTML = ''; //清空容器 // 初始化蓝牙广播接收器 initReceiver(); // 开启搜索 BAdapter.startDiscovery(); // 初始化广播信息过滤 initIntentFilter(); } function initReceiver() { BluetoothDevice = plus.android.importClass("android.bluetooth.BluetoothDevice"); var bdevice = new BluetoothDevice(); receiver = plus.android.implements('io.dcloud.android.content.BroadcastReceiver', { onReceive: function(context, intent) { //实现onReceiver回调函数 plus.android.importClass(intent); //通过intent实例引入intent类,方便以后的‘.’操作 //console.log(intent.getAction()); //获取action if (intent.getAction() == "android.bluetooth.adapter.action.DISCOVERY_FINISHED") { mMain.unregisterReceiver(receiver); //取消监听 //console.log("搜索结束") plus.nativeUI.closeWaiting(); } else { BleDevice = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE); // console.log(JSON.stringify(BluetoothDevice)); // console.log(JSON.stringify(BleDevice)); //判断是否配对 if (BleDevice.getBondState() == bdevice.BOND_NONE) { //console.log("未配对蓝牙设备:" + BleDevice.getName() + ' ' + BleDevice.getAddress()); if (!document.getElementById(BleDevice.getAddress())) { //判断防止重复添加 var li1 = genLi(BleDevice); vlist1.appendChild(li1); } } else { if (!document.getElementById(BleDevice.getAddress())) { //判断防止重复添加 //console.log("已配对蓝牙设备:" + BleDevice.getName() + ' ' + BleDevice.getAddress()); var li2 = genLi(BleDevice); vlist2.appendChild(li2); } } } } }); } function initIntentFilter() { // 设置广播信息过滤 var IntentFilter = plus.android.importClass('android.content.IntentFilter'); var filter = new IntentFilter(); filter.addAction(BluetoothDevice.ACTION_FOUND); filter.addAction(BAdapter.ACTION_DISCOVERY_STARTED); filter.addAction(BAdapter.ACTION_DISCOVERY_FINISHED); filter.addAction(BAdapter.ACTION_STATE_CHANGED); // 注册广播接收器,接收并处理搜索结果 mMain.registerReceiver(receiver, filter); } function connect(mac_address) { // 查找蓝牙设备 var unConnected = BAdapter.getRemoteDevice(mac_address); if (unConnected) { try { if (BleDevice.createBond()) { //配对命令.createBond() //console.log("配对成功"); } } catch (e) { //TODO handle the exception mui.alert('连接到设备失败'); } } } //mac_address:打印机的mac地址 function print(mac_address, str) { if (!mac_address) { mui.toast('请选择蓝牙打印机'); return; } if (mDevice == null) { // mMain = plus.android.runtimeMainActivity(); // BluetoothAdapter = plus.android.importClass("android.bluetooth.BluetoothAdapter"); // BAdapter = BluetoothAdapter.getDefaultAdapter(); UUID = plus.android.importClass("java.util.UUID"); mUUID = UUID.fromString("00001101-0000-1000-8000-00805F9B34FB"); mDevice = BAdapter.getRemoteDevice(mac_address); plus.android.importClass(mDevice); BluetoothSocket = mDevice.createInsecureRfcommSocketToServiceRecord(mUUID); } plus.android.importClass(BluetoothSocket); if (!BluetoothSocket.isConnected()) { //console.log('检测到设备未连接,尝试连接....'); try { BluetoothSocket.connect(); } catch (e) { //TODO handle the exception mui.alert('连接超时'); return; } } // 防止蓝牙未完成连接时调用打印 CommonUtil.WaitFor( function() { // 等待条件 return BluetoothSocket.isConnected(); }, function() { // 回调方法 if (!BluetoothSocket.isConnected()) { plus.nativeUI.toast('请连接打印机'); return; } printTest(); //printPictureTest(); }, 3000); } function printTest() { // 初始化PintUtil PrintUtil.init(BluetoothSocket); // 以下测试打印 var printStr = '测试打印\r\n'; // 设置字体大小 PrintUtil.SetFontSize(30); // 打印字符串 PrintUtil.PrintString(printStr); // 设置字体大小 PrintUtil.SetFontSize(20); // 打印字符串 PrintUtil.PrintString(printStr); // 重置打印机 PrintUtil.Reset(); // 打印字符串 PrintUtil.PrintString(printStr); // 切纸 PrintUtil.CutPage(); // 结束打印 PrintUtil.End(); } function genLi(bleDevice) { var li = document.createElement('li'); li.setAttribute('id', bleDevice.getAddress()); li.className = 'mui-table-view-cell'; var a = document.createElement('a'); a.setAttribute('class', 'mui-navigate-right') a.innerText = bleDevice.getName(); li.appendChild(a); return li; }
辅助方法
页面上用到的几个方法也贴出来吧。
CommonUtil.WaitFor = function(condition, callback, timeout, unitTime) { // 设置默认等待时间(循环间隔) if(!unitTime || isNaN(unitTime)) { unitTime = 100; } // 设置超时(到达超时则返回) if(!timeout || isNaN(timeout)) { timeout = 100; } if(condition && condition()) { // 等待条件成立,则执行回调 callback(); } else if(timeout - unitTime <= 0) { // 等待超时,则执行回调 callback(); } else { // 设置延时等待操作 setTimeout(function() { owner.WaitFor(condition, callback, timeout - unitTime, unitTime); }, unitTime); } };
PrintUtil打印公共方法
这里使用了一些打印机指令,具体的指令可以自己根据使用的打印机去找。
(function($, owner) { owner.OutputStream = null; owner.init = function(BluetoothSocket) { owner.OutputStream = BluetoothSocket.getOutputStream(); plus.android.importClass(owner.OutputStream); } // 设置字体大小 owner.SetFontSize = function(n) { var font = [0x1D, 0X21, n] owner.OutputStream.write(font); }; // 打印字符串 owner.PrintString = function(string) { var bytes = plus.android.invoke(string, 'getBytes', 'gbk'); owner.OutputStream.write(bytes); }; // 重置打印机 owner.Reset = function() { var reset = [0x1B, 0X40]; owner.OutputStream.write(reset); }; // 打印下划线 owner.Underline = function() { // 下划线指令 var underline = [0x1b, 0x2d, 0x01]; owner.OutputStream.write(underline); }; // 结束打印 owner.End = function() { owner.OutputStream.flush(); var end = [0x1d, 0x4c, 0x1f, 0x00]; owner.OutputStream.write(end); }; // 打印图片(暂不可用) owner.Picture = function() { var picture = [0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1B, 0x40, 0x1B, 0x33, 0x00]; // var picture = [0x1B, 0x2A]; owner.OutputStream.write(picture); }; // 切纸(暂不可用) owner.CutPage = function() { // 发送切纸指令 var end = [0x1B, 0x69]; owner.OutputStream.write(end); }; // 条形码打印(暂不可用) owner.PrintBarcode = function(n) { var barcode = [0x1D, 0x6B, 65, 5, 11, 12, 3, 6, 23]; owner.OutputStream.write(barcode); };}(mui, window.PrintUtil = {}))
好了,基本上代码都贴出来了,作为一个代码狗,很多时候我都相信:Talk is cheap, show me the code。
1 0
- MUI蓝牙打印(Android)
- Android蓝牙打印源码
- android蓝牙打印
- android 蓝牙打印
- android 蓝牙打印
- Android打印机--蓝牙打印
- Android蓝牙连接打印
- Android蓝牙相关—蓝牙打印
- android蓝牙打印的若干问题
- Android蓝牙打印格式排版
- Android控制蓝牙票据打印
- android蓝牙打印小票机Demo
- android 蓝牙打印和网络打印
- android文件打印的两种方法(外部app-printerShare-打印和蓝牙打印)
- Android蓝牙打印二维码打印外卖单打印
- Android蓝牙打印二维码打印外卖单打印
- Android pad 连接蓝牙打印机Gprinter---实现蓝牙打印功能
- Android使用PrinterShare实现蓝牙打印
- 由Integer封装与拆箱引申出的java面试题
- 51单片机输出pwm波形
- C++中重写和重载以及隐藏
- day14总结(1. 不同修饰符及自定义数据类型的使用 2. 导出javadoc(API)文档 3. jar包的导出、导入)
- Android robotium自动化测试框架 solo.getEditText(int index) BUG
- MUI蓝牙打印(Android)
- cJSON系列(1) - cJSON 入门与应用
- 使用dom解析xml
- 开发IOS App如何赚钱
- 缩进,注释,代码块,编译与优化,编码,运算符,切片
- AVL树删除算法 (使用树高)
- 准确率,召回率,F值,ROC,AUC
- linux文件目录操作命令 cat
- Java学习提要——认识'泛型'与其常见操作