Home Article h5+app 蓝牙打印小票功能开发

h5+app 蓝牙打印小票功能开发

Release time:2020-07-03 Author:Mr.赵 Reading volume:14

数据库(极简版):

DROP TABLE IF EXISTS `tbprinter`;
CREATE TABLE `tbprinter` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`uid` int(11) DEFAULT NULL,
`mac` varchar(50) DEFAULT NULL COMMENT '蓝牙mac_address',
`name` varchar(100) DEFAULT NULL COMMENT '蓝牙名称',
`limitdegree` int(2) DEFAULT '0' COMMENT '默认字段 1默认',
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

-- ----------------------------
-- Records of tbprinter
-- ----------------------------

-- ----------------------------
-- Table structure for `tbshop`
-- ----------------------------
DROP TABLE IF EXISTS `tbshop`;
CREATE TABLE `tbshop` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`shopname` varchar(50) NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

php后台:

public function dyj(){  //进入打印机设置页面
    $shopname = Session::get('shopname');
    $shopinfo = Db::table('tbshop')->where('shopname', $shopname)->find();
    $info=Db::table('tbprinter')->where('uid='.$shopinfo['id'].' AND limitdegree=1')->find();
    if(!$info){
        $info['name']=='';
        $info['mac']=='';
    }
    $this->assign('info',$info);
	return view();
}
public function print_default(){  //打印机提交页面

    $mac  = $this->request->has('newmac') ? $this->request->param('newmac',''): '';
    $name = $this->request->has('newaddress') ? $this->request->param('newaddress',''): '';
    if($mac=='' || $name==''){
        return "<script> {window.alert('设置默认打印机失败');location.href='dyj.html'} </script>";
    }
    $shopname=Session::get('shopname');
    $shopinfo=Db::table('tbshop')->where('shopname',$shopname)->find();
    $shop_id=$shopinfo['id'];
    $data=array();
    $data['uid']=$shop_id;
    if(count(DB::table('tbprinter')->where($data)->select())>0){
        DB::table('tbprinter')->where($data)->update(array('limitdegree'=>0));
    }
    $data['mac']=$mac;
    $data['name']=$name;
    if(DB::table('tbprinter')->where($data)->find()!=false){
        $save=DB::table('tbprinter')->where($data)->update(array('limitdegree'=>1));
    }else{
        $data['limitdegree']=1;
        $save=DB::table('tbprinter')->insert($data);
    }
    if($save){
        return "<script> {window.alert('设置默认打印机成功');location.href='dyj.html'} </script>";
    }else{
        return "<script> {window.alert('设置默认打印机失败');location.href='dyj.html'} </script>";
    }

}
//打印机打印测试页面
public function printer(){
		    //此为简易模板,只需查询+替换 contents的内容即可完整使用
    $shopname=Session::get('shopname');
    $shopinfo=Db::table('tbshop')->where('shopname',$shopname)->find();
    $shop_id=$shopinfo['id'];
    $data=array();
    $data['uid']=$shop_id;
    $data['limitdegree']=1;
    $printerContent=DB::table('tbprinter')->where($data)->find();
    $info=array();
    $info['mac']=$printerContent['mac'];
    $contents='00 111
 日期:2222 
 卡号:8801 
 消费商品:单次票 
  数量:1 
 单价:20/元 
 经办人:系统管理员 

';
    $info['contents']=$contents;
    $this->assign('info',$info);
    return view();
}

前端页面:

打印机设置页面:自行下载mui和jquery
<!DOCTYPE html>
<html lang="en">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>打印机配置</title>
<!-- <link href="/index_files/lanren.css" type="text/css" rel="stylesheet" /> -->
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=1"> 
</head>
<link href="http://mp3.zhaozhiqi.top/css/mui.min.css" rel="stylesheet"/>
<script src="http://mp3.zhaozhiqi.top/js/mui.min.js"></script>
<script src="http://mp3.zhaozhiqi.top/js/mui.js"></script>
<script src="http://mp3.zhaozhiqi.top/js/jquery.min.js"></script>

<style type="text/css">
*{margin:0; padding:0; list-style:none; font-family:'微软雅黑' }
body{ background:#EBECED; }
a{text-decoration: none;}
.form{width:96%; height: 100%; margin:0.3em ; overflow:hidden;color: #1b1b1b; padding:0.2em; 
    background:#fff;  }
.form div{padding:3px 0;overflow: hidden;}
.form label{width: 90px;display: block;float: left;}
.form .infos{width:200px;height: 26px;line-height: 26px;border:1px solid #BFBFBF;padding:2px;border-radius:4px;float: left;}

</style>

<body>
<!--代码部分begin-->
<script>
    var timeout=setTimeout(function () {
        searchDevices();
    },3000);
</script>


        <input type="hidden" id="addresss" value="{$info.name}">
<input type="hidden" id="mac" value="{$info.mac}">
    <div class="form">
        <form method="post" action="{:url('print_default')}"  >
        <div style="width: 100%;height: auto;margin: auto">
            &nbsp;&nbsp;&nbsp;&nbsp; <p style="color: red">注意:</p>  系统只检测已配对的蓝牙打印机,如打印机不在列表中,请手动打开前往系统匹配蓝牙!然后<span onclick="window.location.href=window.location.href" style="color: red">刷新</span>或重新进入本页面检测!
        </div>

        <div>
            <div id="shoutitle">已配对蓝牙设备(搜索中)</div>


            <ul id="list2">

            </ul>
        </div>
        <input type="hidden" id="newaddress" name="newaddress"  value="{$info.name}">
        <input type="hidden" id="newmac" name="newmac" value="{$info.mac}">
        <div id="shownew">
            {if $info.name!=''}
            您已重新选择蓝牙:{$info.name} 作为新的默认打印机
            {else/}
            您暂未设置蓝牙打印机
            {/if}
        </div>
        <div>
            <input type="submit" value="确认设置" />
        </div>
        </form>
        {if $info.name!=''} <input type="button" value="测试打印" onclick="window.location.href='/hztapp/index/index/printer'" /> {/if}
    </div>
            
<!--代码部分end-->
</body>

<script type="text/javascript">
    var bArray = [];

    function scanBluetoothDevice(callback) {
        //获取android应用Activity对象
        var main = plus.android.runtimeMainActivity();
        //过滤器
        var IntentFilter = plus.android.importClass('android.content.IntentFilter');
        //蓝牙设备
        var BluetoothDevice = plus.android.importClass("android.bluetooth.BluetoothDevice");
        //蓝牙适配器
        var BluetoothAdapter = plus.android.importClass("android.bluetooth.BluetoothAdapter");

        var filter = new IntentFilter();
        var BDevice = new BluetoothDevice();
        //蓝牙本地适配器
        var BAdapter = BluetoothAdapter.getDefaultAdapter();

        // 判断是否开启蓝牙
        if (!BAdapter.isEnabled()) {
            BAdapter.enable(); //启动蓝牙
        }
        BAdapter.startDiscovery(); //开启搜索

        var receiver = plus.android.implements('io.dcloud.android.content.BroadcastReceiver', {
            onReceive: function (context, intent) { //回调
                try {
                    plus.android.importClass(intent); //通过intent实例引入intent类
                    if (intent.getAction() == "android.bluetooth.adapter.action.DISCOVERY_FINISHED") {
                        main.unregisterReceiver(receiver); //取消监听
                    } else {
                        //从Intent中获取设备对象
                        BDevice = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);

                        if (BDevice == null) {
                            main.unregisterReceiver(receiver); //取消监听
                            return;
                        }

                        var name = BDevice.getAddress() + BDevice.getName();
                        if (bArray.indexOf(name) == -1) {     //去重
                            bArray.push(name);
                            callback({
                                "name": BDevice.getName(),
                                "SN": BDevice.getAddress()
                            });
                        }

                    }
                } catch (e) {
                    console.error(e);
                }
            }
        });

        //main.unregisterReceiver(receiver); //取消监听,这一步可以不需要

        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); //注册监听
    }

    //address=""搜索蓝牙//address=设备mac地址,自动配对给出mac地址的设备
    function searchDevices() {

//注册类
        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();
        var filter = new IntentFilter();
        var bdevice = new BluetoothDevice();

        var un = null;
        $('#list2').html('');

        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);//取消监听

                    // console.log("搜索结束")

                } else {
                    BleDevice = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
//判断是否配对
                    if (BleDevice.getBondState() == bdevice.BOND_NONE) {

                    } else {

                        if (BleDevice.getName() != un) { //判断防止重复添加
                            var nums=Math.ceil(Math.random()*10000);
                            un = BleDevice.getName();
                            var html='<li id="'+nums+'" class="'+BleDevice.getAddress()+'" onclick="print('+nums+')"  ';
                            var macs=$('#macs').val();
                            var addresss=$('#addresss').val();
                            if(BleDevice.getAddress()==macs && BleDevice.getName()==addresss){
                                html+='style="backgrount-color:black"';
                            }
                            html+=   '>'+BleDevice.getName()+'</li>';
                            // console.log(html);
                            $('#list2').append(html);

                        }
                    }

                }   
                var htmlsss="已配对蓝牙设备(搜索完成)";
                $('#shoutitle').html(htmlsss);

            }

        });
        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); //注册监听
    }

    var device = null,
        BAdapter = null,
        BluetoothAdapter = null,
        uuid = null,
        main = null,
        bluetoothSocket = null;

    function print(idnum) {
        var aa=$('#'+idnum).attr("class"); //mac地址
        var cc=$('#'+idnum).text();   //蓝牙名称
        $('#newmac').val(aa);
        $('#newaddress').val(cc);
        var htmla="您已重新选择蓝牙:<a color='red'>"+cc+"</a> 作为新的默认打印机";
        console.log(htmla);
        $('#shownew').html(htmla);
        console.log($('#newmac').val());console.log($('#newaddress').val());


    }

</script>
</html>
打印机测试页面
<!DOCTYPE html>

<head>
    <meta charset="UTF-8">

    <title></title>

    <meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=1">
    <link href="/css/mui.min.css" rel="stylesheet"/>
    <script src="/js/mui.min.js"></script>
    <script src="/js/mui.js"></script>
    <script src="/js/jquery.min.js"></script>
</head>

<body>
<input type="hidden" id="mac" value="{$info.mac}">
<div style="color: red">蓝牙小票打印准备中..........</div>
<div id="contents">{$info.contents}</div>
<script>
    var timeout=setTimeout(function () {
        var mac=$('#mac').val();
        print(mac);
    },3000)
    // var timeout=setTimeout(function () {
    //    window.history.back(-2);
    // },6000)
</script>






</body>


<script type="text/javascript">
    var bArray = [];

    function scanBluetoothDevice(callback) {
        //获取android应用Activity对象
        var main = plus.android.runtimeMainActivity();
        //过滤器
        var IntentFilter = plus.android.importClass('android.content.IntentFilter');
        //蓝牙设备
        var BluetoothDevice = plus.android.importClass("android.bluetooth.BluetoothDevice");
        //蓝牙适配器
        var BluetoothAdapter = plus.android.importClass("android.bluetooth.BluetoothAdapter");

        var filter = new IntentFilter();
        var BDevice = new BluetoothDevice();
        //蓝牙本地适配器
        var BAdapter = BluetoothAdapter.getDefaultAdapter();

        // 判断是否开启蓝牙
        if (!BAdapter.isEnabled()) {
            BAdapter.enable(); //启动蓝牙
        }
        BAdapter.startDiscovery(); //开启搜索

        var receiver = plus.android.implements('io.dcloud.android.content.BroadcastReceiver', {
            onReceive: function (context, intent) { //回调
                try {
                    plus.android.importClass(intent); //通过intent实例引入intent类
                    if (intent.getAction() == "android.bluetooth.adapter.action.DISCOVERY_FINISHED") {
                        main.unregisterReceiver(receiver); //取消监听
                    } else {
                        //从Intent中获取设备对象
                        BDevice = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);

                        if (BDevice == null) {
                            main.unregisterReceiver(receiver); //取消监听
                            return;
                        }

                        var name = BDevice.getAddress() + BDevice.getName();
                        if (bArray.indexOf(name) == -1) {     //去重
                            bArray.push(name);
                            callback({
                                "name": BDevice.getName(),
                                "SN": BDevice.getAddress()
                            });
                        }

                    }
                } catch (e) {
                    console.error(e);
                }
            }
        });

        //main.unregisterReceiver(receiver); //取消监听,这一步可以不需要

        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); //注册监听
    }

    //address=""搜索蓝牙//address=设备mac地址,自动配对给出mac地址的设备


    var device = null,
        BAdapter = null,
        BluetoothAdapter = null,
        uuid = null,
        main = null,
        bluetoothSocket = null;

    function print(mac_address) {
        if (!mac_address) {
            mui.toast('请选择蓝牙打印机');
            return;
        }

        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(mac_address);
        plus.android.importClass(device);
        bluetoothSocket = device.createInsecureRfcommSocketToServiceRecord(uuid);
        plus.android.importClass(bluetoothSocket);

        if (!bluetoothSocket.isConnected()) {
            console.log('检测到设备未连接,尝试连接....');
            bluetoothSocket.connect();
        }
        console.log(bluetoothSocket);
        if (bluetoothSocket.isConnected()) {
            var outputStream = bluetoothSocket.getOutputStream();
            plus.android.importClass(outputStream);
            var string = $('#contents').html();
            // var string = "\0\0 111\n 日期:2222 \n 卡号:8801 \n 消费商品:单次票 \n  数量:1 \n 单价:20/元 \n 经办人:系统管理员 \n\n\n\n\n";

            var bytes = plus.android.invoke(string, 'getBytes', 'gbk');
            outputStream.write(bytes);
            outputStream.flush();
            device = null //这里关键
            bluetoothSocket.close(); //必须关闭蓝牙连接否则意外断开的话打印错误

        }else{
            alert('蓝牙连接失败!请重试!');
        }
        window.history.back(-2);
    }


</script>


</html>

注意点:1.设置页面理论上来说ajax提交更方便,但是打包成app会无法提交ajax

               2.最好先隐藏提交按钮,防止报错,在print(idnum)最好再显示出来 hide show

               3.为什么随机一个数做id,之前的用mac_address做id去取值的,但是mac格式是 aa:bb:cc:dd的 用jq的 $('#mac’).html() 时候会找不到,为了多方面协调,改成了现在的写法



  
I want to comment
Leave a message
http://boke.zhaozhiqi.top/index.php/
User login
You have not written any reviews yet!
You have commented!
Can only praise once!
You have a collection!