微信硬件蓝牙设备开发demo(完整版)13篇

2016年09月08日 10:37 | 4280次浏览 | 分类: 微信蓝牙开发 作者原创 版权保护

关于微信硬件蓝牙设备开发案例已经分享了很多代码案例,这节总结一下,给大家晒出完整的代码示例,只要读者复制黏贴到自己项目中,即可运行,不用修改,本示例是经过作者测试成功分享而出,请尊重原创,转载注明本网站出处。

完整微信硬件接入案例源码:点我下载案例源码

咱们首先看看写好的示例文件

1,代码示例文件

1,如上图所示,一共有7个文件,实际上示例文件只有五个,其中weui.css和weui.min.css是相同文件,只是一个压缩了而已,而微信硬件蓝牙开发完整demo的zip文件为示例压缩文件。

2,b_chat_t.html文件为操作微信硬件蓝牙设备和微信app之间通讯的H5界面,其中有三个按钮,充值按钮,查询余额按钮,刷新按钮,点击刷新按钮获取蓝牙设备信息。


3,bytes_base64.js和data_object.js文件为调用微信硬件jsapi接口文件,非常重要

4,weui.css文件是微信weui样式文件

5,jquery.min.js文件,由于微信硬件jsapi接口依赖jquery,所以此文件为jquery依赖库。

2,实例文件代码分享

1,b_chat_t.html文件示例代码

<!DOCTYPE html>
<html>
<head>
  <meta charset="utf-8">
  <title>V型知识库 智能购电</title>
  <meta name="viewport" content="width=device-width, initial-scale=1, user-scalable=0">
  <link rel="stylesheet" href="weui.min.css?what=0">
  <script src="jquery.min.js?what=0"> </script>
  <script src="http://res.wx.qq.com/open/js/jweixin-1.1.0.js"> </script>
  <script src="data_object.js?what=0"></script>
  <script src="bytes_base64.js?what=0"></script>
</head>
<body ontouchstart>

<!--标题行 V型知识库 www.vxzsk.com-->
<h1 style="color: white;background-color: green;text-align: center;background-position: center;">V型知识库-微信硬件蓝牙jsapi示例</h1>
  

<div class="page">
    <div class="bd spacing">
        <div class="weui_cells weui_cells_form">
             	<input type="hidden" id="BLEState" value=""></input>
	            <input type="hidden" id="open-id" value=""></input> 
        	 <div class="weui_cell">
                <div class="weui_cell_hd"><label class="weui_label" style="width: auto;">充值金额(元):&nbsp</label></div>
                <div class="weui_cell_bd weui_cell_primary">
                    <input id="addMoney" class="weui_input" style="color: blue;" type="number" onkeyup="return ValidateFloat2(this,value)" placeholder="请输入金额值" readonly="true"/>
                </div>
            </div>
            <div class="weui_cell">
                <div class="weui_cell_hd"><label class="weui_label" style="width: auto;">当前余额(元):&nbsp</label></div>
                <div class="weui_cell_bd weui_cell_primary">
                    <input id="curBalance" class="weui_input" style="color: red;" type="text" placeholder="尚未查询"  readonly="true"/>
                </div>
            </div>
            <div class="weui_cell">
                <div class="weui_cell_hd"><label class="weui_label" style="width: auto;">当前设备:&nbsp</label></div>
                <div class="weui_cell_bd weui_cell_primary">
                   <label id="lbdeviceid" class="weui_label" style="width: auto;"></label>
                </div>
            </div>
            <div class="weui_cell">
                <div class="weui_cell_hd"><label class="weui_label" style="width: auto;">状态信息:&nbsp</label></div>
                <div class="weui_cell_bd weui_cell_primary">
                    <label id="lbInfo" class="weui_label" style="width: auto;"></label>
                </div>
            </div>
            <div class="weui_cell" style="visibility:hidden">
            	<div class="weui_cell_hd"><label class="weui_label">日志:  </label></div>
                <div class="weui_cell_bd weui_cell_primary">
                    <textarea id="logtext" class="weui_textarea" placeholder="日志" rows="5"></textarea>
                </div>
            </div>
        </div>
    	<div class="weui_btn_area weui_btn_area_inline">
	        <button class="weui_btn weui_btn_disabled weui_btn_primary" id="CallAddValue">充值</button>
	        <button class="weui_btn weui_btn_disabled weui_btn_primary" id="CallGetBalance">查余额</button>
            <button class="weui_btn weui_btn weui_btn_warn" id="CallGetWXrefresh">刷新</button>
        </div>
        
        
    </div>
    
    
    <div class="weui_dialog_alert" id="Mydialog" style="display: none;">
    <div class="weui_mask"></div>
    <div class="weui_dialog">
        <div class="weui_dialog_hd" id="dialogTitle"><strong class="weui_dialog_title">着急啦</strong></div>
        <div class="weui_dialog_bd" id="dialogContent">亲,使用本功能,请先打开手机蓝牙!</div>
        <div class="weui_dialog_ft">
            <a href="#" class="weui_btn_dialog primary">确定</a>
        </div>
    </div>
    </div>
    
    
    <!--BEGIN toast-->
    <div id="toast" style="display: none;">
        <div class="weui_mask_transparent"></div>
        <div class="weui_toast">
            <i class="weui_icon_toast"></i>
            <p class="weui_toast_content" id="toast_msg">已完成</p>
        </div>
    </div>
    <!--end toast-->

    <!-- loading toast -->
    <div id="loadingToast" class="weui_loading_toast" style="display:none;">
        <div class="weui_mask_transparent"></div>
        <div class="weui_toast">
            <div class="weui_loading">
                <div class="weui_loading_leaf weui_loading_leaf_0"></div>
                <div class="weui_loading_leaf weui_loading_leaf_1"></div>
                <div class="weui_loading_leaf weui_loading_leaf_2"></div>
                <div class="weui_loading_leaf weui_loading_leaf_3"></div>
                <div class="weui_loading_leaf weui_loading_leaf_4"></div>
                <div class="weui_loading_leaf weui_loading_leaf_5"></div>
                <div class="weui_loading_leaf weui_loading_leaf_6"></div>
                <div class="weui_loading_leaf weui_loading_leaf_7"></div>
                <div class="weui_loading_leaf weui_loading_leaf_8"></div>
                <div class="weui_loading_leaf weui_loading_leaf_9"></div>
                <div class="weui_loading_leaf weui_loading_leaf_10"></div>
                <div class="weui_loading_leaf weui_loading_leaf_11"></div>
            </div>
            <p class="weui_toast_content" id="loading_toast_msg">数据加载中</p>
        </div>
    </div>
    <!-- End loading toast -->
    
    <!--BEGIN dialog1-->
    <div class="weui_dialog_confirm" id="dialog1" style="display: none;">
        <div class="weui_mask"></div>
        <div class="weui_dialog">
            <div class="weui_dialog_hd"><strong class="weui_dialog_title">弹窗标题</strong></div>
            <div class="weui_dialog_bd">自定义弹窗内容,居左对齐显示,告知需要确认的信息等</div>
            <div class="weui_dialog_ft">
                <a href="javascript:;" class="weui_btn_dialog default" id="qxBtn">取消</a>
                <a href="javascript:;" class="weui_btn_dialog primary" id="okBtn">确定</a>
            </div>
        </div>
    </div>
    <!--END dialog1-->
    <!--BEGIN dialog2-->
    <div class="weui_dialog_alert" id="dialog2" style="display: none;">
        <div class="weui_mask"></div>
        <div class="weui_dialog">
            <div class="weui_dialog_hd"><strong class="weui_dialog_title">弹窗标题</strong></div>
            <div class="weui_dialog_bd">弹窗内容,告知当前页面信息等</div>
            <div class="weui_dialog_ft">
                <a href="javascript:;" class="weui_btn_dialog primary">确定</a>
            </div>
        </div>
    </div>
    <!--END dialog2-->
</div>
</body> 

</html>

2,bytes_base64.js文件示例代码

/**
 * 	作者:
 * 		V型知识库 www.vxzsk.com
 * 	创建日期:
 * 		2016年04月02日
 *  参考连接:
 *	 
 */

/** 字符串转换成Base64字符 */
function string_to_base64(rawString) {
	if (rawString.length == 0) {
		return "";
	}
	var b64Chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/';
	var result = "";
	// 给末尾添加的字符,先计算出后面的字符
	var d3 = rawString.length % 3;
	var endChar = "";
	if (d3 == 1) {
		var value = rawString.charCodeAt(rawString.length - 1);
		endChar = b64Chars.charAt(value >> 2);
		endChar += b64Chars.charAt((value << 4) & 0x3F);
		endChar += "==";
	} else if (d3 == 2) {
		var value1 = rawString.charCodeAt(rawString.length - 2);
		var value2 = rawString.charCodeAt(rawString.length - 1);
		endChar = b64Chars.charAt(value1 >> 2);
		endChar += b64Chars.charAt(((value1 << 4) & 0x3F) + (value2 >> 4));
		endChar += b64Chars.charAt((value2 << 2) & 0x3F);
		endChar += "=";
	}

	// 计算能进行多少次完整的转换, ** JavaScript中不会切掉小数点后面的数, 就是说tiems是浮点型数据,times不减一就会多循环一次
	// 在字符能被整除的情况下,会少循环一次所以要判断是否能被整除 (d3 == 0 ? 0 : 1)
	var times = rawString.length / 3;
	var startIndex = 0;
	// 开始计算
	for (var i = 0; i < times - (d3 == 0 ? 0 : 1); i++) {
		startIndex = i * 3;
		// 原字单个符串
		var S1 = rawString.charCodeAt(startIndex + 0);// 第一个字符的码值
		var S2 = rawString.charCodeAt(startIndex + 1);// 第二个字符的码值
		var S3 = rawString.charCodeAt(startIndex + 2);// 第三个字符的码值

		// 转换之后的单个字符的对应的Base64码值
		var s1 = b64Chars.charAt(S1 >> 2);
		var s2 = b64Chars.charAt(((S1 << 4) & 0x3F) + (S2 >> 4));
		var s3 = b64Chars.charAt(((S2 & 0xF) << 2) + (S3 >> 6));
		var s4 = b64Chars.charAt(S3 & 0x3F);
		// 添加到结果字符串中
		result += (s1 + s2 + s3 + s4);
	}

	return result + endChar;
}

/**
 *  Byte数组转Base64字符,原理同上 
 *	@Param [0x00,0x00]
 *	@return Base64字符串
 **/
function bytes_array_to_base64(array) {
	if (array.length == 0) {
		return "";
	}
	var b64Chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/';
	var result = "";
	// 给末尾添加的字符,先计算出后面的字符
	var d3 = array.length % 3;
	var endChar = "";
	if (d3 == 1) {
		var value = array[array.length - 1];
		endChar = b64Chars.charAt(value >> 2);
		endChar += b64Chars.charAt((value << 4) & 0x3F);
		endChar += "==";
	} else if (d3 == 2) {
		var value1 = array[array.length - 2];
		var value2 = array[array.length - 1];
		endChar = b64Chars.charAt(value1 >> 2);
		endChar += b64Chars.charAt(((value1 << 4) & 0x3F) + (value2 >> 4));
		endChar += b64Chars.charAt((value2 << 2) & 0x3F);
		endChar += "=";
	}

	var times = array.length / 3;
	var startIndex = 0;
	// 开始计算
	for (var i = 0; i < times - (d3 == 0 ? 0 : 1); i++) {
		startIndex = i * 3;

		var S1 = array[startIndex + 0];
		var S2 = array[startIndex + 1];
		var S3 = array[startIndex + 2];

		var s1 = b64Chars.charAt(S1 >> 2);
		var s2 = b64Chars.charAt(((S1 << 4) & 0x3F) + (S2 >> 4));
		var s3 = b64Chars.charAt(((S2 & 0xF) << 2) + (S3 >> 6));
		var s4 = b64Chars.charAt(S3 & 0x3F);
		// 添加到结果字符串中
		result += (s1 + s2 + s3 + s4);
	}

	return result + endChar;
}

/**
 * 将Base64字符串转换成Byte数组
 * @return [0x00,0x00]
 * @param 字符串
 */
function base64_to_bytes_array(base64String) {
	var result = new Array();
	if (base64String.length % 4 != 0 || base64String.length == 0) {
		return result;
	}
	var b64Chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/';
	// 先将后面的字段转换成原来的Byte数组
	var len = base64String.length;
	var endBytes = new Array();
	if (base64String.charAt(len - 1) == "=") {
		if (base64String.charAt(len - 2) == "=") {								// 有两个等号的情况
			var s1 = base64String.charAt(len - 4);								// 后面的第一个字符
			var s2 = base64String.charAt(len - 3);								// 后面的第二个字符
			var v1 = ((b64Chars.indexOf(s1) << 2) & 0xFF) + (b64Chars.indexOf(s2) >> 4);	//这个就是最后面的一个字节
			
			endBytes[0]=v1;
		} else {																// 只有一个等号的情况
			var s1 = base64String.charAt(len - 4);								// 后面的第一个字符
			var s2 = base64String.charAt(len - 3);								// 后面的第二个字符
			var s3 = base64String.charAt(len - 2);								// 后面的第三个字符
			
			var v1= ((b64Chars.indexOf(s1) << 2) & 0xFF) + (b64Chars.indexOf(s2) >> 4);		//这个就是最后面的第一个字节
			var v2= ((b64Chars.indexOf(s2) << 4) & 0xFF) + (b64Chars.indexOf(s3) >> 2);		//这个就是最后面的第二个字节
			
			endBytes[0] = v1;
			endBytes[1] = v2;
		}
	}

	var times = base64String.length / 4;

	for (var i = 0; i < times - (endBytes.length == 0 ? 0 : 1); i++) {
		var startIndex = i * 4;
		var V1 = base64String.charAt(startIndex + 0);
		var V2 = base64String.charAt(startIndex + 1);
		var V3 = base64String.charAt(startIndex + 2);
		var V4 = base64String.charAt(startIndex + 3);

		result[i * 3 + 0]=((b64Chars.indexOf(V1) << 2) & 0xFF) + (b64Chars.indexOf(V2) >> 4);
		result[i * 3 + 1]=((b64Chars.indexOf(V2) << 4) & 0xFF) + (b64Chars.indexOf(V3) >> 2);
		result[i * 3 + 2]=((b64Chars.indexOf(V3) << 6) & 0xFF) + b64Chars.indexOf(V4);
	}
	return result.concat(endBytes);
}
/**
 * 把字节数组按16进制打印,这里需要保证数组的每个元素是Number类型
 * @param bytes
 */
function print_hex(bytes){
	var hexString="Head:[";
	for(var i=0;i<bytes.length;i++){
		if(i===bytes.length-1 || i===11) hexString+=(bytes[i]>0xF?bytes[i].toString(16):"0"+bytes[i].toString(16));
		else hexString+=(bytes[i]>0xF?bytes[i].toString(16):"0"+bytes[i].toString(16))+",";
		if(i===11) hexString+="]<br/>Body:[";
	}
	hexString+="]";
	return hexString;
}

/**
 * 16进制的字符串转换成字节数组
 * @param hexString
 */
function parseToBytes(hexString){
	var bytes=new Array();
	if(bytes.length%2==0){
		var len=hexString.length;
		for(var i=0,j=0; j<len; i++,j+=2){
			bytes[i]=parseInt(hexString[j]+hexString[j+1],16);
		}
	}else{
		alert("当前数据字符的  长度  不能被2整除,请在末尾添加0,或者在末尾前一位插入零!");
	}
	return bytes;
}
/*************************************************
 * 作者: wxh 2016-04-03
 * 十进制数字转换成16进制的字节,高位在前
 * 例如 500 转换成 16禁止为 : 01 F4
 * 入口参数:
 *   N :10进制字符串
 * 出口参数:
 *   返回字节数组
 *************************************************/
 function DataToBytes(N){
    var bytes=new Array();     // 定义返回数组
    //1. 首先把N扩大100倍,因为金额是精确到分
    var N100 = Number(N);
    //1.1 吐过是数字,则执行下面的操作
    if (!isNaN(N100)){
        N100=N100*100;
        var HexStr=N100.toString(16);  //转变成16进制字符串
        if (HexStr.length%2!==0){
            HexStr='0'+HexStr;   
        };
        
        if(HexStr.length>8){
            HexStr='00000000';
        }
        else
        {
            var len=HexStr.length;
            for(i=0;i<(8-len);i++){
                HexStr='0'+HexStr;
            }
        }
        
    }
    else
       HexStr='00000000';   
    return parseToBytes(HexStr);
 }
 
 /****************************************************
  * 作者:wxh 2016-04-03
  * 把命令字节增加校验和字节,并把校验和字节放在最后的位置
  * 例如 01 02 结果为:01 02 03  执行的是XOR校验
  * 入口参数:
  *     DataBytes;
  * 出口参数:
  *     返回带校验和的字节数组       
 ****************************************************/
 function GetCommandByes(DataBytes){
    var len=DataBytes.length;
    var ReturnBytes = new Array();
    var x=0;
    for(var i=0; i<=len-1; i++){
        ReturnBytes[i]=DataBytes[i];
        x=x ^ ReturnBytes[i];  //按位置异或
		}
       ReturnBytes[len]=x; 
    return ReturnBytes;   
 }
 
 /************************************************
  * 作者:wxh 2016-04-03
  * 查询余额命令
  * 返回查询余额字节流
  * 入口参数:无
  * 出口参数:返回余额字节流
 ************************************************/
 function CheckBalance(){
    var Bytes=new Array();
    Bytes[0]=0x02;
    Bytes[1]=0x00;
    Bytes[2]=0x01;
    Bytes[3]=0x33;
    Bytes[4]=0x03;
    Bytes[5]=0x33;
    return Bytes;
 }

 /************************************************
  * 作者:wxh 2016-04-03
  * 充值
  * 返回需要充值的字节流
  * 入口参数:
  *    Money: 需要充值的金额
  * 出口参数: 返回充值字节流
 ************************************************/ 
 function AddValue(Money){
    var MoneyBytes=DataToBytes(Money);
    var RBytes=new Array();
    var len=MoneyBytes.length;
    RBytes[0]=0x02;
    RBytes[1]=0x00;
    RBytes[2]=0x05;
    RBytes[3]=0x34;
    //保存充值金额
    for(var i=0; i<=3; i++){
        RBytes[i+4]=MoneyBytes[i];
		}
    RBytes[8]=0x03;
    //取得生成的结果字节流
    return GetCommandByes(RBytes);     
 }
 
 /************************************************
  * 作者:wxh 2016-04-03
  * 查询是否已经插入电卡命令
  * 返回需要的字节流
  * 入口参数: 无
  * 出口参数: 返回充值字节流
 ************************************************/ 
 function CheckCard(){
   var Bytes=new Array();
    Bytes[0]=0x02;
    Bytes[1]=0x00;
    Bytes[2]=0x02;
    Bytes[3]=0x31;
    Bytes[4]=0x44;
    Bytes[5]=0x03;
    Bytes[6]=0x76;
    return Bytes; 
 }

/************************************************
 * 作者:wxh 2016-04-04
 * 返回命令解析
 * 检查当前命令是否合法,返回是什么命令
 * 入口参数:
 *    recev_Data : 字节流,收到的字节内容
 * 出口参数:
 *    返回命令码,如果命令码=0,表示命令长度不足,=1表示校验错误 
*************************************************/

//声明一个结果对象
 var recevResult=new Object();
     recevResult.command=0;  //保存命令码,如果是0表示错误,具体错误参见result
     recevResult.result=0;   //保存结果,0:命令长度不足;1:校验码错误 
 
 function checkReceiveData(recev_Data){
    var len=recev_Data.length;
    //1. 如果命令长度不够最小的6,则返回0
    if(len < 6){
      recevResult.command=0;
      recevResult.result=0;
      return recevResult
    };
    //取得实际命令长度
    var datalen=recev_Data[1]*256 + recev_Data[2];  
    //2. 实际长度是否符合协议要求
    if((3+datalen + 2) < len){ //命令长度错误
      recevResult.command=0;
      recevResult.result=0;
      return recevResult
    };
    //3. 验证效验码是否OK
    var x=0;
    for(var i=0; i<=len-2; i++){
        x=x ^ recev_Data[i];  //按位置异或
		};
    if(x!==recev_Data[len-1]){ //校验码错误
      recevResult.command=0;
      recevResult.result=1;
      return recevResult
    };
    //4. 经过以上步骤,说明数据已经合法
    switch (recev_Data[3]) //根据命令码
    {
        case 0x31:  //查询版本、查询有无电卡
            switch (recev_Data[4])
            {
                case 0x40:  //查询版本
                    recevResult.command=0x40;
                    recevResult.result='ABCD';
                    return recevResult  
                case 0x44:  //查询有无电卡
                    switch (recev_Data[5])
                    {
                        case 0x30:  //无卡
                            recevResult.command=0x31;
                            recevResult.result=0;
                            return recevResult  
                        case 0x31:  //有卡
                            recevResult.command=0x31;
                            recevResult.result=1;
                            return recevResult 
                        default:  //其他值,表示错误
                            recevResult.command=0x31;
                            recevResult.result=2;
                            return recevResult    
                    }
            };    
        case 0x33:  //查询余额
          switch (recev_Data[4])
          {
            case 0x59:  //余额查询成功
              recevResult.command=0x33;
              recevResult.result=0;
              recevResult.result=recev_Data[5]*256*256*256 + recev_Data[6]*256*256 + recev_Data[7]*256 + recev_Data[8];
              recevResult.result=recevResult.result/100;
              //alert('0x59');  
              return recevResult; 
            case 0x47:  //没有发现卡
              //alert('0x47');           
              recevResult.command=0x00;
              recevResult.result=0x47;  //没有发现卡   
              return recevResult;   
            case 0x4E:  //查询失败
              recevResult.command=0x00;
              recevResult.result=0x4E;  //查询失败   
              return recevResult     
          };    
        case 0x34:  //电卡充值
          switch (recev_Data[4])
          {
            case 0x59:  //电卡充值成功
              recevResult.command=0x34;
              recevResult.result=0;
              recevResult.result=recev_Data[5]*256*256*256 + recev_Data[6]*256*256 + recev_Data[7]*256 + recev_Data[8];
              recevResult.result=recevResult.result/100;
              return recevResult; 
            case 0x47:  //没有发现卡
              recevResult.command=0x00;
              recevResult.result=0x47;  //没有发现卡   
              return recevResult;   
            case 0x4E:  //电卡充值失败
              recevResult.command=0x00;
              recevResult.result=0x4E;  //电卡充值失败   
              return recevResult     
          };  
        default:
          recevResult.command=0;
          recevResult.result=0;
          return recevResult 
    } // switch (recev_Data[3]) //根据命令码   
 } //函数结尾

/*****************************************************
 * 输入框中只可以输入数字,可以输入2位小数点的数字
*****************************************************/
function ValidateFloat2(e, pnumber)
{
 if (!/^\d+[.]?[0-9]?[0-9]?$/.test(pnumber))
 {
   e.value = /\d+[.]?[0-9]?[0-9]?/.exec(e.value);
 }
return false;
}

/*****************************************************
 * 以下为WX调用的函数
*****************************************************/

function showOKToastByTime(message,time) {
    var $toast = $('#toast');
    var $toast_msg= $('#toast_msg');
    $toast_msg.text(message);
    
    if ($toast.css('display') != 'none') {
        return;
    }

    $toast.show();
    if(time>0){//2000
	    setTimeout(function () {
	        $toast.hide();
	    }, time);
    }
};

function showOKToast(message) {
	showOKToastByTime(message,0);
};

function hideOKToast() {
    var $toast = $('#toast');
    $toast.hide();
};

function showLoadingToastByTime(message,time) {
	var $loadingToast = $('#loadingToast');
    var $loading_toast_msg= $('#loading_toast_msg');
    $loading_toast_msg.text(message);
    
    if ($loadingToast.css('display') != 'none') {
        return;
    }

    $loadingToast.show();
    if(time>0){
	    setTimeout(function () {
	        $loadingToast.hide();
	    }, time);
    }
};
function showLoadingToast(message) {
	showLoadingToastByTime(message,0);
};

function hideLoadingToast() {
    var $loadingToast = $('#loadingToast');
    $loadingToast.hide();
};

function mlog(m){
	var log=$('#logtext').val();
	//log=log+m;
    log = m;
	$('#logtext').val(log);
}

function clog(){
	$('#logtext').val('');
}

var C_DEVICEID=null;

function pHex(bytes){
	var hexString="[";
	for(var i=0;i<bytes.length;i++){
		if(i===bytes.length-1 || i===11) 
			hexString+=(bytes[i]>0xF?bytes[i].toString(16):"0"+bytes[i].toString(16));
		else 
			hexString+=(bytes[i]>0xF?bytes[i].toString(16):"0"+bytes[i].toString(16))+",";
		if(i===11) hexString+="";
	}
	hexString+="]";
	return hexString;
}

var seqCount=1;

/*******************************************************************
 * 发送数据函数
 * 作者:wxh 2016-04-04
 * 入口参数:
 *     cmdBytes: 需要发送的命令字节
 *     selDeviceID: 选择的需要发送设备的ID 
 * 出口参数:
 *     返回: 0表示发送成功;1表示发送失败
 *     如果成功,则接收事件应该能够收到相应的数据
*******************************************************************/
function senddataBytes(cmdBytes,selDeviceID){
  //1. 如果输入的参数长度为零,则直接退出
  if(cmdBytes.length<=0){return 1};
  //1.1 如果设备ID为空,则直接返回
  if(selDeviceID.length<=0){return 1};
  //2. 发送数据
  var x=0;
  WeixinJSBridge.invoke('sendDataToWXDevice', {
			"deviceId":selDeviceID, 
			"base64Data":bytes_array_to_base64(cmdBytes)
			}, function(res){
			if(res.err_msg=='sendDataToWXDevice:ok')
               {
                 $("#deviceStatus").val("数据发送成功");
                 x=0;
               }  
            else
               {
                 $("#deviceStatus").val("数据发送失败");
                 x=1; 
               } 
		});  
  return x;      
}

/*********************************************************
* 打开微信设备
* 作者:V型知识库 www.vxzsk.com 2016-04-04
* my_openWXDeviceLib
* 入口参数:无
* 出口参数:0表示打开成功;1表示打开失败
*********************************************************/
function my_openWXDeviceLib(){
   var x=0; 
   WeixinJSBridge.invoke('openWXDeviceLib', {}, 
   function(res){
      if(res.err_msg=='openWXDeviceLib:ok')
        {
          if(res.bluetoothState=='off')
            {    
              showdialog("太着急啦","亲,使用前请先打开手机蓝牙!");  
              $("#lbInfo").innerHTML="1.请打开手机蓝牙";
              $("#lbInfo").css({color:"red"});
              x=1;
            };
          if(res.bluetoothState=='unauthorized')
            {
              showdialog("出错啦","亲,请授权微信蓝牙功能并打开蓝牙!");    
              $("#lbInfo").html("1.请授权蓝牙功能");
              $("#lbInfo").css({color:"red"});
              x=1;
            }; 
          if(res.bluetoothState=='on')
            {
              $("#lbInfo").html("1.蓝牙已打开,未找到设备");
              $("#lbInfo").css({color:"red"});
              //$("#lbInfo").attr(("style", "background-color:#000");
              x=0;
            };      
        }
      else
        {
          $("#lbInfo").html("1.微信蓝牙打开失败");
          x=1;  
        }
    });
   return x;  //0表示成功 1表示失败
}

/*********************************************************
* 装载微信事件处理
* 作者:V型知识库 www.vxzsk.com 2016-04-04
* my_installwxEvents
* 入口参数:无
* 出口参数:无
*********************************************************/
 function my_installwxEvents(){
   //1. 安装微信绑定事件
   WeixinJSBridge.on('onWXDeviceBindStateChange', function(argv) {
       //todo
		}); 
   //2. 扫描到某个设备      
   WeixinJSBridge.on('onScanWXDeviceResult', function(argv) {
        //todo
	    });
   //3. 手机蓝牙状态改变事件    
   WeixinJSBridge.on('onWXDeviceBluetoothStateChange', function(argv) {
	    //todo
        });         
 }
 
/*********************************************************
* 接收到数据事件
* 作者:V型知识库 www.vxzsk.com 2016-04-04
* my_onReceiveDataFromWXDevice
* 入口参数:无
* 出口参数:无
*********************************************************/ 
function my_onReceiveDataFromWXDevice(){ 
    WeixinJSBridge.on('onReceiveDataFromWXDevice', function(argv) {
		var Bytes=base64_to_bytes_array(argv.base64Data);
        //mlog("接收的数据-->"+pHex(base64_to_bytes_array(argv.base64Data)));
        recevResult=checkReceiveData(Bytes);
        switch (recevResult.command) //根据命令码
        {
            case 0x00: //错误
              switch(recevResult.result)
              {
                case 0x47:
                    $("#lbInfo").html("x.请插入电卡!");
                    $("#lbInfo").css({color:"red"});
                    $("#curBalance").val(""); 
                    showdialog("太着急啦","亲,使用前请先插入电卡!");  
                    break;
                case 0x4E:
                    $("#lbInfo").html("x.余额查询失败!");
                    $("#lbInfo").css({color:"red"});
                    $("#curBalance").val(""); 
                    showdialog("出错啦","操作失败,请重新试");  
                    break;    	     
              }
              break;           
            case 0x33:
              $("#curBalance").val(recevResult.result); 
              break;
            case 0x34:
              $("#curBalance").val(recevResult.result); 
              break;   
        }
	  });
}
 


/**********************************************
* 取得微信设备信息
* 作者:V型知识库 www.vxzsk.com 2016-04-04
* my_getWXDeviceInfos
* 入口参数:无
* 出口参数:返回一个已经链接的设备的ID
**********************************************/
function my_getWXDeviceInfos(){
    EnableAddButton(false);
    EnableBalanceButton(false);
    WeixinJSBridge.invoke('getWXDeviceInfos', {}, function(res){
        var len=res.deviceInfos.length;  //绑定设备总数量
		for(i=0; i<=len-1;i++)
         {
           //alert(i + ' ' + res.deviceInfos[i].deviceId + ' ' +res.deviceInfos[i].state); 
           if(res.deviceInfos[i].state==="connected")
            {
              $("#lbdeviceid").html(res.deviceInfos[i].deviceId); 
              C_DEVICEID = res.deviceInfos[i].deviceId;
              $("#lbInfo").html("2.设备已成功连接");
              $("#lbInfo").css({color:"green"});
              EnableAddButton(true);
              EnableBalanceButton(true);
              break;   
            }  
         }
         	
    }); 
  return;    
}

/**********************************************
* 设备状态变化事件
* 作者:V型知识库 www.vxzsk.com 2016-04-04
* my_onWXDeviceStateChange
* 入口参数:无
* 出口参数:返回一个已经链接的设备的ID
**********************************************/
function my_onWXDeviceStateChange(){
    var con=0;
    WeixinJSBridge.on('onWXDeviceStateChange', 
    function(argv) 
     {
        var deviceId = argv.deviceId;
        var deviceStatus=argv.state;
        $("#curBalance").val(deviceStatus);
        $("#BLEState").val(deviceStatus);
        if(deviceStatus==="connected")
          { 
			$("#lbdeviceid").html(res.deviceInfos[i].deviceId); 
            C_DEVICEID = res.deviceInfos[i].deviceId;
            $("#lbInfo").html("x.蓝牙设备已连接");	  
            //$("#BLEState").val("connected");
          }
        if(deviceStatus==="connecting")
          {
            $("#lbdeviceid").html(res.deviceInfos[i].deviceId); 
            C_DEVICEID = res.deviceInfos[i].deviceId;
            $("#lbInfo").html("x.蓝牙设备正连接...");
            //$("#BLEState").val("connecting");	
          }
        if(deviceStatus==="disconnected")
          {
            $("#lbdeviceid").html(''); 
            C_DEVICEID = "";
            $("#lbInfo").html("x.蓝牙设备已断开");	
            
            EnableAddButton(false);
            EnableBalanceButton(false);
            //$("#BLEState").val("disconnected");
          }	  			
	  });
 }     
 
 /********************************************************
  * 设置充值按键的允许状态
  * 作者:V型知识库 www.vxzsk.com 2016-04-05
  * EnableAddButton(T)
  *入口参数:
  *    T:True表示允许,False表示禁止
  *出口参数:无    
 *********************************************************/

function EnableAddButton(T){
    if(T==false){
      $("#CallAddValue").attr({"disabled":true});      
      $("#CallAddValue").removeClass('weui_btn weui_btn_primary');//删除样式,样式名为className
      $("#CallAddValue").addClass('weui_btn weui_btn_disabled weui_btn_primary');//添加样式,样式名为className  
      //设置充值金额的读写属性
      $("#addMoney").attr("readonly",true);
    }
    else
    {
      $("#CallAddValue").attr({"disabled":false});      
      $("#CallAddValue").removeClass('weui_btn weui_btn_disabled weui_btn_primary');//删除样式,样式名为className
      $("#CallAddValue").addClass('weui_btn weui_btn_primary');//添加样式,样式名为className
      $("#addMoney").attr("readonly",false);    
    }
}

 /********************************************************
  * 设置余额查询按键的允许状态
  * 作者:V型知识库 www.vxzsk.com 2016-04-05
  * EnableBalanceButton(T)
  *入口参数:
  *    T:True表示允许,False表示禁止
  *出口参数:无    
 *********************************************************/
function EnableBalanceButton(T){
    if(T==false){
      $("#CallGetBalance").attr({"disabled":true});  
      $("#CallGetBalance").removeClass('weui_btn weui_btn_primary');//删除样式,样式名为className
      $("#CallGetBalance").addClass('weui_btn weui_btn_disabled weui_btn_primary');//添加样式,样式名为className  
    }
    else
    {
      $("#CallGetBalance").attr({"disabled":false});    
      $("#CallGetBalance").removeClass('weui_btn weui_btn_disabled weui_btn_primary');//删除样式,样式名为className
      $("#CallGetBalance").addClass('weui_btn weui_btn_primary');//添加样式,样式名为className    
    }
}

/***************************************************************
 * 显示提示信息
***************************************************************/
function showdialog(DialogTitle,DialogContent){
   var $dialog = $("#Mydialog");
   $dialog.find("#dialogTitle").html(DialogTitle);
   $dialog.find("#dialogContent").html(DialogContent);
   $dialog.show();
   $dialog.find(".weui_btn_dialog").one("click", function(){
        $dialog.hide();
   });
}


  
function sendData(cmd,body){
	var deviceId=C_DEVICEID;
	mlog("向"+deviceId+"发送..."+cmd);
	if(cmd.length <= 0){
		clog();
		var bytes=parseToBytes(body);
		mlog("发送的cmd数据-->"+pHex(bytes));
		
		WeixinJSBridge.invoke('sendDataToWXDevice', {
			"deviceId":C_DEVICEID, //deviceId, 
			"base64Data":bytes_array_to_base64(bytes)
			}, function(res){
			 
             $("#deviceStatus").val("数据发送成功");
             
		});
	}else{
		clog();
		var data=new DataPacket(new Head(cmd,seqCount++),body);
		mlog("发送的Data数据-->"+pHex(data.toBytes()));
		WeixinJSBridge.invoke('sendDataToWXDevice', {
			"deviceId":C_DEVICEID,  //deviceId, 
			"base64Data":bytes_array_to_base64(data.toBytes())
			}, function(res){
			
		});
	}
}


/** 微信JS库 */
function loadXMLDoc()
  {
    var xmlhttp;
    var url = window.location.href;
    if (window.XMLHttpRequest){
      xmlhttp=new XMLHttpRequest();
    }else{
      xmlhttp=new ActiveXObject("Microsoft.XMLHTTP");
    }
    xmlhttp.onreadystatechange=function(){
      if (xmlhttp.readyState==4 && xmlhttp.status==200)
      {
        var tt = eval("("+xmlhttp.responseText+")");
              
        alert(tt.appid);
        //alert(tt.timestamp); 
        //alert(tt.nonceStr); 
        //alert(tt.signature); 
        
        alert(location.href.split('#')[0]);
                 
		 wx.config({
		 	  beta: true,
		      debug: true,
		      appId: tt.appid, //'wx1704c363451ba04b',
		      timestamp: tt.timestamp,
		      nonceStr: tt.nonceStr,
		      signature: tt.signature,
		      jsApiList: [
		        'openWXDeviceLib',
		        'closeWXDeviceLib',
		        'getWXDeviceInfos',
		        'getWXDeviceBindTicket',
		        'getWXDeviceUnbindTicket',
		        'startScanWXDevice',
		        'stopScanWXDevice',
		        'connectWXDevice',
		        'disconnectWXDevice',
		        'sendDataToWXDevice',
		        'onWXDeviceBindStateChange',
		        'onWXDeviceStateChange',
		        'onScanWXDeviceResult',
		        'onReceiveDataFromWXDevice',
		        'onWXDeviceBluetoothStateChange',
		      ]
		  });
		
      }
    };
    xmlhttp.open("POST","/?What=1001",true);
    xmlhttp.setRequestHeader("Content-type","application/x-www-form-urlencoded");
    xmlhttp.send("url="+url);
  }



$(document).ready(function(){
	
 loadXMLDoc();
 
 /*
 //1. 打开微信设备 
 my_openWXDeviceLib();
 //2. 安装设备事件
 my_installwxEvents();
 //2.1安装状态改变事件
 my_onWXDeviceStateChange(); 
 //3. 安装接收到数据事件
 my_onReceiveDataFromWXDevice();
 //4. 刷新设备信息
 my_getWXDeviceInfos();
 */

  $("#CallGetWXrefresh").on("click",function(e){  
    //showdialog();
    
     //1. 打开微信设备 
     my_openWXDeviceLib();
     
     //2. 安装设备事件
     my_installwxEvents();
     
     //2.1安装状态改变事件
     my_onWXDeviceStateChange(); 
     
     //3. 安装接收到数据事件
     my_onReceiveDataFromWXDevice();
     
     //4. 刷新设备信息
     my_getWXDeviceInfos();
     
     
      
  });

  $("#CallAddValue").on("click",function(e){
     //判断是否有输入数据
     var x1=$("#addMoney").val();
     //alert("A" + x1 + "B"+ x1.length);
     if(x1.length==0){
        showdialog("出错啦","充值金额不合法,请输入有效金额");
        return;
     }
     if(parseInt(x1)==0){
        showdialog("出错啦","充值金额不能是0,请输入有效金额");
        return;
     }
     
	 var Bytes=AddValue($("#addMoney").val());
     var x=senddataBytes(Bytes,C_DEVICEID);    
     if(x===0){$("#lbInfo").html('x.电卡充值命令完成')}
     else {$("#lbInfo").html('x.电卡充值命令失败')};
  });
  
  //******************************************

  $("#CallGetBalance").on("click",function(e){
	 var Bytes=CheckBalance();
     var x=senddataBytes(Bytes,C_DEVICEID);
     if(x===0){$("#lbInfo").html('x.余额查询完成')}
     else {$("#lbInfo").html('x.余额查询失败')};
     
    // $("#CallAddValue").attr({"disabled":true});
    // $("#CallAddValue").removeClass('weui_btn weui_btn_primary');//删除样式,样式名为className
    // $("#CallAddValue").addClass('weui_btn weui_btn_disabled weui_btn_primary');//添加样式,样式名为className
     
     
  });


});

wx.error(function (res) {
  alert(res.errMsg);
});

注意:loadXMLDoc();方法的四个参数需要读者替换为自己的。

3,data_object.js文件示例代码

/**
 * 常用的指令 V型知识库 www.vxzsk.com
 */
var CMDID = {
	BCHAT_FAN_STATE : 0x2020,			// 读取风扇状态
	BCHAT_FAN_POWER : 0x2021,			// 开关风扇
	BCHAT_MOTOR_STATE : 0x2030,			// 读取马达状态
	BCHAT_MOTOR_POWER : 0x2031,			// 控制马达开关及震动强度
	BCHAT_TEMP_HUMI_READ : 0x2040,		// 读取当前温湿度
	BCHAT_TEMP_HUMI_STATE : 0x2041,		// 读取当前温湿度自动更新状态
	BCHAT_TEMP_HUMI_AUTO : 0x2042,		// BChat 自动更新温湿度功能开关
	BCHAT_REQ_UART : 0x2050,			// 微信端向 bChat 发送 Uart 数据
	BCHAT_CONFIG_UART : 0x2051,			// 设置 uart 的波特率,停止位等
	BCHAT_GET_UART_CONF : 0x2052,		// 获取 uart 的配置信息
	BCHAT_LAMP_POWER_OFF : 0x2060,		// 关灯
	BCHAT_LAMP_TEMPERATURE : 0x2061,	// 控制色温
	BCHAT_LAMP_COLOR : 0x2062,			// 调节灯的颜色
	BCHAT_LAMP_COLOR_BLINK : 0x2063,	// 控制灯闪烁
	BCHAT_SET_SEND_TYPE : 0x2070,		// 更改 bChat 发送数据的方向
	BCHAT_GET_SEND_TYPE : 0x2071,		// 获取 bChat 发送数据的方向
	BCHAT_BEGIN_WEIGH : 0x20a1,			// 开始称重
	BCHAT_CALIBRATE_BALANCE : 0x20a0,	// 调整称重
}

/**
 * 包头的对象
 * magic=0xFECF;
 * varsion=0x0001;
 * cmdId
 * seq   命令序列:可以每次递增1
 * errorCode  0:成功,1,失败
 */
function Head(cmdId, seq) {
	this.magic = 0xFECF;
	this.version = 0x0001;
	this.length = 0x000C;
	this.cmdId = cmdId;
	this.seq = seq;
	this.errorCode = 0x0000;
	this.toBytes=function(){
		var bytes = new Array();
		var index = 0;
		for (var b in this) {
			bytes[index++] = ((this[b] >> 8) & 0xFF);
			bytes[index++] = (this[b] & 0xFF);
			if(index==12)break;
		}
		return bytes;
	}
}

/**
 * 包的对象 head为自定义的头部结构体,其中每一个变量都是,byte数组(0x0000) body为字节数组(0x00)
 */
function DataPacket(head, body) {
	this.length=head.length+body.length;
	this.head = head;
	this.body = body;
	this.head.length+=this.body.length;
	this.toBytes = function() {		
		var bytes=this.head.toBytes();
		return bytes.concat(this.body);
	}
	this.fromBytes=function(bytes){
		var index=0;
		for(var t in this.head){
			this.head[t]=(bytes[index++]<<8)+bytes[index++];
			if(index==12)break;
		}
		this.body=[];
		for(var i=0;index<bytes.length;i++,index++){
			this.body[i]=bytes[index];
		}
	}
}

4,weui.css文件示例代码请读者http://www.vxzsk.com/60.html 下载。下载按钮在文章底部。

5,jquery.min.js文件示例代码读者可引用网络地址文件或者去jquery官方网站下载。

此文章本站原创,地址 http://www.vxzsk.com/174.html   转载请注明出处!谢谢!

感觉本站内容不错,读后有收获?小额赞助,鼓励网站分享出更好的教程