蓝牙打印_蓝牙打印机 - CSDN
  • 蓝牙打印机

    2019-04-03 14:23:13
    小号字体加粗 esc.addSelectPrintModes(EscCommand.FONT.**FONTA**, EscCommand.ENABLE.**ON**, EscCommand.ENABLE.**OFF**, EscCommand.ENABLE.**OFF**, EscCommand.ENABLE.**OFF**); // 设置为倍高倍宽 ...
     小号字体加粗
        esc.addSelectPrintModes(EscCommand.FONT.**FONTA**, EscCommand.ENABLE.**ON**, EscCommand.ENABLE.**OFF**, EscCommand.ENABLE.**OFF**, EscCommand.ENABLE.**OFF**);
    

    // 设置为倍高倍宽
    esc.addSelectPrintModes(EscCommand.FONT.FONTB, EscCommand.ENABLE.OFF, EscCommand.ENABLE.ON, EscCommand.ENABLE.ON, EscCommand.ENABLE.OFF);
    // 设置打印居中
    esc.addSelectJustification(EscCommand.JUSTIFICATION.CENTER);

    展开全文
  • 这段时间公司给人开发连接打印机的手机端APP时候做的一个小的例子,直接打开手机蓝牙,连接打印机,还有就是打印出来的内容我直接在程序里面写死了,大家可以修改一下,就能用了,用的Androidstudio开发的。...
  • 蓝牙打印方案

    2020-07-27 23:31:55
    在很多近距离的数据传输方面,蓝牙技术的应用已经趋于普及化,其中以...与此同时,蓝牙打印机的安全性是比较受到用户关注的问题之一,它既要防止不经许可就进行打印的现象,又要确保打印至打印机的信息不被他人截获。
  • h5+连接蓝牙打印机打印小票

    千次阅读 热门讨论 2019-12-11 16:00:04
    由于所在公司产品需要一个骑手端自动接单,接单后自动打印小票的功能,所以将原有的公众号做成了app,调用蓝牙打印机打印小票。 运用框架:mui.js;jquery(不要吐槽,是原有基础上改。。~ 摊手手~) html: <div ...

    由于所在公司产品需要一个骑手端自动接单,接单后自动打印小票的功能,所以将原有的公众号做成了app,调用蓝牙打印机打印小票。
    运用框架:mui.js;jquery(不要吐槽,是原有基础上改。。~ 摊手手~)
    html:

    <div class="main-box mui-off-canvas-wrap">
        <!-- 菜单容器 -->
    	  <aside class="mui-off-canvas-left">	
    		<div class="mui-scroll-wrapper">
    		  <div class="mui-scroll" id="offCanvasSideScroll">
    			<!-- 菜单具体展示内容 -->
    			  <div class="mui-btn">
    				<input id="bt1" class="mui-icon mui-icon-search" type="button" value="点击搜索设备" onclick="searchDevices('a')">
    			  </div>
    			  <div class="title">未配对蓝牙设备</div>
    			  <ul class="mui-table-view" id="list1">
    				<li class="mui-table-view-cell"></li>
    			  </ul>
    			  <div class="title">已配对蓝牙设备</div>
    			  <ul class="mui-table-view" id="list2">
    				<li class="mui-table-view-cell"></li>
    			  </ul>
    		  </div>
    		</div>
    	  </aside>
    	  <div class="mui-inner-wrap">
    		<div id="backdrop" class="mui-off-canvas-backdrop"></div>
    		<div >主体内容省略。。。</div>
    	</div>
    </div>
    

    大概就是下面的样子:
    在这里插入图片描述
    js来了:

    var device = null,
    	BAdapter = null,
    	BluetoothAdapter = null,
    	uuid = null,
    	main = null,
    	bluetoothSocket = null;
    mui.plusReady(function(){
    //如果已经连接过,就自动连接
    	if(localStorage.getItem('macaddress')){
    		connectFun(localStorage.getItem('macaddress'));
    	}
    })
    //手动搜索蓝牙
    //address=""搜索蓝牙//address=设备mac地址,自动配对给出mac地址的设备  
    function searchDevices(address) {
    	//注册类  
    	var main = plus.android.runtimeMainActivity();
    	var IntentFilter = plus.android.importClass('android.content.IntentFilter');
    	var BluetoothAdapter = plus.android.importClass("android.bluetooth.BluetoothAdapter");
    	var BluetoothDevice = plus.android.importClass("android.bluetooth.BluetoothDevice");
    	var BAdapter = BluetoothAdapter.getDefaultAdapter();
    	if (!BAdapter.isEnabled()) {
    		plus.nativeUI.confirm("蓝牙处于关闭状态,是否打开?", function(e) {
    			console.log(e.index)
    			if (e.index == 0) {
    				BAdapter.enable();
    				searchDevices();
    			}else{
    				mui.toast('请打开蓝牙')
    			}
    		});
    		console.log(BAdapter.isEnabled())
    	} else{
    		
    	var filter = new IntentFilter();
    	var bdevice = new BluetoothDevice();
    	var on = null;
    	var un = null;
    	var vlist1 = document.getElementById('list1'); //注册容器用来显示未配对设备  
    	vlist1.innerHTML = ''; //清空容器  
    	var vlist2 = document.getElementById('list2'); //注册容器用来显示未配对设备  
    	vlist2.innerHTML = ''; //清空容器  
    	var button1 = document.getElementById('bt1');
    	button1.disabled = true;
    	button1.value = '正在搜索请稍候...';
    	BAdapter.startDiscovery(); //开启搜索  
    	var receiver;
    	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") {
    				main.unregisterReceiver(receiver); //取消监听  
    				button1.disabled = false;
    				button1.value = '搜索设备';
    			} else {
    				BleDevice = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
    				//判断是否配对  
    				if (BleDevice.getBondState() == bdevice.BOND_NONE) {
    					console.log("未配对蓝牙设备:" + BleDevice.getName() + '    ' + BleDevice.getAddress());
    					//参数如果跟取得的mac地址一样就配对  
    					if (address == BleDevice.getAddress()) {
    						if (BleDevice.createBond()) { //配对命令.createBond()  
    							var li2 = document.createElement('li'); //注册  
    							li2.setAttribute('id', BleDevice.getAddress()); //打印机mac地址  
    							li2.setAttribute('onclick', 'connectFun(id)'); //注册click点击列表进行打印  
    							li2.innerText = BleDevice.getName();
    							vlist2.appendChild(li2);
    						}
    
    					} else {
    						if (BleDevice.getName() != on) { //判断防止重复添加  
    							var li1 = document.createElement('li'); //注册  
    							li1.setAttribute('id', BleDevice.getAddress()); //打印机mac地址  
    							li1.setAttribute('onclick', 'searchDevices(id)'); //注册click点击列表进行配对  
    							on = BleDevice.getName();
    							li1.innerText = on;
    							vlist1.appendChild(li1);
    
    						}
    
    					}
    				} else {
    					if (BleDevice.getName() != un) { //判断防止重复添加  
    						console.log("已配对蓝牙设备:" + BleDevice.getName() + '    ' + BleDevice.getAddress());
    						var li2 = document.createElement('li'); //注册  
    						li2.setAttribute('id', BleDevice.getAddress()); //打印机mac地址  
    						li2.setAttribute('onclick', 'connectFun(id)'); //注册click点击列表进行打印  
    						un = BleDevice.getName();
    						li2.innerText = un;
    						vlist2.appendChild(li2);
    					}
    				}
    			}
    
    		}
    	});
    
    	filter.addAction(bdevice.ACTION_FOUND);
    	filter.addAction(BAdapter.ACTION_DISCOVERY_STARTED);
    	filter.addAction(BAdapter.ACTION_DISCOVERY_FINISHED);
    	filter.addAction(BAdapter.ACTION_STATE_CHANGED);
    
    	main.registerReceiver(receiver, filter); //注册监听  
    	}
    }
        function connectFun(macaddress){
          // var macaddress = localStorage.getItem("macaddress");
          if(!macaddress) {
            mui.toast('请选择蓝牙打印机');
            return;
          }
          localStorage.setItem("macaddress", macaddress);
          main = plus.android.runtimeMainActivity();
          BluetoothAdapter = plus.android.importClass("android.bluetooth.BluetoothAdapter");
          UUID = plus.android.importClass("java.util.UUID");
          uuid = UUID.fromString("00001101-0000-1000-8000-00805F9B34FB");
          BAdapter = BluetoothAdapter.getDefaultAdapter();
          device = BAdapter.getRemoteDevice(macaddress);
          plus.android.importClass(device);
          bluetoothSocket = device.createInsecureRfcommSocketToServiceRecord(uuid);
          plus.android.importClass(bluetoothSocket);
          
          if (!bluetoothSocket.isConnected()) {
            console.log('检测到设备未连接,尝试连接....');
            bluetoothSocket.connect();
          }
          mui.toast('打印机已就绪,可正常打印!');
         // $('#searchBluetooth').html('已连接设备');
         // if(autoReceipt == 1){
         //   timer = setInterval(() => {
         //     orderRefresh()//后台自动接单就打印,所以前端要做轮询~无奈~
        //    }, 20000);
       //   }
           device = null //这里关键
         bluetoothSocket.close(); //必须关闭蓝牙连接否则意外断开的话打印错误
    } 
    //打印函数差点忘了:公司使用的打印机指令集为ESC/POS,其它自行百度
    function printOrder(obj){
    	macaddress = localStorage.getItem('macaddress');
    	  var BAdapter = BluetoothAdapter.getDefaultAdapter();
    	  if(bluetoothSocket==null){
    		  mui.toast('请连接蓝牙')
    		  return false;
    		}else{
    		 if (bluetoothSocket.isConnected()) {
    			if(BAdapter.isEnabled()){
    				console.log('xxxxx ' + device);
    				outputStream = bluetoothSocket.getOutputStream();
    				plus.android.importClass(outputStream);
    			 	outputStream.write([0x1B,0x40]);//打印复位
    		 		outputStream.write([0x1B,0x24,0x00,0x00]);
    		 		outputStream.write([0x1D,0x4C,0x0A,0x0A]);//左边距0x0A
    		 		
    		 		outputStream.write([ 0x1D, 0x21, 0x00]);//字体[0x1D, 0X21, n]
    		 		var str1 = '\n订单号:' + obj.orderNo +'\n\r';
    		 		str1 += '下单时间:' + obj.createDate +'\n\r';
    		 		str1 += '联系人:' + obj.pickupPop +'\n\r';
    		 		str1 += '电话:' + obj.pickupPhone +'\n\r';
    		 		str1 += '收货地址:' + obj.userAddressee.addressee + '\n\r';
    		 		var bytes1 = plus.android.invoke(str1, 'getBytes', 'GBK');
    		 		outputStream.write(bytes1);
    		 		outputStream.flush();
    		 
    		 		outputStream.write([ 0x1D, 0x21, 0x11]);//字体[0x1D, 0X21, n]放大两倍
    		 		var str2 = '门牌号:' + obj.userAddressee.doorNumber + '\n\r';
    		 		var bytes2 = plus.android.invoke(str2, 'getBytes', 'GBK');
    		 		outputStream.write(bytes2);
    		 		outputStream.flush();
    		 		
    		 		for (let j = 0; j < obj.orderInfoCartList.length; j++) {
    		 		  const res = obj.orderInfoCartList[j];
    		 		  outputStream.write([ 0x1D, 0x21, 0x00]);//字体[0x1D, 0X21, n]
    		 		  var str3 = '物件'+ (j+1) +':\n\r';
    		 		  var bytes3 = plus.android.invoke(str3, 'getBytes', 'GBK');
    		 		  outputStream.write(bytes3);
    		 		  outputStream.flush();
    		 		  
    		 		  outputStream.write([ 0x1D, 0x21, 0x11]);//字体[0x1D, 0X21, n]放大两倍
    		 		  str4 = '取件码:' + res.pickupCode +'\n\r';
    		 		  var bytes4 = plus.android.invoke(str4, 'getBytes', 'GBK');
    		 		  outputStream.write(bytes4);
    		 		  outputStream.flush();
    		 		  
    		 		  outputStream.write([ 0x1D, 0x21, 0x00]);//字体[0x1D, 0X21, n]
    		 		  str5 = '物件重量:' + res.weightValue +'\n\r';
    		 		  str5 += '备注:' + res.remarks +'\n\r';
    		 		  var bytes5 = plus.android.invoke(str5, 'getBytes', 'GBK');
    		 		  outputStream.write(bytes5);
    		 		  outputStream.flush();
    		 		}
    			 		
    		 		outputStream.write([ 0x1D, 0x21, 0x00]);//字体[0x1D, 0X21, n]
    		 		var str6 ='取件地址:' + obj.pickupAddress +'\n\r';
    				var bytes6 = plus.android.invoke(str6, 'getBytes', 'GBK');
    				outputStream.write(bytes6);
    				outputStream.flush();
    				
    				outputStream.write([0x1b, 0x61, 0x01]);//居中
    				outputStream.write([ 0x1D, 0x21, 0x00]);//字体[0x1D, 0X21, n]
    				var endStr = '\n***END***\n'
    				outputStream.write(plus.android.invoke(endStr, 'getBytes', 'gbk'))
    				outputStream.write(plus.android.invoke('\n', 'getBytes', 'gbk'))
    				outputStream.flush();
    			}
    		}else{
    		 mui.toast('请连接蓝牙')
    		 return false;
    	 }	 
      }
    }
    

    如果需要全部的源码,可以评论留下你的邮件地址

    展开全文
  • Android蓝牙打印机打印图片文字

    千次阅读 2019-08-23 15:33:32
    一、打印的效果图,打印照片+二维码+文字 二、蓝牙相关组件介绍 /** * 代表本地蓝牙适配器(蓝牙无线电)。BluetoothAdapter是所有蓝牙交互的入口。 * 使用这个你可以发现其他蓝牙设备,查询已配对的设备列表, ...

    一、打印的效果图,打印照片+二维码+文字

    照片,二维码、文字

    二、蓝牙相关组件介绍

        /**
         * 代表本地蓝牙适配器(蓝牙无线电)。BluetoothAdapter是所有蓝牙交互的入口。
         * 使用这个你可以发现其他蓝牙设备,查询已配对的设备列表,
         * 使用一个已知的MAC地址来实例化一个BluetoothDevice,
         * 以及创建一个BluetoothServerSocket来为监听与其他设备的通信。
         */
        private BluetoothAdapter mBluetoothAdapter = null;
    
    
        /**
         * 代表一个远程蓝牙设备,使用这个来请求一个与远程设备的BluetoothSocket连接,
         * 或者查询关于设备名称、地址、类和连接状态等设备信息。
         */
        private BluetoothDevice mBluetoothDevice = null;
    
        /**
         * 代表一个蓝牙socket的接口(和TCP Socket类似)。这是一个连接点,
         * 它允许一个应用与其他蓝牙设备通过InputStream和OutputStream交换数据。
         */
        private BluetoothSocket mBluetoothSocket = null;
    
    

    三、搜索蓝牙设备

        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
    
            setContentView(R.layout.activity_search_device);
    
            mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
    
            //注册设备被发现时的广播
            IntentFilter filter1=new IntentFilter(BluetoothDevice.ACTION_FOUND);
            registerReceiver(mReceiver,filter1);
            //注册一个搜索结束时的广播
            IntentFilter filter2=new IntentFilter(BluetoothAdapter.ACTION_DISCOVERY_FINISHED);
            registerReceiver(mReceiver,filter2);
    
            IntentFilter filter3=new IntentFilter(BluetoothAdapter.ACTION_DISCOVERY_STARTED);
            registerReceiver(mReceiver,filter3);
    
            IntentFilter filter4=new IntentFilter(BluetoothAdapter.ACTION_REQUEST_ENABLE);  // 开关变化的广播
            registerReceiver(mReceiver,filter4);
    
    
    
            Button btn = (Button)findViewById(R.id.btnV1);   //  设备搜索
            btn.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    if(mBluetoothAdapter != null){
                        if(!mBluetoothAdapter.isEnabled()){  // 蓝牙开关是否打开
                            mBluetoothAdapter.enable();
                        }else{
                            Log.d(TAG,"mBluetoothAdapter.isEnabled() == true");
                        }
                        mBluetoothAdapter.startDiscovery();  // 开始搜索蓝牙设备,通过监听广播接收搜索到的设备
                    }else{
                        Toast.makeText(SearchBlueToothActivity.this,"该设备没有蓝牙模块",Toast.LENGTH_SHORT).show();
                    }
                }
            });
        }
    
        /**
         * 接收搜索蓝牙设备结果的信息
         */
        private BroadcastReceiver mReceiver = new BroadcastReceiver() {
            @Override
            public void onReceive(Context context, Intent intent) {
                String action = intent.getAction();
                if(BluetoothDevice.ACTION_FOUND.equals(action)){
                    BluetoothDevice device=intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
                    Log.d(TAG,"device = " + device);
                    if(device.getBondState()==BluetoothDevice.BOND_BONDED){    //显示已配对设备
                        Log.d(TAG,"已配对设备 : " + device.getName() + ", " + device.getName());
                    }else{
                        Log.d(TAG,"未配对设备 : " + device.getName() + ", " + device.getName());
                    }
    
                }else if(BluetoothAdapter.ACTION_DISCOVERY_FINISHED.equals(action)){
                    Log.d(TAG,"搜索完成...");
                }else if(BluetoothAdapter.ACTION_DISCOVERY_STARTED.equals(action)){
                    Log.d(TAG,"搜索开始...");
                }else if(BluetoothAdapter.ACTION_REQUEST_ENABLE.equals(action)){
                    Log.d(TAG,"蓝牙打开...");
                }
            }
        };
    
    

    四、蓝牙打印 // 这里写死了,要修改获取蓝牙设备的方式

    public class BtPrint {
        private static BtPrint instance;
        public static String TAG = BtPrint.class.getSimpleName();
        private List<String> mpairedDeviceList = new ArrayList<String>();
    
        private BluetoothAdapter mBluetoothAdapter = null;
    
        private BluetoothDevice mBluetoothDevice = null;
    
        private BluetoothSocket mBluetoothSocket = null;
    
        private static final UUID SPP_UUID = UUID.fromString("00001101-0000-1000-8000-00805F9B34FB");
        private OutputStream mOutputStream = null;
        Set<BluetoothDevice> pairedDevices = null;
    
        /**
         * @return
         * @throws
         * @Title: getInstance
         */
        public static BtPrint getInstance() {
            if (instance == null) {
                synchronized (BtPrint.class) {
                    if (instance == null) {
                        instance = new BtPrint();
                    }
                }
            }
            return instance;
        }
    
        public void releasePrint(){
            mBluetoothAdapter = null;
            if(mBluetoothSocket != null){
                try {
                    mBluetoothSocket.close();
                    mBluetoothSocket = null;
                } catch (IOException e) {
                    e.printStackTrace();
                    Log.d(TAG,"releasePrint(),IOException :",e);
                    mBluetoothSocket = null;
                }
            }
        }
    
        /**
         * 连接打印机设备
         */
        public void connectPrinter(){
            mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
            if(mBluetoothAdapter == null){   // 蓝牙功能没有打开,UI界面弹出打开蓝牙功能
                Log.d(TAG,"connectPrinter(),mBluetoothAdapter = null");
            }else if(mBluetoothAdapter.isEnabled()){  // 蓝牙已经打开
                // 列出已经配对过的设备
                String getName = mBluetoothAdapter.getName();
                Log.d(TAG, "getName = " + getName);
                pairedDevices = mBluetoothAdapter.getBondedDevices(); // 已经配对了的设备?
                while (mpairedDeviceList.size() > 1) {
                    mpairedDeviceList.remove(1);
                }
                if (pairedDevices.size() == 0) {
                    Log.d(TAG,"connectPrinter(),pairedDevices.size == 0");
                    return;  // 没有配对过的设备
                }
                for (BluetoothDevice device : pairedDevices) {
                    getName = device.getAddress();
                    mpairedDeviceList.add(getName);//蓝牙名
                }
                String temString = mpairedDeviceList.get(0);
                Log.d(TAG,"temString = " + temString + ", mBluetoothDevice = " + mBluetoothDevice);
    
                mBluetoothDevice = mBluetoothAdapter.getRemoteDevice(temString);
                try {
                    mBluetoothSocket = mBluetoothDevice.createRfcommSocketToServiceRecord(SPP_UUID);
                    mBluetoothSocket.connect();
                    Log.d(TAG,"mBluetoothDevice = " + mBluetoothDevice +", mBluetoothSocket = " + mBluetoothSocket);
                } catch (IOException e) {
                    Log.d(TAG,"connectPrinter(),IOException :",e);
                }
            }else {  // 蓝牙未打开
                Log.d(TAG,"connectPrinter(),bluetooth isnot open");
            }
        }
    
        private  static int printTimes = 0;  // 出错时重试打印的次数
    
        /**
         * 打印小条
         */
        public void printVerifyData(String tmpName,
                                    String tmpIdNo,
                                    String curName,
                                    String idcardNo,
                                    String headerPic) {
            if(mBluetoothSocket == null){
                connectPrinter();
            }else{
                if(!mBluetoothSocket.isConnected()){
                    try {
                        mBluetoothSocket.connect();
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                }else{
                    Log.d(TAG,"printVerifyData(),mBluetoothSocket.isConnected.");
                }
            }
    
            // 打印图片
            // 打印标题
            String title = Const.VALUE.TITLE;
            String line = ".......................................";
            try {
                mOutputStream = mBluetoothSocket.getOutputStream();
                PrintUtils PrintUtils = new PrintUtils();
                PrintUtils.setOutputStream(mOutputStream);
                PrintUtils.selectCommand(PrintUtils.RESET);
                PrintUtils.selectCommand(PrintUtils.LINE_SPACING_DEFAULT);
                PrintUtils.selectCommand(PrintUtils.LINE_SPACING);
                PrintUtils.selectCommand(PrintUtils.ALIGN_CENTER);
                PrintUtils.selectCommand(PrintUtils.BOLD);
                PrintUtils.selectCommand(PrintUtils.DOUBLE_HEIGHT_WIDTH);  //宽高加倍
                PrintUtils.printText(title + "\n");
                PrintUtils.selectCommand(PrintUtils.BOLD_CANCEL);
                PrintUtils.selectCommand(PrintUtils.NORMAL);
                PrintUtils.printText(line + "\n");
    
                // 打印照片
                Bitmap image = ImageUtils.getBitmap(headerPic);
    
                image = convertGreyImgByFloyd(image);
                byte[]imageData = PrinterUtils.decodeBitmap(image);
                PrintUtils.selectCommand(imageData);
                PrintUtils.printText(line + "\n");
    
                PrintUtils.selectCommand(PrintUtils.ALIGN_CENTER);
                PrintUtils.selectCommand(PrintUtils.BOLD);
                Log.d(TAG,"BtPrint # tmpName = " + tmpName + ",tmpIdNo = " + tmpIdNo);
                PrintUtils.printText(PrintUtils.printTwoData("姓名:", tmpName +"\n"));
                PrintUtils.printText(PrintUtils.printTwoData("身份证号码:", tmpIdNo+"\n"));
                PrintUtils.printText(PrintUtils.printTwoData("凭证有效期:", TimeUtils.date2String(new Date(),new SimpleDateFormat("yyyy年MM月dd日"))+"\n"));
    
                PrintUtils.selectCommand(PrintUtils.BOLD_CANCEL);
                PrintUtils.printText(line + "\n");
                String oriString = curName+"|" +idcardNo;
                Log.d(TAG,"BtPrint # oriString = " + oriString);
                String qrString = Base64.encodeToString(oriString.getBytes("UTF-8"),Base64.NO_WRAP);
                Log.d(TAG,"qrString = " + qrString);
                Bitmap qrCodeImage = QRCodeUtil.createQRCodeBitmap(qrString, 300, "0");
                byte[] qrData = PrinterUtils.decodeBitmap(qrCodeImage);
                PrintUtils.selectCommand(qrData);
    
                PrintUtils.printText(line + "\n");
                PrintUtils.selectCommand(PrintUtils.NORMAL);
                PrintUtils.selectCommand(PrintUtils.ALIGN_LEFT);
                PrintUtils.selectCommand(PrintUtils.BOLD);
                PrintUtils.selectCommand(PrintUtils.COLUMN_SPACING);
                String tips1 = " lajdflajdfl,"+ "\n";
                String tips2 = " lasdjflkajsdlfjalksdjflajsdflja"+"\n";
                PrintUtils.printText(tips1);
                PrintUtils.printText(tips2);
                PrintUtils.selectCommand(PrintUtils.BOLD_CANCEL);
                PrintUtils.selectCommand(PrintUtils.COLUMN_SPACING_CANCEL);
                PrintUtils.printText("\n\n");
                // 切纸
                mOutputStream = mBluetoothSocket.getOutputStream();
                mOutputStream.write(new byte[]{0x0a, 0x0a, 0x1d, 0x56, 0x01});
                mOutputStream.flush();
    
                BusEvent busEvent = new BusEvent();
                busEvent.action = "printer_completed";
                busEvent.data = "ok";
                EventBus.getDefault().post(busEvent);
            } catch (Exception e) {
                Log.d(TAG, "print error printTimes = " + printTimes);
                if(printTimes < 5){
                    printTimes ++;
                    printVerifyData(tmpName,tmpIdNo,curName,idcardNo,headerPic);
                }else{
                    Log.d(TAG, "print error :", e);
                    LogUtils.file(e.getCause() + "--" + e.getMessage());
                    sendPrintErr();
                }
            }
        }
    
        /**
         * 发送打印错误的信息
         */
        private void sendPrintErr(){
            BusEvent busEvent = new BusEvent();
            busEvent.action = "printer_completed";
            busEvent.data = "error";
            EventBus.getDefault().post(busEvent);
            BtPrint.getInstance().releasePrint();
        }
    
        public Bitmap convertGreyImgByFloyd(Bitmap img) {
            int width = img.getWidth();
            //获取位图的宽
            int height = img.getHeight();
            //获取位图的高 \
            int[] pixels = new int[width * height];
            //通过位图的大小创建像素点数组
            img.getPixels(pixels, 0, width, 0, 0, width, height);
            int[] gray = new int[height * width];
            for (int i = 0; i < height; i++) {
                for (int j = 0; j < width; j++) {
                    int grey = pixels[width * i + j];
                    int red = ((grey & 0x00FF0000) >> 16);
                    gray[width * i + j] = red;
                }
            }
            int e = 0;
            for (int i = 0; i < height; i++) {
                for (int j = 0; j < width; j++) {
                    int g = gray[width * i + j];
                    if (g >= 128) {
                        pixels[width * i + j] = 0xffffffff;
                        e = g - 255;
                    } else {
                        pixels[width * i + j] = 0xff000000;
                        e = g - 0;
                    }
                    if (j < width - 1 && i < height - 1) {
                        //右边像素处理
                        gray[width * i + j + 1] += 3 * e / 8;
                        //下
                        gray[width * (i + 1) + j] += 3 * e / 8;
                        //右下
                        gray[width * (i + 1) + j + 1] += e / 4;
                    } else if (j == width - 1 && i < height - 1) {
                        //靠右或靠下边的像素的情况
                        //下方像素处理
                        gray[width * (i + 1) + j] += 3 * e / 8;
                    } else if (j < width - 1 && i == height - 1) {
                        //右边像素处理
                        gray[width * (i) + j + 1] += e / 4;
                    }
                }
            }
            Bitmap mBitmap = Bitmap.createBitmap(width, height, Bitmap.Config.RGB_565);
            mBitmap.setPixels(pixels, 0, width, 0, 0, width, height);
            return mBitmap;
        }
    }
    

    PrintUtils

    
    import android.annotation.SuppressLint;
    
    import java.io.IOException;
    import java.io.OutputStream;
    import java.nio.charset.Charset;
    
    public class PrintUtils {
    
        private static final int LINE_BYTE_SIZE = 32;
        private static OutputStream outputStream = null;
    
        public static void setOutputStream(OutputStream outputStream) {
            PrintUtils.outputStream = outputStream;
        }
    
    
        /**
         * 打印文字
         *
         * @param text 要打印的文字
         */
        public static void printText(String text) {
            try {
                byte[] data = text.getBytes("gbk");
                outputStream.write(data, 0, data.length);
                outputStream.flush();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    
        /**
         * 设置打印格式
         *
         * @param command 格式指令
         */
        public static void selectCommand(byte[] command) {
            try {
                outputStream.write(command);
                outputStream.flush();
            } catch (IOException e) {
                //Toast.makeText(this.context, "发送失败!", Toast.LENGTH_SHORT).show();
                e.printStackTrace();
            }
        }
    
        /**
         * 复位打印机
         */
        public static final byte[] RESET = {0x1b, 0x40};
    
        /**
         * 左对齐
         */
        public static final byte[] ALIGN_LEFT = {0x1b, 0x61, 0x00};
    
        /**
         * 中间对齐
         */
        public static final byte[] ALIGN_CENTER = {0x1b, 0x61, 0x01};
    
        /**
         * 选择加粗模式
         */
        public static final byte[] BOLD = {0x1b, 0x45, 0x01};
    
        /**
         * 取消加粗模式
         */
        public static final byte[] BOLD_CANCEL = {0x1b, 0x45, 0x00};
    
        /**
         * 宽高加倍
         */
        public static final byte[] DOUBLE_HEIGHT_WIDTH = {0x1d, 0x21, 0x11};
    
        /**
         * 字体不放大
         */
        public static final byte[] NORMAL = {0x1d, 0x21, 0x00};
    
        /**
         * 设置默认行间距
         */
        public static final byte[] LINE_SPACING_DEFAULT = {0x1b, 0x32};
    
    //    /**
    //     * 设置行间距
    //     */
    	public static final byte[] LINE_SPACING = {0x1b, 0x33, 0x50};  // 20的行间距(0,255)
    
        /**
         * 设置字符间距
         */
        public static final byte[] COLUMN_SPACING = {0x1b, 0x20, 0x25};
    
        /**
         * 取消设置字符间距
         */
        public static final byte[] COLUMN_SPACING_CANCEL = {0x1b, 0x20, 0x00};
    
        /**
         * 打印两列
         *
         * @param leftText  左侧文字
         * @param rightText 右侧文字
         * @return
         */
        @SuppressLint("NewApi")
        public static String printTwoData(String leftText, String rightText) {
            StringBuilder sb = new StringBuilder();
            int leftTextLength = getBytesLength(leftText);
            int rightTextLength = getBytesLength(rightText);
            sb.append(leftText);
    
            // 计算两侧文字中间的空格
            int marginBetweenMiddleAndRight = LINE_BYTE_SIZE - leftTextLength - rightTextLength;
    
            for (int i = 0; i < marginBetweenMiddleAndRight; i++) {
                sb.append(" ");
            }
            sb.append(rightText);
            return sb.toString();
        }
    
        /**
         * 获取数据长度
         *
         * @param msg
         * @return
         */
        @SuppressLint("NewApi")
        private static int getBytesLength(String msg) {
            return msg.getBytes(Charset.forName("GB2312")).length;
        }
    }
    
    
    展开全文
  • J2ME 实现蓝牙打印功能 dos.write(0x1D); dos.write(0x0C); //送黑标纸至打印起始位置
  • Android 蓝牙开发,蓝牙连打印机。

    万次阅读 热门讨论 2020-03-27 15:49:57
    本文可能内容比较长,但是难度不大,流程梳理清楚了之后,一步一步的来,就非常简单。

    目录

    效果:

    开发环境

    涉及知识点

    集成配置

    蓝牙连接

    蓝牙打印

    GitHub


    效果:

     

     

    特别声明:较之前的版本有很大的调整,之前的版本是未适配8.0的,现在是适配了的,接入方式也不一样,包括代码逻辑都有调整,不过梳理清楚流程之后也就不难了,非常简单。(更新时间:2020-03-27)

     

    开发环境

    • Gprinter佳博打印机,型号GP-2120TU
    • Android Studio 3.6.1,gradle 3.5.3

     

    本文可能内容比较长,但是难度不大。文末附github地址。

     

    涉及知识点

    • 蓝牙相关
    • 多线程开发
    • 线程池
    • 构建者模式
    • 单例模式
    • 运行时权限
    • BroadcastReceiver
    • startActivityForResult
    • 等等

     

    集成配置

    1.添加jar包,在app目录下新建libs文件夹,拷入jar文件并Add As Library

    2.在main目录下新建jniLibs目录,并拷入so文件

    3.配置我们的manifest文件,添加必要的权限

        <!-- 打印相关权限 -->
        <uses-permission android:name="android.permission.INTERNET" />
        <uses-permission android:name="android.permission.BLUETOOTH_ADMIN" />
        <uses-permission android:name="android.permission.BLUETOOTH" />
        <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
        <uses-permission android:name="android.permission.CHANGE_NETWORK_STATE" />
        <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
        <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
    
        <uses-feature
            android:name="android.hardware.usb.host"
            android:required="true" />

     

    ok,基本的配置完成,开始进入正题。

    基本大的流程分为两部分,一是蓝牙连接,二是打印,下面开始一一介绍。

     

    蓝牙连接

    分为几个小步骤

    1.因为蓝牙涉及到隐私权限,所以先检查、请求权限

        private void checkPermission() {
            for (String permission : permissions) {
                if (PackageManager.PERMISSION_GRANTED != ContextCompat.checkSelfPermission(this, permission)) {
                    per.add(permission);
                }
            }
        }
    
        private void requestPermission() {
            if (per.size() > 0) {
                String[] p = new String[per.size()];
                ActivityCompat.requestPermissions(this, per.toArray(p), REQUEST_CODE);
            }
        }

    2.点击连接按钮,通过startActivityForResult启动一个蓝牙列表页面,实际上显示为一个dialog

        public void btnConnect(View view) {
            startActivityForResult(new Intent(MainActivity.this, BluetoothListActivity.class), BLUETOOTH_REQUEST_CODE);
        }

    3.这个页面的作用就是判断蓝牙是否可用、是否开启,显示已配对和未配对的蓝牙设备列表

        /**
         * 初始化蓝牙
         */
        private void initBluetooth() {
            // 获取蓝牙适配器
            mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
            // 检查蓝牙是否可用
            if (mBluetoothAdapter == null) {
                Toast.makeText(this, "当前设备不支持蓝牙", Toast.LENGTH_SHORT).show();
            } else {
                // 检查蓝牙是否打开
                if (!mBluetoothAdapter.isEnabled()) {
                    Intent enableIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
                    startActivityForResult(enableIntent, REQUEST_ENABLE_BT);
                } else {
                    getDeviceList();
                }
            }
        }
    
        @Override
        protected void onActivityResult(int requestCode, int resultCode, Intent data) {
            super.onActivityResult(requestCode, resultCode, data);
            if (requestCode == REQUEST_ENABLE_BT) {
                if (resultCode == Activity.RESULT_OK) {
                    // bluetooth is opened
                    getDeviceList();
                } else {
                    // bluetooth is not open
                    Toast.makeText(this, "蓝牙没有开启", Toast.LENGTH_SHORT).show();
                }
            }
        }
    
        /**
         * 蓝牙设备列表
         */
        protected void getDeviceList() {
            // 初始化一个数组适配器,用来显示已匹对和未匹对的设备
            mDevicesArrayAdapter = new ArrayAdapter<>(this, R.layout.bluetooth_device_name_item);
            lvPairedDevice.setAdapter(mDevicesArrayAdapter);
            lvPairedDevice.setOnItemClickListener(mDeviceClickListener);
            // 已匹对数据
            Set<BluetoothDevice> pairedDevices = mBluetoothAdapter.getBondedDevices();
            // 添加一个item显示信息
            mDevicesArrayAdapter.add("已配对:");
            if (pairedDevices.size() > 0) {
                //遍历填充数据
                for (BluetoothDevice device : pairedDevices) {
                    mDevicesArrayAdapter.add(device.getName() + "\n" + device.getAddress());
                }
            } else {
                mDevicesArrayAdapter.add("没有已配对设备");
            }
        }
    
        /**
         * 接收扫描设备的广播
         * changes the title when discovery is finished
         */
        private final BroadcastReceiver mFindBlueToothReceiver = new BroadcastReceiver() {
            @Override
            public void onReceive(Context context, Intent intent) {
                String action = intent.getAction();
                // 每当发现一个蓝牙设备时
                if (BluetoothDevice.ACTION_FOUND.equals(action)) {
                    // Get the BluetoothDevice object from the Intent
                    //获取设备
                    BluetoothDevice device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
                    // If it's already paired, skip it, because it's been listed
                    // 未匹对的情况下添加显示
                    if (device.getBondState() != BluetoothDevice.BOND_BONDED) {
                        mDevicesArrayAdapter.add(device.getName() + "\n" + device.getAddress());
                    }
                    // 扫描结束
                } else if (BluetoothAdapter.ACTION_DISCOVERY_FINISHED.equals(action)) {
                    setProgressBarIndeterminateVisibility(false);
                    setTitle("选择蓝牙设备");
                    //此处-2是减去我们手动添加的两个区分显示的item
                    Log.i("tag", "finish discovery" + (mDevicesArrayAdapter.getCount() - 2));
                    if (mDevicesArrayAdapter.getCount() == 0) {
                        mDevicesArrayAdapter.add("没有找到蓝牙设备");
                    }
                }
            }
        };
    
        /**
         * 扫描设备
         */
        private void discoveryDevice() {
            setProgressBarIndeterminateVisibility(true);
            setTitle("扫描中");
            // 添加一个item区分显示信息
            mDevicesArrayAdapter.add("未配对:");
            // If we're already discovering, stop it
            if (mBluetoothAdapter.isDiscovering()) {
                mBluetoothAdapter.cancelDiscovery();
            }
            // 开始扫描,每扫描到一个设备,都会发送一个广播
            mBluetoothAdapter.startDiscovery();
        }
    

    4.点击一个列表item的时候 即表示连接此设备,通过setResult返回该item对应的设备mac地址

        private OnItemClickListener mDeviceClickListener = new OnItemClickListener() {
            @Override
            public void onItemClick(AdapterView<?> av, View v, int arg2, long arg3) {
                // Cancel discovery because it's costly and we're about to connect
                // Get the device MAC address, which is the last 17 chars in the View
                String info = ((TextView) v).getText().toString();
                String noDevices = "没有已配对设备";
                String noNewDevice = "没有找到蓝牙设备";
                Log.i("TAG", info);
                // info 不是我们手动添加的信息 即表示为真实蓝牙设备信息
                if (!info.equals(noDevices) && !info.equals(noNewDevice) && !info.equals("未配对") && !info.equals("已配对")) {
                    mBluetoothAdapter.cancelDiscovery();
                    //mac 地址
                    String address = info.substring(info.length() - 17);
                    // 设置信息并返回
                    // Set result and finish this Activity
                    Intent intent = new Intent();
                    intent.putExtra(EXTRA_DEVICE_ADDRESS, address);
                    setResult(Activity.RESULT_OK, intent);
                    finish();
                }
            }
        };

    5.在MainActivity的onActivityResult中获取mac地址,并通过设备连接管理类DeviceConnFactoryManager进行连接

        @Override
        protected void onActivityResult(int requestCode, int resultCode, Intent data) {
            super.onActivityResult(requestCode, resultCode, data);
            if (resultCode == RESULT_OK) {
                //蓝牙连接
                if (requestCode == BLUETOOTH_REQUEST_CODE) {
                    closePort();
                    //获取蓝牙mac地址
                    String macAddress = data.getStringExtra(BluetoothListActivity.EXTRA_DEVICE_ADDRESS);
                    //初始化DeviceConnFactoryManager 并设置信息
                    new DeviceConnFactoryManager.Build()
                            //设置标识符
                            .setId(id)
                            //设置连接方式
                            .setConnMethod(DeviceConnFactoryManager.CONN_METHOD.BLUETOOTH)
                            //设置连接的蓝牙mac地址
                            .setMacAddress(macAddress)
                            .build();
                    //配置完信息,就可以打开端口连接了
                    Log.i("TAG", "onActivityResult: 连接蓝牙" + id);
                    threadPool = ThreadPool.getInstantiation();
                    threadPool.addTask(new Runnable() {
                        @Override
                        public void run() {
                            DeviceConnFactoryManager.getDeviceConnFactoryManagers()[id].openPort();
                        }
                    });
                }
            }
        }

    这里可以看到,我们是先拿到了mac地址,然后通过管理类的构建者模式进行设置参数,最后再通过管理类调用openPort方法去连接的。

    6.在连接管理类中通过jar包封装的方法进行连接,并通过广播Broadcast把连接状态发送出去

        public void openPort() {
            deviceConnFactoryManagers[id].isOpenPort = false;
            sendStateBroadcast(CONN_STATE_CONNECTING);
            switch (deviceConnFactoryManagers[id].connMethod) {
                case BLUETOOTH:
                    System.out.println("id -> " + id);
                    mPort = new BluetoothPort(macAddress);
                    isOpenPort = deviceConnFactoryManagers[id].mPort.openPort();
                    break;
                default:
                    break;
            }
    
            //端口打开成功后,检查连接打印机所使用的打印机指令ESC、TSC
            if (isOpenPort) {
                queryCommand();
            } else {
                if (this.mPort != null) {
                    this.mPort = null;
                }
                sendStateBroadcast(CONN_STATE_FAILED);
            }
        }
    

    这里通过实例化BluetoothPort把mac地址传入,然后调用了PortManager的openPort方法返回了一个状态。

    往下看,这个switch代码块之后就是对这个状态的判断,当状态为已连接的时候调用了queryCommand方法,这个方法里面有一些操作,其中一个就是通过广播把已连接的状态发出去。

    7.在MainActivity中接收广播,并根据状态对界面进行显示处理

        private BroadcastReceiver receiver = new BroadcastReceiver() {
            @Override
            public void onReceive(Context context, Intent intent) {
                String action = intent.getAction();
                if (DeviceConnFactoryManager.ACTION_CONN_STATE.equals(action)) {
                    int state = intent.getIntExtra(DeviceConnFactoryManager.STATE, -1);
                    int deviceId = intent.getIntExtra(DeviceConnFactoryManager.DEVICE_ID, -1);
                    switch (state) {
                        case DeviceConnFactoryManager.CONN_STATE_DISCONNECT:
                            if (id == deviceId) mTvState.setText("未连接");
                            break;
                        case DeviceConnFactoryManager.CONN_STATE_CONNECTING:
                            mTvState.setText("连接中");
                            break;
                        case DeviceConnFactoryManager.CONN_STATE_CONNECTED:
                            mTvState.setText("已连接");
                            Toast.makeText(MainActivity.this, "已连接", Toast.LENGTH_SHORT).show();
                            break;
                        case CONN_STATE_FAILED:
                            mTvState.setText("未连接");
                            Toast.makeText(MainActivity.this, "连接失败!重试或重启打印机试试", Toast.LENGTH_SHORT).show();
                            break;
                    }
                    /* Usb连接断开、蓝牙连接断开广播 */
                } else if (ACTION_USB_DEVICE_DETACHED.equals(action)) {
                    mHandler.obtainMessage(CONN_STATE_DISCONN).sendToTarget();
                }
            }
        };

    既然知道状态了就可以根据自己的需求去处理,这里只是简单的提示。

     

    ok,到这连接的部分就介绍完毕了,下面开始介绍打印的部分。

     

    蓝牙打印

    打印其实是软件与硬件之间的交互,而这部分恰恰是sdk的职责所在,所以留给我们的任务已经不多了,也就相对简单很多。

    1.通过线程池添加打印任务

        public void printLabel() {
            Log.i("TAG", "准备打印");
            threadPool = ThreadPool.getInstantiation();
            threadPool.addTask(new Runnable() {
                @Override
                public void run() {
                    ...
                }
            });
        }

    因为打印是耗时任务,所以不管是为了避免卡顿还是ANR,我们应该用线程池进行优化,为了方便再用单例封装起来。

    2.打印之前也要先做蓝牙状态的判断,只有做到足够的严谨,才能看起来万无一失。。

        public void printLabel() {
            Log.i("TAG", "准备打印");
            threadPool = ThreadPool.getInstantiation();
            threadPool.addTask(new Runnable() {
                @Override
                public void run() {
                    //先判断打印机是否连接
                    if (DeviceConnFactoryManager.getDeviceConnFactoryManagers()[id] == null ||
                            !DeviceConnFactoryManager.getDeviceConnFactoryManagers()[id].getConnState()) {
                        mHandler.obtainMessage(CONN_PRINTER).sendToTarget();
                        return;
                    }
                    ...
                }
            });
        }

    这里呢,因为是在子线程,所以通过handler在主线程更新ui或者给个提示

        @SuppressLint("HandlerLeak")
        private Handler mHandler = new Handler() {
            @Override
            public void handleMessage(Message msg) {
                switch (msg.what) {
                    case CONN_STATE_DISCONN:
                        if (DeviceConnFactoryManager.getDeviceConnFactoryManagers()[id] != null || !DeviceConnFactoryManager.getDeviceConnFactoryManagers()[id].getConnState()) {
                            DeviceConnFactoryManager.getDeviceConnFactoryManagers()[id].closePort(id);
                            Toast.makeText(MainActivity.this, "成功断开连接", Toast.LENGTH_SHORT).show();
                        }
                        break;
                    case PRINTER_COMMAND_ERROR:
                        Toast.makeText(MainActivity.this, "请选择正确的打印机指令", Toast.LENGTH_SHORT).show();
                        break;
                    case CONN_PRINTER:
                        Toast.makeText(MainActivity.this, "请先连接打印机", Toast.LENGTH_SHORT).show();
                        break;
                }
            }
        };
    3.一切正常,我们开始走打印流程
     
        public void printLabel() {
            Log.i("TAG", "准备打印");
            threadPool = ThreadPool.getInstantiation();
            threadPool.addTask(new Runnable() {
                @Override
                public void run() {
                    //先判断打印机是否连接
                    if (DeviceConnFactoryManager.getDeviceConnFactoryManagers()[id] == null ||
                            !DeviceConnFactoryManager.getDeviceConnFactoryManagers()[id].getConnState()) {
                        mHandler.obtainMessage(CONN_PRINTER).sendToTarget();
                        return;
                    }
                    if (DeviceConnFactoryManager.getDeviceConnFactoryManagers()[id].getCurrentPrinterCommand() == PrinterCommand.TSC) {
                        Log.i("TAG", "开始打印");
                        sendLabel();
                    } else {
                        mHandler.obtainMessage(PRINTER_COMMAND_ERROR).sendToTarget();
                    }
                }
            });
        }

    4.设置打印数据,发送打印数据

        private void sendLabel() {
            LabelCommand tsc = new LabelCommand();
            tsc.addSize(40, 30); // 设置标签尺寸,按照实际尺寸设置
            tsc.addGap(1); // 设置标签间隙,按照实际尺寸设置,如果为无间隙纸则设置为0
            tsc.addDirection(LabelCommand.DIRECTION.FORWARD, LabelCommand.MIRROR.NORMAL);// 设置打印方向
            tsc.addQueryPrinterStatus(LabelCommand.RESPONSE_MODE.ON);//开启带Response的打印,用于连续打印
            tsc.addReference(0, 0);// 设置原点坐标
            tsc.addTear(EscCommand.ENABLE.ON); // 撕纸模式开启
            tsc.addCls();// 清除打印缓冲区
    
            // 绘制简体中文
            tsc.addText(30, 30, LabelCommand.FONTTYPE.SIMPLIFIED_CHINESE, LabelCommand.ROTATION.ROTATION_0, LabelCommand.FONTMUL.MUL_1, LabelCommand.FONTMUL.MUL_1,
                    "这是标题");
            tsc.addText(200, 30, LabelCommand.FONTTYPE.SIMPLIFIED_CHINESE, LabelCommand.ROTATION.ROTATION_0, LabelCommand.FONTMUL.MUL_1, LabelCommand.FONTMUL.MUL_1,
                    "序号:" + "1");
    
            tsc.addText(30, 90, LabelCommand.FONTTYPE.SIMPLIFIED_CHINESE, LabelCommand.ROTATION.ROTATION_0, LabelCommand.FONTMUL.MUL_1, LabelCommand.FONTMUL.MUL_1,
                    "价格:" + "99.00");
            tsc.addText(30, 140, LabelCommand.FONTTYPE.SIMPLIFIED_CHINESE, LabelCommand.ROTATION.ROTATION_0, LabelCommand.FONTMUL.MUL_1, LabelCommand.FONTMUL.MUL_1,
                    "数量:" + "99");
            tsc.addText(30, 190, LabelCommand.FONTTYPE.SIMPLIFIED_CHINESE, LabelCommand.ROTATION.ROTATION_0, LabelCommand.FONTMUL.MUL_1, LabelCommand.FONTMUL.MUL_1,
                    "日期:" + "2020-02-02");
    
            // 绘制图片
    //        Bitmap b = BitmapFactory.decodeResource(getResources(), R.mipmap.ic_launcher);
    //        tsc.addBitmap(20, 50, LabelCommand.BITMAP_MODE.OVERWRITE, b.getWidth(), b);
    
            //二维码
            tsc.addQRCode(200, 90, LabelCommand.EEC.LEVEL_L, 4, LabelCommand.ROTATION.ROTATION_0, "www.baidu.com");
    
            tsc.addPrint(1, 1); // 打印标签
            tsc.addSound(2, 100); // 打印标签后 蜂鸣器响
    
            /* 发送数据 */
            Vector<Byte> data = tsc.getCommand();
            if (DeviceConnFactoryManager.getDeviceConnFactoryManagers()[id] == null) {
                Log.i("TAG", "sendLabel: 打印机为空");
                return;
            }
            DeviceConnFactoryManager.getDeviceConnFactoryManagers()[id].sendDataImmediately(data);
        }

    数据及显示的位置,根据自己的需求做调整。

     

    ok,以上基本是核心代码了,注释都有,按照上面这个顺序来走的话思路还是很清晰的
     

    GitHub

     

     

    展开全文
  • 安卓手机连接蓝牙打印机实现打印功能

    万次阅读 多人点赞 2014-03-18 16:08:23
    最近在做一个安卓应用,其中有一个需求是要求用蓝牙连接打印机实现打印功能。一开始没有一点头绪,网上找了很多资料也找不到有用的数据。所以自己就去研究,最终,功夫不负有心人,顺利的完成了这个功能。下边贴出我...
  • 6、蓝牙打印机流程 ☆☆☆☆ScanUtils.getPrinter()(获取到具体厂家的打印机示例)☆☆☆☆ //6.1如果是连接状态,进行打印; ☆☆☆☆–>IntTempletFactory.directPrint☆☆☆☆ //6.2如果是未连接连接状态,跳到...
  • Android 蓝牙打印指令

    千次阅读 2019-05-04 02:44:19
    蓝牙打印关于蓝牙连接部分请查看上篇文章 ->Android 蓝牙连接,本篇文章讨论Android中蓝牙打印的指令实现。 蓝牙打印机的种类繁多,支持的打印格式也不尽相同。按照指令集划分,主要可分为:ESC指令集、CPCL指令...
  • MUI蓝牙打印(Android)

    千次阅读 2018-08-27 14:22:33
    MUI蓝牙打印(Android) 使用MUI开发手机APP时使用蓝牙打印功能可能较少使用,MUI官方并为集成蓝牙打印功能,而且似乎对iPhone蓝牙打印的类库支持也不够完善。忙完一阶段后回顾下之前的工作,想想蓝牙打印功能折腾...
  • Wince下C#开发的蓝牙打印程序

    热门讨论 2020-07-30 23:32:53
    wince5.0 下用C#写的蓝牙打印测试程序。程序使用MC3000手持和Zebra MZ220便携式打印机测试通过。 程序是建立serialport对象,指定com口连接打印机,界面上open打开蓝牙端口,close关闭蓝牙端口 打印时向蓝牙端口发送...
  • 这个一个Android蓝牙打印小票demo,类似美团外卖小票打印 先看一下效果图: demo里主要是使用汉印打印机进行蓝牙小票打印,它还支持WiFi打印,USB打印和串口打印,SDK对接的话去汉印官网下载相应的zip包,里面...
  • C#蓝牙打印(windowsmobile) C#蓝牙打印(windowsmobile) C#蓝牙打印(windowsmobile) C#蓝牙打印(windowsmobile)C#蓝牙打印源代码可以直接运行 简单例子,仅供参考。一般
  • uni-app 蓝牙打印功能

    千次阅读 热门讨论 2020-03-26 15:00:41
    uni-app 蓝牙打印功能 最近项目中要用到蓝牙打印功能,头一回遇到这个问题,着实着急。网络上没有过多的demo可以借鉴,Dcloud中的打印demo也是看的一头雾水。好在,我在github上找到了一个使用uni-app提供的蓝牙接口...
  • 小程序蓝牙打印

    千次阅读 热门讨论 2019-04-26 16:38:38
    蓝牙打印中文乱码 不能一次传输完所有包,比如说一行“123456789” 部分机型能够全部传输完成,而有的机型传到“7”就不会传,打印出来的结果就是“1234567”,不能完全打印完整 蓝牙不能打印,调用API成功无报错 ...
  • 安卓系统,微信小程序调用蓝牙打印机(汉印M35)是怎么打印的。 不知道我的思路对不对。首先调用微信的蓝牙api,然后向蓝牙输出打印指令。 但是我 ...如果思路不正确:那么蓝牙打印思路应该是怎样的?
  • 安卓蓝牙打印 XE10

    2020-07-28 23:33:36
    安卓蓝牙打印 delphi XE10 附源代码 解决手机打印问题
  • android蓝牙打印小票机

    2020-07-30 23:32:06
    最近很多人都在问我android怎么连接蓝牙打印小票机,现在我这里就写出来了一个demo供与大家学习参考,详情图介绍可以看我的博客文章—>android应用—>android蓝牙打印小票机Demo
  • Android蓝牙打印内容排版工具类

    热门讨论 2020-07-21 09:59:58
    此类是用于Android蓝牙打印 内容排版的工具类 用法查看:http://blog.csdn.net/qq331710168/article/details/9170135
1 2 3 4 5 ... 20
收藏数 10,328
精华内容 4,131
关键字:

蓝牙打印