蓝牙连接打印机的小Demo

项目需求,最近在玩蓝牙连接打印机,并实现打印功能的Demo,现在Demo已经完成,打印已做好排版,打印的效果还是不错的,就是.....字体有点大


下面就是用蓝牙连接打印接并且实现打印的流程


1.获取BluetoothAdapter

bluetoothAdapter=BluetoothAdapter.getDefaultAdapter();

有了这个,我们才可以进行下面的操作。


if(!bluetoothAdapter.isEnabled()){
    Intent intent=new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
    startActivityForResult(intent,REQUEST_ENABLE);
}
    Bt_ReadyForScan();
//判断是否正在搜索
if(bluetoothAdapter.isDiscovering()){
    //结束搜索
    bluetoothAdapter.cancelDiscovery();
}
//开始搜索
bluetoothAdapter.startDiscovery();


首先我们判断蓝牙是否已经打开,没有的打开蓝牙那就要打开蓝牙了

isEnabled()    就是判断是否打开蓝牙的方法

Intent intent=new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
    startActivityForResult(intent,REQUEST_ENABLE);   这两步会弹出一个对话框,来提示用户时候打开蓝牙


2.搜索附近的蓝牙设备

isDiscovering()   判断是否在搜索     
bluetoothAdapter.cancelDiscovery()  结束搜索
bluetoothAdapter.startDiscovery();  开始搜索,这时候没搜索到一个蓝牙设备,系统就会发出一个
BluetoothDevice.ACTION_FOUND 广播,所以我们还要注册个自定义的广播来接收并且展示到UI上


BlueBroadcast的代码如下


public void onReceive(Context context, Intent intent) {
    String action=intent.getAction();
    if (BluetoothDevice.ACTION_FOUND.equals(action)){//每发现个蓝牙设备就会发送这个广播

        BluetoothDevice device=intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);//获得搜索到的蓝牙设备
        String name=device.getName();//设备的名字
蓝牙设备的绑定状态,若已经配对就不要了,bluetoothAdapter有方法获得已经配对的蓝牙设备
        if(device!=null&&device.getBondState()!=BluetoothDevice.BOND_BONDED&&name!=null&&name.contains("Jolimark")){
            if(reshList==null)return;
            reshList.refreshList("name:"+device.getName()+"\nMac:"+device.getAddress());

        }
    }else if(BluetoothAdapter.ACTION_DISCOVERY_FINISHED.equals(action)){//搜索结束后发送的广播
            if(reshList==null) return;
            reshList.searchFinished();
    }else if(BluetoothDevice.ACTION_ACL_DISCONNECTED.equals(action)){//蓝牙与设备断开连接时发送的广播
            BluetoothDevice device=intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
            Toast.makeText(context,device.getName()+"已断开连接",Toast.LENGTH_SHORT).show();
            PrintHelper.getInstance().setConnection(false);
            PrintHelper.getInstance().close();
    }

好了,自定义的广播大概就是监听这几种广播,若有其他需求自己在添加


private void Bt_ReadyForScan(){
    //获取已经匹配的蓝牙列表
    BlueListAdapter adapter = (BlueListAdapter) device_pair.getAdapter();
    adapter.removeAll();
    Set<BluetoothDevice> bondedDevices = bluetoothAdapter.getBondedDevices();
    if(bondedDevices.size()>0){
        for (BluetoothDevice device:bondedDevices) {
            if(device.getName().contains("Jolimark")){//我这是过滤掉其他的设备,只要Jolimark打印机设备
                adapter.add("name:"+device.getName()+"\nMac:"+device.getAddress());
            }
        }
    }

}

3.连接设备


前面做的事都是为了得到设备的Mac地址,得到Mac地址之后我们就可以去连接设备了


remoteDevice=bluetoothAdapter.getRemoteDevice(deviceAddress);//根据Mac地址来得创建个RemoteDevice
bluetoothSocket = remoteDevice.createRfcommSocketToServiceRecord(UUID.fromString(uuid));
bluetoothSocket.connect();
outputStream = bluetoothSocket.getOutputStream();
inputStream = bluetoothSocket.getInputStream();

UUID是固定的  
String uuid="00001101-0000-1000-8000-00805F9B34FB"

是不是很熟悉,蓝牙连接用的也是Socket,blue Socket得到IO流之后,我们就可以来给连接的打印设备去发送打印指令了


4.发送打印指令

这个就得看打印机的文档了,虽然说ESC指令大多数都是通用的,但还是有个是不同的


对于封装指令来格式话打印,例如字体大小啊,粗体  请可参考   http://blog.csdn.net/a214024475/article/details/52996047 
还有去看看ESC命令文档,她的打印格式化还是不错的,但是我公司打印的发票在打印多列的情况,最后一列并不是在打印发票的最末尾

我推荐还是使用自定义水平制表,来改变打印的位置

public ThermalPaper setTable(int[] table) {
    byte[] cmd = new byte[table.length + 3];
    cmd[0] = 0x1B;
    cmd[1] = 0x44;
    for (int i = 0; i < table.length; i++) {
        cmd[i + 2] = (byte)(table[i] & 0xFF);
    }
    cmd[cmd.length - 1] = 0;
    datas=twoToOne(datas,cmd);
    return this;
}

public ThermalPaper nextTab() {
    byte[] cmd = {0x09};
    datas=twoToOne(datas,cmd);
    return this;
}
我的理解就是,int数组里的每个数都代表的是一个水平制表的位置,这个位置是从0开始计算的,int数组的值就代表的多少个字节,我的打印机打印的汉子是1个汉字两个字节

所以一个汉字的宽度就是两个字节,一个字母和数字的宽度就是一个字节。int数组的长度就是水平制表的个数。

注意,int数组中不能出现0,还有后面的数一定不能小于前面的数。






对于定位,打印机是有黑标功能的,打印纸上面的右边侧是有个黑色的标记,都是用来定位,来找到打印开始的位置和打印结束后撕纸的位置

怎么定位?

{(byte)0x1D,(byte) 0x0c}

封装好定位黑标的指令用outputStream发送过去就可以定位到黑标了,打印开始的位置和打印结束后撕纸的位置就看自己去调整了,利用走纸和进纸去调就是。


打印开始时我碰到个坑,打印汉字时是乱码  想都不想是编码的问题了,把汉字转化为GB2312格式的编码就行了,这个格式可以看打印机的说明文档,一般是这个格式

text.getBytes("GB2312");

还有就是我把文字转化的字节数组发送过去后打印不出来,打印机没反应,这是因为我没有在文字后面加\r\n来实现换行,或者我们在后面发送个 打印并换行的指令



  • 0
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值