前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >微信硬件平台对接--蓝牙

微信硬件平台对接--蓝牙

作者头像
小帅丶
发布2018-02-08 10:27:36
4.2K0
发布2018-02-08 10:27:36
举报
文章被收录于专栏:XAI

http://www.vxzsk.com/142.html这个网站的教程相当详细,本文只是自己测试总结一些相关内容。

  • 平台接入流程

http://iot.weixin.qq.com/wiki/new/index.html?page=3-1  官网有详细截图说的哦。官网的看不明白只能找客服人员了。

  • 设备授权

调用 设备授权新接口 ,获取deviceid和二维码,然后利用获取到的deviceid更新设备属性(如mac地址,connect_protocol等)。

获取到的二维码即为一个硬件一个,设备厂商利用二维码生成器把获取到的二维码串生成为二维码,用户扫描该二维码后,关注厂商公众号,即可绑定设备。

注意:设备授权时必须填上product_id。

  • 获取设备deviceid和二维码URL

 使用的是新接口不需要厂商提供deviceid

http://iot.weixin.qq.com/wiki/document-2_11.html官网的接口介绍请仔细自行查看

接口需要产品ID在公众号平台查看

接下来就是用调用接口生成deviceid 和二维码 url

  1. Java版本的方法
代码语言:js
复制
/**
	 * 微信蓝牙授权新接口
	 */
	public final static String DeviceUrl_new = "https://api.weixin.qq.com/device/getqrcode?access_token=ACCESS_TOKEN&product_id=PRODUCT_ID";

	public static String getDeviceNew(String appid, String appsecret,String productid){
		AccessToken token = new AccessToken();
		token = WeixinUtil.getAccessToken(appid, appsecret);
		String requestUrl = DeviceUrl_new.replace("ACCESS_TOKEN",token.getToken()).replace("PRODUCT_ID", productid);
		JSONObject jsonObject =WeixinUtil.httpRequest(requestUrl, "GET",null);
		if(jsonObject.getString("deviceid")!=null){
			System.out.println(jsonObject.toString());
		}else{
			System.out.println("错误信息"+jsonObject.getString("errcode") +"\n "+jsonObject.getString("errmsg"));
			log.error("error");
		}
		return jsonObject.toString();

	}

2. 获取AccessToken的接口

代码语言:js
复制
/**
	 * 微信蓝牙授权新接口
	 */
	public final static String DeviceUrl_new = "https://api.weixin.qq.com/device/getqrcode?access_token=ACCESS_TOKEN&product_id=PRODUCT_ID";

	public static String getDeviceNew(String appid, String appsecret,String productid){
		AccessToken token = new AccessToken();
		token = WeixinUtil.getAccessToken(appid, appsecret);
		String requestUrl = DeviceUrl_new.replace("ACCESS_TOKEN",token.getToken()).replace("PRODUCT_ID", productid);
		JSONObject jsonObject =WeixinUtil.httpRequest(requestUrl, "GET",null);
		if(jsonObject.getString("deviceid")!=null){
			System.out.println(jsonObject.toString());
		}else{
			System.out.println("错误信息"+jsonObject.getString("errcode") +"\n "+jsonObject.getString("errmsg"));
			log.error("error");
		}
		return jsonObject.toString();

	}

3. 正确返回的JSON数据中包含了deviceid 和 二维码URL(qrticket)

代码语言:js
复制
 {resp_msg:{"ret_code":0," error_info":"ok"},
"deviceid":"gh_d50b0b739699_8888888888888888",
"qrticket":"http://we.qq.com/d/AQDZUo2O9Mu6Bt9__kwMIiMCHiSTzrXqPc1npqXX"}
  1. 通过百度搜索相关生成二维码工具生成
  • 对蓝牙设备授权
  1. Java版本对蓝牙设备授权绑定deviceid
代码语言:js
复制
/**
	 * deviceid更新到设备上
	 */
	public final static String DeviceUrl = "https://api.weixin.qq.com/device/authorize_device?access_token=ACCESS_TOKEN";
	public  static String getDevice(String appid, String appsecret,String devices){
		AccessToken token = new AccessToken();
		token = WeixinUtil.getAccessToken(appid, appsecret);
		String requestUrl = DeviceUrl.replace("ACCESS_TOKEN",token.getToken());
		JSONObject jsonObject =WeixinUtil.httpRequest(requestUrl, "POST", devices);
		if(jsonObject.getString("errcode").equals("0")){
		}else{
			System.out.println("错误信息"+jsonObject.getString("errcode") +"\n "+jsonObject.getString("errmsg"));
			log.error("error");
		}
		return jsonObject.toString();

	}

 2. 对接口要求的JSON格式进行javabean封装

代码语言:js
复制
1.Bluetooth 
public class Bluetooth implements Serializable{
	private String device_num;// 	设备id的个数 	
	private List<DeviceList> device_list; //设备id的列表,json的array格式,其size必须等于device_num
	private String op_type;// 	请求操作的类型,限定取值为:0:设备授权(缺省值为0) 1:设备更新(更新已授权设备的各属性值) 
}
2.DeviceList 
public class DeviceList {
    private String id; //设备的deviceid 
    private String mac; // 	设备的mac地址 格式采用16进制串的方式(长度为12字节)
    private String connect_protocol; // android classic bluetooth – 1  ios classic bluetooth – 2 ble – 3 wifi -- 4 
    private String auth_key; // auth及通信的加密key,第三方需要将key烧制在设备上(128bit),格式采用16进制串的方式(长度为32字节),不需要0X前缀,如: 1234567890ABCDEF1234567890ABCDEF 
    private String close_strategy; //断开策略,目前支持: 1:退出公众号页面时即断开连接 2:退出公众号之后保持连接不断开 
    private String conn_strategy; //连接策略,32位整型,按bit位置位,目前仅第1bit和第3bit位有效(bit置0为无效,1为有效;第2bit已被废弃),且bit位可以按或置位(如1|4=5),各bit置位含义说明如下:
//    1:(第1bit置位)在公众号对话页面,不停的尝试连接设备 
//    4:(第3bit置位)处于非公众号页面(如主界面等),微信自动连接。当用户切换微信到前台时,可能尝试去连接设备,连上后一定时间会断开 
    private String crypt_method; //auth加密方法,目前支持两种取值: 0:不加密 1:AES加密(CBC模式,PKCS7填充方式)
    private String auth_ver; // 	auth version,设备和微信进行auth时,会根据该版本号来确认auth buf和auth key的格式(各version对应的auth buf及key的具体格式可以参看“客户端蓝牙外设协议”),该字段目前支持取值: 0:不加密的version 1:version 1 
    private String manu_mac_pos; // 	表示mac地址在厂商广播manufature data里含有mac地址的偏移,取值如下: -1:在尾部、 -2:表示不包含mac地址 其他:非法偏移 
    private String ser_mac_pos; //表示mac地址在厂商serial number里含有mac地址的偏移,取值如下: -1:表示在尾部 -2:表示不包含mac地址 其他:非法偏移 
    private String ble_simple_protocol; //精简协议类型,取值如下:计步设备精简协议:1 (若该字段填1,connect_protocol 必须包括3。非精简协议设备切勿填写该字段)

set/get省略

3. 返回的数据JSON

代码语言:js
复制
2.deviceid绑定到设备上
		Bluetooth bluetooth = new Bluetooth();
		bluetooth.setDevice_num("1");
		bluetooth.setOp_type("1");
		List<DeviceList> list = new ArrayList<DeviceList>();
		DeviceList deviceList = new DeviceList();
		deviceList.setId("gh_d50b0b739699_88888888888888");
		deviceList.setMac("MAC地址 就是蓝牙设备的地址");
		deviceList.setConnect_protocol("3");
		deviceList.setAuth_key("");
		deviceList.setClose_strategy("1");
		deviceList.setConn_strategy("1");
		deviceList.setCrypt_method("0");
		deviceList.setAuth_ver("0");
		deviceList.setManu_mac_pos("-1");
		deviceList.setSer_mac_pos("-2");
		deviceList.setBle_simple_protocol("0");
		list.add(deviceList);
		bluetooth.setDevice_list(list);
		JSONObject jsonObject = new JSONObject();
		JSONObject object = JSONObject.fromObject(bluetooth);
		JSONArray object2 = object.getJSONArray("device_list");
		String device = jsonObject.fromObject(bluetooth).toString();
		String str  = WeixinUtil.getDevice(Constants.appId, Constants.appSecret, device);
		
[{"base_info":{
"device_type":"gh_d9999999999",
"device_id":"gh_d50b0b739699_88888888888"},
"errmsg":"ok",
"errcode":0}]}
  • 通过微信扫一扫进行绑定 第一次扫描会显示绑定设备

    1.点击绑定并进入公众号 后台会收到相关的事件  博主没有做处理只是一个简单的获取

    2.在公众号里面会显示链接状态 显示已连接一个设备

    3.写个H5 通过jsapi获取相关事件 推送到服务器 进行处理哦(只做了一部分)

  • 页面的代码
代码语言:java
复制
<%@page language="java" contentType="text/html; charset=UTF-8"%>    
    <%
String path = request.getContextPath();
String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";
session.setAttribute("basePath",basePath);
%>
    <!DOCTYPE html>    
    <html>    
    <head>    
    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">    
    <meta http-equiv="X-UA-Compatible" content="IE=edge">    
    <meta name="viewport"    
        content="width=device-width,initial-scale=1.0,maximum-scale=1.0,user-scalable=0">    
    <meta name="apple-mobile-web-app-capable" content="yes">    
    <meta name="apple-mobile-web-app-status-bar-style" content="black">    
    <meta name="format-detection" content="telephone=no">    
    <title>测试蓝牙</title>    
    <link rel="stylesheet" href="css/jquery.mobile-1.4.5.css">
    <script src="js/jquery-1.8.3.min.js"></script>    
    <script src="http://res.wx.qq.com/open/js/jweixin-1.0.0.js"></script>    
    <style type="text/css">    
    .wdbll4 {    
        margin-top: 15px;    
    }    
        
    .grxx_top_biaoge td {    
        text-align: center;    
    }    
    </style>    
    </head>    
    <body id="activity-detail" class="zh_CN ">  
     <input id="appId"  type="hidden" value="${sign.appId }"/>
	<input id="nonceStr" type="hidden" value="${sign.nonceStr }"/>
	<input id="timestamp" type="hidden" value="${sign.timestamp }"/>
	<input id="signature" type="hidden" value="${sign.signature }"/>  
        <div class="wdbll4" align="center"    
            style="padding-left: 10px; padding-right: 10px;">    
            <div style="width: 95%; margin: 0 auto; text-align: center" id="scan">    
                <div class='aui-btn aui-btn-info aui-btn-block' onclick="scan();"    
                    id="startScanWXDevice">搜索蓝牙</div>    
            </div>    
        </div>    
        <div class="wdbll4" align="center"    
            style="padding-left: 10px; padding-right: 10px;">    
            <div style="width: 95%; margin: 0 auto; text-align: center" id="scan">    
                <div class='aui-btn aui-btn-info aui-btn-block' onclick="stopSacn();"    
                    id="stopScanWXDevice">停止搜索</div>    
            </div>    
        </div>    
        <div class="wdbll4" align="center"    
            style="padding-left: 10px; padding-right: 10px;">    
            <div style="width: 95%; margin: 0 auto; text-align: center" id="scan">    
                <div class='aui-btn aui-btn-info aui-btn-block' onclick="getInfo()">获取设备信息</div>    
            </div>    
        </div>    
        <div class="wdbll4" align="center"    
            style="padding-left: 10px; padding-right: 10px;">    
            <div style="width: 95%; margin: 0 auto; text-align: center" id="scan">    
                <div class='aui-btn aui-btn-info aui-btn-block' onclick="bleConn()">连接蓝牙</div>    
            </div>    
        </div>    
        <div class="wdbll4" align="center"    
            style="padding-left: 10px; padding-right: 10px;">    
            <div style="width: 95%; margin: 0 auto; text-align: center" id="scan">    
                <div class='aui-btn aui-btn-info aui-btn-block' onclick="sendData()">发送数据</div>    
            </div>    
        </div>    
        <input type="text" id="sbmacid">
        <div id="initBle"></div>    
    </body>    
    <script type="text/javascript">    
        function BleManage() {    
        };    
        //在它的原型上添加方法      
        BleManage.prototype = {    
            //搜索蓝牙      
            bleInit_sAcn : function() {    
                wx.invoke('startScanWXDevice', {    
                    //  'connType' : 'blue',      
                    'btVersion' : 'ble'    
                }, function(res) {    
                    console.log('开始扫描设备:', res);    
                    $("#initBle").append("<p>开始扫描设备:" + res.err_msg + "</p>");    
                });    
            },    
            //关不搜索蓝牙      
            bleInit_stopSacn : function() {    
                wx.invoke('stopScanWXDevice', {    
                    'connType' : 'blue'    
                }, function(res) {    
                    $("#initBle").append("<p>停止扫描设备:" + res.err_msg + "</p>");    
                    console.log('停止扫描设备:', res);    
                    //alert(res.err_msg);        
                });    
            },    
            //获取设备信息      
            bleInit_getDev_Info : function() {    
                wx.invoke('getWXDeviceInfos', {    
                    'connType' : 'ble'    
                }, function(res) {    
                    alert(JSON.stringify(res))    
                });    
            },    
            //连接蓝牙      
            bleInit_connBle : function() {     
                var id = $("#sbmacid").val();
                wx.invoke('connectWXDevice', {    
                    'deviceId' : 'gh_d50b0b739699_87ba0a0dd8ebb9d7',    
                    'connType' : 'ble'    
                }, function(res) {    
                    alert(JSON.stringify(res))    
                });    
            },    
            //发送数据      
            bleInit_sendData : function() {    
                wx    
                        .invoke(    
                                'sendDataToWXDevice',    
                                {    
                                    'deviceId' : 'gh_d50b0b739699_452d50b87a2121c1',    
                                    'connType' : 'ble',    
                                    'base64Data' : 'MDAwMEZGRjItMDAwMC0xMDAwLTgwMDAtMDA4MDVGOUIzNEZC'    
                                }, function(res) {    
                                    alert(JSON.stringify(res))    
                                });    
            },    
            //初始化微信配置      
            bleInit_callback_ : function() {    
                //刚刚开测试 建议这4个值 直接在页面上写死      
                //动态获取签名的时候才建议 使用下面 ready里面的ajax      
                /*  
                var appId = data.appId;    
                var timestamp = data.timestamp;    
                var nonceStr = data.nonceStr;    
                var signature = data.signature;  6eee7ee157ea0fbe3bb92e11e12357c696933b9e  
                 */    
                 var appId=$("#appId").val();
         		var nonceStr=$("#nonceStr").val();
         		var timestamp=$("#timestamp").val();
         		var signature=$("#signature").val();
                wx.config({    
                    beta : true, //坑:这个很重要,必须配置这个为true,才能调用微信的硬件API    
                    debug : true, //是否开启调试模式,会自动弹一些消息框显示微信返回的数据    
                    appId: appId,  			//openid
  			      timestamp: timestamp,		//时间戳
  			      nonceStr: nonceStr,		//随机串
  			      signature: signature,	 	//签名  
                    jsApiList : [ //需要调用的接口,都得在这里面写一遍        
                    "openWXDeviceLib",//初始化设备库(只支持蓝牙设备)        
                    "closeWXDeviceLib",//关闭设备库(只支持蓝牙设备)        
                    "getWXDeviceInfos",//获取设备信息(获取当前用户已绑定的蓝牙设备列表)        
                    "sendDataToWXDevice",//发送数据给设备        
                    "startScanWXDevice",//扫描设备(获取周围所有的设备列表,无论绑定还是未被绑定的设备都会扫描到)        
                    "stopScanWXDevice",//停止扫描设备        
                    "connectWXDevice",//连接设备        
                    "disconnectWXDevice",//断开设备连接        
                    "getWXDeviceTicket",//获取操作凭证        
        
                    //下面是监听事件:        
                    "onWXDeviceBindStateChange",//微信客户端设备绑定状态被改变时触发此事件        
                    "onWXDeviceStateChange",//监听连接状态,可以监听连接中、连接上、连接断开        
                    "onReceiveDataFromWXDevice",//接收到来自设备的数据时触发        
                    "onScanWXDeviceResult",//扫描到某个设备时触发        
                    "onWXDeviceBluetoothStateChange",//手机蓝牙打开或关闭时触发        
                    ]    
                });    
                wx.ready(function() {    
                    wx.invoke('openWXDeviceLib', {    
                    	'brandUserName':'gh_d50b0b739699',
                    	'connType':'blue'
                    // 'brandUserName' : '',    
                    // 'connType':'blue'    
                    }, function(res) {    
                        $("#initBle").append("<p>初始化设备库:" + res.err_msg + "</p>");    
                        if (res.bluetoothState == "off") {    
                            alert("请先开启手机蓝牙");    
                            $("#initBle").append("<p>请先开启手机蓝牙</p>");    
        
                        }    
                    });    
                    wx.invoke('getWXDeviceInfos', {    
                        'connType' : 'blue'    
                    }, function(res) {    
                        $("#initBle").append("<p>获取我的设备:" + res.err_msg + "</p>");    
                    });    
        
                    wx.on('onScanWXDeviceResult', function(res) {    
                        var ret_ = res.devices;    
                        alert(ret_);
                        for (var i = 0; i < ret_.length; i++) {    
                            var macid = JSON.stringify(res.devices[i].deviceId)    
                                    .replace(/\"/g, "");    
                            //给扫描到的设备添加点击事件    
                            $("#sbmacid").val(macid);
                            $("#initBle").append(    
                                    "<button onclick=\"bindBle('" + macid    
                                            + "')\">扫描到设备:" + macid + "</button>");    
                        }    
                    });    
                    //手机蓝牙状态改变时触发 (这是监听事件的调用方法,注意,监听事件都没有参数)        
                    wx.on('onWXDeviceBluetoothStateChange', function(res) {    
                        //把res输出来看吧        
                        $("#initBle").append(    
                                "<p>蓝牙状态变更:" + JSON.stringify(res) + "</p>");    
                    });    
                    //设备绑定状态改变事件(解绑成功,绑定成功的瞬间,会触发)        
                    wx.on('onWXDeviceBindStateChange', function(res) {    
        
                        $("#initBle").append(    
                                "<p>绑定状态变更:" + JSON.stringify(res) + "</p>");    
                    });    
                    //设备连接状态改变        
                    wx.on('onWXDeviceStateChange', function(res) {    
                        //有3个状态:connecting连接中,connected已连接,unconnected未连接        
                        //每当手机和设备之间的状态改变的瞬间,会触发一次        
        
                        $("#initBle").append("<p>设备连接状态:" + res.state + "</p>");    
                    });    
                    //接收到设备传来的数据        
                    wx.on('onReceiveDataFromWXDevice', function(res) {    
                        $("#initBle").append(    
                                "<p>收到设备数据:" + JSON.stringify(res) + "</p>");    
                    });    
                    wx.error(function(res) {    
                        alert("wx.error错误:" + JSON.stringify(res));    
                        //如果初始化出错了会调用此方法,没什么特别要注意的        
                    });    
        
                });    
            }    
        }    
        //绑定设备    
        function bindBle(str) {    
            alert('<%=basePath%>');
            var openid = "o2VKNjts--hGjXMDV2HoRcCEpXTc";
                        //强制绑定 传值 后台获取的openid  和当前点击的设备ID    
                        $.ajax({    
                            type : "get",    
                            url : "<%=basePath%>/servlet/bindServlet",    
                            data : {     
                                "deviceId" : str,    
                                "openid" : openid    
                            },    
                            dataType : "json",    
                            success : function(data) {    
                                alert(JSON.stringify(data))    
                                var s = data.errmsg;    
                                if (s == "ok") {    
                                    alert("bind   succ");    
                                }    
                            },    
                            error : function(data) {   
                            	 alert(JSON.stringify(data))    
                                 var s = data.errmsg;     
                                	alert(s);
                            }    
            });    
        }    
        
        var bleManage = null;    
        //进来动态加载签名      
        $(document).ready(function() {    
            bleManage = new BleManage();    
            bleManage.bleInit_callback_();    
            /*  
            $.ajax({    
                type : "post",    
                url : "xxx.com",    
                data : {},    
                dataType : "json",    
                success : function(data) {    
                    //调用之前先打印一下传回来的4个值 是否跟你之前写死的 能成功的值是一样的    
                    bleManage.bleInit_callback_(data);    
                }    
            });  
             */    
        });    
        
        function scan() {    
            bleManage.bleInit_sAcn();    
        }    
        function stopSacn() {    
            bleManage.bleInit_stopSacn();    
        }    
        function getInfo() {    
            bleManage.bleInit_getDev_Info();    
        }    
        function bleConn() {    
            bleManage.bleInit_connBle();    
        }    
        function sendData() {    
            bleManage.bleInit_sendData();    
        }    
        var base64EncodeChars = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";    
        function base64encode(str) {    
            var out, i, len;    
            var c1, c2, c3;    
            len = str.length;    
            i = 0;    
            out = "";    
            while (i < len) {    
                c1 = str.charCodeAt(i++) & 0xff;    
                if (i == len) {    
                    out += base64EncodeChars.charAt(c1 >> 2);    
                    out += base64EncodeChars.charAt((c1 & 0x3) << 4);    
                    out += "==";    
                    break;    
                }    
                c2 = str.charCodeAt(i++);    
                if (i == len) {    
                    out += base64EncodeChars.charAt(c1 >> 2);    
                    out += base64EncodeChars.charAt(((c1 & 0x3) << 4)    
                            | ((c2 & 0xF0) >> 4));    
                    out += base64EncodeChars.charAt((c2 & 0xF) << 2);    
                    out += "=";    
                    break;    
                }    
                c3 = str.charCodeAt(i++);    
                out += base64EncodeChars.charAt(c1 >> 2);    
                out += base64EncodeChars.charAt(((c1 & 0x3) << 4)    
                        | ((c2 & 0xF0) >> 4));    
                out += base64EncodeChars.charAt(((c2 & 0xF) << 2)    
                        | ((c3 & 0xC0) >> 6));    
                out += base64EncodeChars.charAt(c3 & 0x3F);    
            }    
            return out;    
        }    
    </script>    
    </html>    
  • servlet跳转到页面的代码
代码语言:js
复制
public class BlueServlet extends HttpServlet {

	public void doGet(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {
		WeixinUtil util = new WeixinUtil();
		JsapiTicket jt = util.getJsapiTicket(Constants.appId,Constants.appSecret);
		String ticket = jt.getTicket();
		StringBuffer url = request.getRequestURL();
		System.out.println("jssdk=" + ticket);
		System.out.println("获取的路径==" + url);
		Map<String, String> t = Sign.sign(ticket, url.toString());
		request.setAttribute("sign", t);
		request.getRequestDispatcher("/blue.jsp").forward(request,
				response);
	}

	public void doPost(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {
		doGet(request, response);
	}

}

是否打开蓝牙都会有提示  开始扫描就会扫描到没有链接但是属于当前公众号的设备 这块就可以进行扫描到的设备进行读取信息 处理信息了。这块博主还在测试中。根据以上内容 对一个蓝牙设备连接绑定是没有问题的。具体有官网文档仔细说明。建议相关术语查询官网文档。有大神也可以指导博主的问题哦。

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • http://www.vxzsk.com/142.html这个网站的教程相当详细,本文只是自己测试总结一些相关内容。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档