Android教程網
  1. 首頁
  2. Android 技術
  3. Android 手機
  4. Android 系統教程
  5. Android 游戲
 Android教程網 >> Android技術 >> 關於Android編程 >> MUI藍牙打印(Android)

MUI藍牙打印(Android)

編輯:關於Android編程

使用MUI開發手機APP時使用藍牙打印功能可能較少使用,MUI官方並為集成藍牙打印功能,而且似乎對iPhone藍牙打印的類庫支持也不夠完善。忙完一階段後回顧下之前的工作,想想藍牙打印功能折騰了夠長時間了,寫這篇文章既是自己做個總結,也希望能給遇到同樣為藍牙打印功能掙扎的人帶來一點幫助。

以下打印的代碼中使用了一些NativeJS的方法,如果對NativeJS沒有了解的朋友,建議自行Google一下。我們直接上代碼。


頁面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. 上一頁:
      2. 下一頁:
      熱門文章
      閱讀排行版
      Copyright © Android教程網 All Rights Reserved