精华内容
下载资源
问答
  • 微信小程序控制硬件第1篇 】 全网首发,借助 emq 消息服务器带你如何搭建微信小程序的mqtt服务器,轻松控制智能硬件! 【微信小程序控制硬件第2篇 】 开始微信小程序之旅,导入小程序Mqtt客户端源码,实现简单的...
  • 微信小程序蓝牙 API教程完整版

    千次阅读 2020-10-15 22:54:54
    微信小程序蓝牙 API教程完整版 1. 首先是要初始化蓝牙: openBluetoothAdapter() if (wx.openBluetoothAdapter) { wx.openBluetoothAdapter({ success: function(res) { / 获取本机的蓝牙状态 / setTimeout(() =&...

    微信小程序蓝牙 API教程完整版

    1. 首先是要初始化蓝牙: openBluetoothAdapter()

    if (wx.openBluetoothAdapter) {
    	wx.openBluetoothAdapter({
    	success: function(res) {
    	/ 获取本机的蓝牙状态 /
    	setTimeout(() => {
    	getBluetoothAdapterState()	
    }, 1000)	
    },
    	fail: function(err) {
    	// 初始化失败	
    }	
    })	
    } else {
    	
    }
    

    2. 检测本机蓝牙是否可用:

     初始化蓝牙成功之后回调里调用
    
    getBluetoothAdapterState() {
    	var that = this;
    	that.toastTitle = '检查蓝牙状态'
    	wx.getBluetoothAdapterState({
    	success: function(res) {
    	startBluetoothDevicesDiscovery()	
    },
    	fail(res) {
    	console.log(res)	
    }	
    })	
    }
    

    3. 开始搜索蓝牙设备:

    startBluetoothDevicesDiscovery() {
    	var that = this;
    	setTimeout(() => {
    	wx.startBluetoothDevicesDiscovery({
    	success: function(res) {
    	/ 获取蓝牙设备列表 /
    	that.getBluetoothDevices()	
    },
    	fail(res) {
    	
    }	
    })	
    }, 1000)	
    }
    

    4. 获取搜索到的蓝牙设备列表

    / that.deviceName 是获取到的蓝牙设备的名称, 因为蓝牙设备在安卓和苹果手机上搜到的蓝牙地址显示是不一样的, 所以根据设备名称匹配蓝牙 /
    getBluetoothDevices() {
    	var that = this;
    	setTimeout(() => {
    	wx.getBluetoothDevices({
    	services: [],
    	allowDuplicatesKey: false,
    	interval: 0,
    	success: function(res) {
    	if (res.devices.length> 0) {
    	if (JSON.stringify(res.devices).indexOf(that.deviceName) !== -1) {
    	for (let i = 0; i <res.devices.length; i++) {
    	if (that.deviceName === res.devices[i].name) {
    	/ 根据指定的蓝牙设备名称匹配到 deviceId /
    	that.deviceId = that.devices[i].deviceId;
    	setTimeout(() => {
    	that.connectTO();	
    }, 2000);	
    };	
    };	
    } else {
    	
    }	
    } else {
    	
    }	
    },
    	fail(res) {
    	console.log(res, '获取蓝牙设备列表失败 =====')	
    }	
    })	
    }, 2000)	
    },
    

    5. 连接蓝牙

    匹配到的蓝牙设备 ID 发送连接蓝牙的请求, 连接成功之后 应该断开蓝牙搜索的 API, 然后去获取所连接蓝牙设备的 service 服务

    connectTO() {
    	wx.createBLEConnection({
    	deviceId: deviceId,
    	success: function(res) {
    	that.connectedDeviceId = deviceId;
    	/ 4. 获取连接设备的 service 服务 /
    	that.getBLEDeviceServices();
    	wx.stopBluetoothDevicesDiscovery({
    	success: function(res) {
    	console.log(res, '停止搜索')	
    },
    	fail(res) {
    	
    }	
    })	
    },
    	fail: function(res) {
    	
    }	
    })	
    }
    

    6. 获取蓝牙设备的 service 服务

    获取的 serviceId 有多个要试着连接最终确定哪个是稳定版本的 service 获取服务完后获取设备特征值

    getBLEDeviceServices() {
    	setTimeout(() => {
    	wx.getBLEDeviceServices({
    	deviceId: that.connectedDeviceId,
    	success: function(res) {
    	that.services = res.services
    	/ 获取连接设备的所有特征值 /
    	that.getBLEDeviceCharacteristics()	
    },
    	fail: (res) => {
    	
    }	
    })	
    }, 2000)	
    }
    

    7. 获取蓝牙设备特征值

    获取到的特征值有多个, 最后要用的事能读, 能写, 能监听的那个值的 uuid 作为特征值 id

    getBLEDeviceCharacteristics() {
    	setTimeout(() => {
    	wx.getBLEDeviceCharacteristics({
    	deviceId: connectedDeviceId,
    	serviceId: services[2].uuid,
    	success: function(res) {
    	for (var i = 0; i <res.characteristics.length; i++) {
    	if ((res.characteristics[i].properties.notify || res.characteristics[i].properties.indicate) &&
    	(res.characteristics[i].properties.read && res.characteristics[i].properties.write)) {
    	console.log(res.characteristics[i].uuid, '蓝牙特征值 ==========')
    	/ 获取蓝牙特征值 /
    	that.notifyCharacteristicsId = res.characteristics[i].uuid
    	// 启用低功耗蓝牙设备特征值变化时的 notify 功能
    	that.notifyBLECharacteristicValueChange()	
    }	
    }	
    },
    	fail: function(res) {
    	
    }	
    })	
    }, 1000)	
    }
    

    8. 启动 notify 蓝牙监听功能

    然后使用 wx.onBLECharacteristicValueChange 用来监听蓝牙设备传递数据
    #接收到的数据和发送的数据必须是二进制数据, 页面展示的时候需要进行转换

    notifyBLECharacteristicValueChange() { // 启用低功耗蓝牙设备特征值变化时的 notify 功能
            var that = this;
            console.log('6. 启用低功耗蓝牙设备特征值变化时的 notify 功能')
            wx.notifyBLECharacteristicValueChange({
                state: true,
                deviceId: that.connectedDeviceId,
                serviceId: that.notifyServicweId,
                characteristicId: that.notifyCharacteristicsId,
                complete(res) {
                    /* 用来监听手机蓝牙设备的数据变化 */
                    wx.onBLECharacteristicValueChange(function(res) {
                        /**/
                        that.balanceData += that.buf2string(res.value)
                        that.hexstr += that.receiveData(res.value)
                    })
                },
                fail(res) {
                    console.log(res, '启用低功耗蓝牙设备监听失败')
                    that.measuringTip(res)
                }
            })
        },
        /* 转换成需要的格式 */
         buf2string(buffer) {
                    var arr = Array.prototype.map.call(new Uint8Array(buffer), x => x)
                    return arr.map((char, i) => {
                        return String.fromCharCode(char);
                    }).join('');
        },
          receiveData(buf) {
                    return this.hexCharCodeToStr(this.ab2hex(buf))
          },
          /* 转成二进制 */
           ab2hex (buffer) {
              var hexArr = Array.prototype.map.call(
                  new Uint8Array(buffer), function (bit) {
                      return ('00' + bit.toString(16)).slice(-2)
                  }
              )
              return hexArr.join('')
          },
          /* 转成可展会的文字 */
          hexCharCodeToStr(hexCharCodeStr) {
              var trimedStr = hexCharCodeStr.trim();
              var rawStr = trimedStr.substr(0, 2).toLowerCase() === '0x' ? trimedStr.substr(2) : trimedStr;
              var len = rawStr.length;
              var curCharCode;
              var resultStr = [];
              for (var i = 0; i < len; i = i + 2) {
                  curCharCode = parseInt(rawStr.substr(i, 2), 16);
                  resultStr.push(String.fromCharCode(curCharCode));
              }
              return resultStr.join('');
          },
    

    9. 向蓝牙设备发送数据

    sendData(str) {
    	let that = this;
    	let dataBuffer = new ArrayBuffer(str.length)
    	let dataView = new DataView(dataBuffer)
    	for (var i = 0; i < str.length; i++) {
    	dataView.setUint8(i, str.charAt(i).charCodeAt())	
    }
    	let dataHex = that.ab2hex(dataBuffer);
    	this.writeDatas = that.hexCharCodeToStr(dataHex);
    	wx.writeBLECharacteristicValue({
    	deviceId: that.connectedDeviceId,
    	serviceId: that.notifyServicweId,
    	characteristicId: that.notifyCharacteristicsId,
    	value: dataBuffer,
    	success: function (res) {
    	console.log('发送的数据:' + that.writeDatas)
    	console.log('message 发送成功')	
    },
    	fail: function (res) {
    	
    },
    	complete: function (res) {
    	
    }	
    })	
    },
    

    10.当不需要连接蓝牙了后就要关闭蓝牙, 并关闭蓝牙模块

    // 断开设备连接
    closeConnect() {
    	if (that.connectedDeviceId) {
    	wx.closeBLEConnection({
    	deviceId: that.connectedDeviceId,
    	success: function(res) {
    	that.closeBluetoothAdapter()	
    },
    	fail(res) {
    	
    }	
    })	
    } else {
    	that.closeBluetoothAdapter()	
    }	
    },
    // 关闭蓝牙模块
    closeBluetoothAdapter() {
    	wx.closeBluetoothAdapter({
    	success: function(res) {
    	
    },
    	fail: function(err) {
    	
    }	
    })	
    },
    

    11.蓝牙设备通信流程图

    在这里插入图片描述

    展开全文
  • 微信小程序 蓝牙的实现实例代码 1.简述 蓝牙适配器接口是基础库版本 1.1.0 开始支持。 iOS 微信客户端 6.5.6 版本开始支持,Android 客户端暂不支持 蓝牙总共增加了18个api接口。 2.Api分类 搜索类 连接类 通信...
  • 微信小程序蓝牙API使用指南

    千次阅读 2017-08-22 15:07:47
    目前蓝牙资料极少,但是为了让大家能够迅速的了解新API及可能遇到的问题,本帖将不断聚合跟蓝牙相关的内容;以便大家参考;官方文档地址:https://mp.weixin.qq.com/debug/wxadoc/dev/api/bluetooth.html 基础库版本...

    目前蓝牙资料极少,但是为了让大家能够迅速的了解新API及可能遇到的问题,本帖将不断聚合跟蓝牙相关的内容;以便大家参考;官方文档地址:https://mp.weixin.qq.com/debug/wxadoc/dev/api/bluetooth.html

    基础库版本 1.1.0 开始支持,低版本需做[兼容处理](https://mp.weixin.qq.com/debug/wxadoc/dev/framework/compatibility.html)
    
    iOS 微信客户端 6.5.6 版本开始支持,Android 客户端目前已经支持
    
    由于系统的问题,目前仅在 mac 版的开发工具上支持蓝牙调试
    
    tip: Mac系统可能无法获取advertisData及RSSI,请使用真机调试
    
    tip: 开发者工具和 Android 上获取到的deviceId为设备 MAC 地址,iOS 上则为设备 uuid。因此deviceId不能硬编码到代码中
    
    开发者工具和 Android 上获取到的deviceId为设备 MAC 地址,iOS 上则为设备 uuid。因此deviceId不能硬编码到代码中
    
    tip: 并行调用多次读写接口存在读写失败的可能性。
    
    tip: read接口读取到的信息需要在onBLECharacteristicValueChange方法注册的回调中获取。
    

    相关文章

    微信小程序 蓝牙实现

    微信小程序更新--测试API之蓝牙

    微信小程序实现BLE蓝牙连接

    微信小程序 蓝牙BLE开发实战(附demo)

    经验问答

    跳坑《一百七十六》蓝牙API使用指南

    【蓝牙】开发相关汇总

    【经验总结】小程序有效判断手机蓝牙开/关状态

    小程序蓝牙发送数据问题

    求助微信小程序开发问题之安卓手机无法连接蓝牙打印机

    蓝牙read接口疑问

    小程序蓝牙开发心得和问题

    微信小程序学习用demo:蓝牙测试

    微信小程序 低耗蓝牙接口封装

    问答《六十五》蓝牙写入数据问题,marker iconPath 路径

    展开全文
  • 自从微信小程序提供BLE蓝牙api后,网上随便一搜便是各种称实现了小程序连接ble 的功能的文章,上来就贴代码,贴效果图,对于我们这种没有与硬件开发打过交道的互联网开发者,单单看这些文章与小程序api 离自己真正调...
  • 微信小程序 蓝牙实现

    2021-03-29 21:26:34
    微信小程序 蓝牙的实现实例代码 1.简述 蓝牙适配器接口是基础库版本 1.1.0 开始支持。 iOS 微信客户端 6.5.6 版本开始支持,Android 客户端暂不支持 蓝牙总共增加了18个api接口。 2.Api分类 搜索类 连接类 通信类 3....
  • 在前几天我们发布了一款名叫“我的硬件”的微信小程序,该小程序可通过拖拽控件的方式编辑界面,并支持蓝牙、MQTT等通信方式。用这块小程序可实现零基础制作属于自己的小程序去控制多个硬件。 思来想去觉得应该写几...
  • 接着上一篇来继续测:微信小程序蓝牙API每个测试了一下发现跟以前的写Android的蓝牙调取是一样的,打开流程:先打开蓝牙的适配器,然后确定下本机的蓝牙状态,然后开始搜索蓝牙,搜索完成以后关闭搜索。...
  • 注意:微信小程序蓝牙API与支付宝小程序蓝牙API有略微不同之处,注意闭坑,本文所讲的是自己开发低功耗蓝牙开锁的功能和全流程。所用技术为Taro,具体用法可以去查Taro官网(Taro:...

    【最全】微信支付宝小程序蓝牙API开锁全流程

    注意:微信小程序蓝牙API与支付宝小程序蓝牙API有略微不同之处,注意闭坑,本文所讲的是自己开发低功耗蓝牙开锁的功能和全流程。所用技术为Taro,具体用法可以去查Taro官网(Taro:https://taro-docs.jd.com/taro/docs/README)。 有写的不好的或者意见和建议,请在评论区留言 。

    蓝牙低功耗 (Bluetooth Low Energy, BLE)

    蓝牙低功耗是从蓝牙 4.0 起支持的协议,与经典蓝牙相比,功耗极低、传输速度更快,但传输数据量较小。常用在对续航要求较高且只需小数据量传输的各种智能电子产品中,比如智能穿戴设备、智能家电、传感器等,应用场景广泛。

    支付宝蓝牙与微信小程序蓝牙区别:

    1. 支付宝部分api名字与微信小程序蓝牙api名字有不一样的,具体见下文
    2. 微信小程序搜索蓝牙设备api,结果返回advertisData和serivceData都是ArrayBuffer类型的,需要自己将ArrayBuffer转为16进制,最后在进行解析数据等操作,而支付宝小程序搜索蓝牙api返回的直接是16进制,不需要再次转换,但是需要把16进制转换为能识别的16进制字符串数组才可以进行接下来的数据解析等操作

    支付宝低功耗蓝牙API概览:

    在这里插入图片描述

    支付宝传统蓝牙API概览:

    在这里插入图片描述

    微信低功耗蓝牙API概览:

    在这里插入图片描述


    【重点:如何使用API以及细节】:

    1.【第一步】:需要调用Taro.openBluetoothAdapter(),判断蓝牙是否开启(注意事项⚠️:Taro.openBluetoothAdapter支付宝和微信小程序返回的结果不一样,注意区分判断)

     if (Taro.getEnv() === "ALIPAY") {
          res = await Taro.openBluetoothAdapter();
     } else {
          const { errMsg } = await Taro.openBluetoothAdapter();
          res = errMsg;
     }
    
      //微信小程序蓝牙未打开
     if (Taro.getEnv() === "WEAPP" && res !== "openBluetoothAdapter:ok") {
        // TODO 没有打开蓝牙,需要提示用户打开 
     }
      //支付宝小程序  error: 12, errorMessage: "蓝牙未打开"
     if (Taro.getEnv() === "ALIPAY" && res.error === 12) {
         // TODO 没有打开蓝牙,需要提示用户打开 
     }
    

    2.**【第二步】**开启蓝牙后,需要调用Taro.getLocation()开启地理位置,方便搜索到蓝牙,因android手机不兼容,所以必须要调用定位的方法,以更准确的查到附近的蓝牙设备

     //获取当前的地理位置、速度。当用户离开小程序后,此接口无法调用
     Taro.getLocation({})
            .then(res => {
             //	TODO 通过后端接口获取你需要的设备信息,一般需要uuid,localKey 等等
     })
            .catch(err => {
              console.log("err", err);
     });
    

    3.**【第三步】**通过后端接口获取你需要的设备信息,拿到对应的uuid,localKey,其中,uuid是为了与搜索到的众多的蓝牙设备相匹配

     //TODO 调用接口拿到自己设备的信息
     const { uuid, localKey } = await getBleLocksInfoData(deviceIds);
     const loginKey = localKey.substr(0, 6);
     Taro.setStorageSync("loginKey", loginKey);
     
     //TODO 根据接口返回的uuid进行查找附近的设备并进行匹配
     searchBle(uuid);
    

    4.**【第四步】**开始搜寻附近的蓝牙外围设备。此操作比较耗费系统资源,请在搜索并连接到设备后调用 wx.stopBluetoothDevicesDiscovery 方法停止搜索。 另外,services:要搜索的蓝牙设备主 service 的 uuid 列表。某些蓝牙设备会广播自己的主 service 的 uuid。如果设置此参数,则只搜索广播包有对应 uuid 的主服务的蓝牙设备。建议主要通过该参数过滤掉周边不需要处理的其他蓝牙设备。

    参数介绍:
    在这里插入图片描述

    //因为我们的services是["A201"],所以这里直接参数写为["A201"]来查询
    const data = await Taro.startBluetoothDevicesDiscovery({
          services: ["A201"]
    });
    
    //此处,微信小程序和支付宝小程序api返回的data结果不一样,请注意区分
    if (data.isDiscovering || data) {
    
     //TODO:搜索蓝牙设备,并匹配UUID
     onDiscoveryBLE(uuid)
     
     //另注意:可以多次调用搜索蓝牙,但一定要及时关闭定时器
     //多次调用搜索蓝牙
     this.delayTimer = setInterval(() => {
       this.onDiscoveryBLE(uuid);
     }, 1000);
     
     //关闭定时器
     this.setTimer = setTimeout(() => {
            // 关闭蓝牙
            Taro.stopBluetoothDevicesDiscovery();
            // 清理定时
            clearInterval(this.delayTimer);
      }, 15000);
    }
    

    5.**【第五步】**调用Taro.getBluetoothDevices获取附近蓝牙设备,并进行筛选匹配过滤(要注意微信和支付宝api返回的结果是不一样的,微信需要转为十六进制,支付宝需要转换为十六进制字符串数组)

     // 搜索蓝牙 -- 微信 支付宝搜索蓝牙设备并连接
      onDiscoveryBLE = async uuid => {
        //获取在蓝牙模块生效期间所有已发现的蓝牙设备。包括已经和本机处于连接状态的设备。
        let isALiPay = Taro.getEnv() === "ALIPAY";
        let { devices } = await Taro.getBluetoothDevices();
        let macAddress = "";
        try {
          // 过滤一些设备
          devices = devices.filter(item => item.name && item.name !== "未知设备");
          //这里打印出设备列表,方便查看设备信息
          console.log("devices", devices);
          // 匹配 uuid 找到对应的设备
          if (devices.length) {
            for (const item of devices) {
              let {
                advertisServiceUUIDs,
                serviceData,
                advertisData,
                deviceId
              } = item;
              if (!advertisServiceUUIDs || !serviceData) return;
              if (isALiPay) { //支付宝
              	//TODO hexStringToArray十六进制字符串转十六进制字符串数组(方法见下文)
                serviceData = utils.hexStringToArray(serviceData[advertisServiceUUIDs]);
                advertisData = utils.hexStringToArray(advertisData);
              } else { //微信 
              	//TODO ab2hex ArrayBuffer转十六进制(方法见下文)
                serviceData = utils.ab2hex(serviceData[advertisServiceUUIDs]);
                advertisData = utils.ab2hex(advertisData);
              }
              //TODO 这里需要根据advertisData, serviceData这两个参数解密出uuid,然后与后端接口返回的uuid匹配,
              //为ture就表示是自己的设备
              const uuids = utils.getUuid(advertisData, serviceData);
              if (uuids === uuid) {
                console.log("数据有了:", item);
                macAddress = deviceId;
                Taro.setStorageSync("macAddress", macAddress);
                break;
              }
            }
            if (macAddress) {
            	//TODO 找到自己的设备后,开始建立建立连接(【第六步】)
              connectBle();
            }
          }
        } catch (error) {
        	//TODO 处理失败的逻辑 可给予弹窗提示
        }
      };
    

    支付宝返回结果:
    在这里插入图片描述
    微信返回结果:
    在这里插入图片描述

    6.**【第六步】**在connectBle()这个方法内处理建立连接逻辑,拿到macAddress后,调用Taro.createBLEConnection()进行连接

    //TODO 要注意支付宝和微信的区别
    const deviceId = macAddress;
     
     if (Taro.getEnv() === "ALIPAY") {
            BLEConnection = my.connectBLEDevice
     }else{
            BLEConnection = Taro.createBLEConnection
     }
     
     BLEConnection({ deviceId })
            .then(connect => {
              getBLEDeviceServices(connect,deviceId,resolve)
            })
            .catch(err => {
              console.log("connect error", err);
              //TODO 可以处理连接失败的操作,具体可以重连等
              //思路:先关闭连接,然后再重新初始化蓝牙
              Taro.closeBLEConnection({ deviceId })
                    .then(res => {
                      console.log("res", res);
                      initBleConnect();
               })
                    .catch(error => {
                      console.log("error", error);
                      initBleConnect();
              });
            });
            
    
     const initBleConnect = () => {
          Taro.closeBluetoothAdapter()
            .then(ddd => {
              console.log("ddd", ddd);
              // 一秒钟之后再去开启蓝牙
              setTimeout(() => {
              //初始化蓝牙
                Taro.openBluetoothAdapter()
                  .then(res => {
                    console.log("蓝牙重启", res);
                    const { errMsg } = res;
                    if (errMsg === "openBluetoothAdapter:ok" || res.error !== 12) {
                      console.log("蓝牙重启 -----===========");
                      connectBluttoth(macAddress)
                        .then(connect => resolve(connect))
                        .catch(err => reject(err));
                    } else {
                      reject({ code: 1 });
                    }
                  })
                  .catch(err => {
                    reject({ code: 1 });
                    console.log("重启失败err", err);
                  });
              }, 500);
            })
            .catch(rr => {
              console.log("rr", rr);
            });
        };
    

    7.**【第七步】**在getBLEDeviceServices()处理获取蓝牙低功耗设备所有服务 (service),另外,调用notifyBLECharacteristicValueChange必须先启用notifyBLECharacteristicValueChange 才能监听到设备 characteristicValueChange 事件,所以在页面加载完成后我们需要加载此方法

    const getBLEDeviceServices =(connect,deviceId,resolve)=>{
    	//因为支付宝返回的{},所以在此做了兼容
      if (Number(connect.errCode) === 0 || JSON.stringify(connect) === '{}') {
      	//处理获取蓝牙低功耗设备所有服务 (service)
        Taro.getBLEDeviceServices({ deviceId }).then(({ services }) => {
          console.log(services);
          if (!services.length) {
            console.log("未找到服务列表");
            return;
          }
          if (services.length) {
            const service = services[0];
            // 获取蓝牙低功耗设备某个服务中所有特征 (characteristic)。
            Taro.getBLEDeviceCharacteristics({
              deviceId,
              serviceId: service.uuid || service.serviceId
            }).then(({ characteristics }) => {
              // 获取设备数据
              if (!characteristics.length) {
                console.log("未找到设备特征值");
                return;
              }
              characteristics.forEach(item => {
                if (item.properties.notify) {
       //启用蓝牙低功耗设备特征值变化时的 notify 功能,订阅特征。注意:必须设备的特征支持 notify 或者 indicate 才可以成功调用。
       //另外,必须先启用 wx.notifyBLECharacteristicValueChange 才能监听到设备 characteristicValueChange 事件
                  Taro.notifyBLECharacteristicValueChange({
                    deviceId,
                    serviceId: service.uuid || service.serviceId,
                    characteristicId: item.uuid || item.characteristicId,
                    state: true
                  });
                } else if (item.properties.write) {
                  clearTimeout(connectTimer);
                  resolve({
                    characteristicIdUuid: item.uuid || item.characteristicId,
                    serviceUuid: service.uuid || service.serviceId
                  });
                } else {
                  console.log("该特征值属性: 其他");
                }
              });
            });
          }
        });
      }
    }
    
     import aesjs from "aes-js"; //需要引入aes-js
     
     async componentDidMount() {
        global["events"].on("onPairResult", this.onPairResult, this);
        global["events"].on("openLockClick", this.openLockClick, this);
        global["events"].emit("initLockState", 1);
        //监听低功耗蓝牙设备的特征值变化事件。
        //必须先启用 notifyBLECharacteristicValueChange 接口才能接收到设备推送的 notification。
        Taro.onBLECharacteristicValueChange(res => {
          // 在开锁中才接受数据
          if (this.isOpenLock) {
            const { value } = res;
            let key = ''
            if (Taro.getEnv() === "ALIPAY") {
              key = utils.HexString2Bytes(value)
            } else {
              const str = utils.ab2hex(value).join("");
              key = utils.HexString2Bytes(str);
            }
            console.log('parseDataReceived -- key:' + key);
            //开锁的逻辑,需要解析数据 -- 根据自己的业务和需求进行解析
            parseDataReceived.call(this, key);
          }
        });
        
         //监听低功耗蓝牙连接状态的改变事件。包括开发者主动连接或断开连接,设备丢失,连接异常断开等等
        if (Taro.getEnv() === "ALIPAY") {
          my.onBLEConnectionStateChanged(res => {
           		// TODO 可以处理失败的弹窗提示等
          });
        } else {
          Taro.onBLEConnectionStateChange(res => {
            // 该方法回调中可以用于处理连接意外断开等异常情况
            // TODO 可以处理失败的弹窗提示等
          });
        }
      } 
    

    8.【工具类】 工具类

    /**
     * 字符串转 16 进制
     * @param str 字符串
     */
    function HexString2Bytes(str) {
      var pos = 0;
      var len = str.length;
      if (len % 2 != 0) {
        return null;
      }
      len /= 2;
      var arrBytes = new Array();
      for (var i = 0; i < len; i++) {
        var s = str.substr(pos, 2);
        var v = intToByte(parseInt(s, 16));
        arrBytes.push(v);
        pos += 2;
      }
      return arrBytes;
    }
    
    
    //十六进制字符串转换为数组
    function hexStringToArray(str) {
      var pos = 0;
      var len = str.length;
      if (len % 2 != 0) {
        return null;
      }
      len /= 2;
      var arrBytes = new Array();
      for (var i = 0; i < len; i++) {
        var s = str.substr(pos, 2);
        arrBytes.push(s);
        pos += 2;
      }
      return arrBytes;
    }
    
    
    /**
     * 把 ArrayBuffer 转换成 16 进制内容
     * @param buffer 二进制内容
     */
    const ab2hex = buffer => {
      const arr = [] as any;
      Array.prototype.map.call(new Uint8Array(buffer), function(bit) {
        let item = ("00" + bit.toString(16)).slice(-2);
        arr.push(item);
      });
      return arr;
    };
    
    //通过advertisData, serviceData这两个参数获取uuid,与自己设备的uuid相匹配
    const getUuid = (advertisData, serviceData) => {
      serviceData = serviceData.slice(1, serviceData.length);
      const pid = serviceData.join("");
      const strByte = aesjs.utils.hex.toBytes(pid);
      const md5Val = md5.array(strByte);
    
      const uuidDataArr = advertisData.slice(8, advertisData.length);
      const uuidDataStr = uuidDataArr.join("");
      const encryptUuid = aesjs.utils.hex.toBytes(uuidDataStr);
      const aesCbc = new aesjs.ModeOfOperation.cbc(md5Val, md5Val);
      const decryptedBytes = aesCbc.decrypt(encryptUuid);
      const uuid = aesjs.utils.utf8.fromBytes(decryptedBytes);
      return uuid;
    };
    
    展开全文
  • 微信小程序蓝牙封装

    2021-07-09 11:43:08
    import{ warning, ...//打开蓝牙则是第一次初始化初始化失败继续调用isFirestShow有值则第一次调用 exportfunctionopenBlue(isFirestShow){ returnnewPromise((resolved,rejected)=>{ wx.close...
    import {
      warning,
      loading,
      closeLoading
    } from 'tips'
    const app = getApp()
    // 蓝牙初始化连接步骤
    // 打开蓝牙 则是第一次初始化 初始化失败继续调用 isFirestShow 有值则第一次调用
    export function openBlue(isFirestShow) {
      return new Promise((resolved, rejected) => {
        wx.closeBluetoothAdapter({
          success: function (r) {
            wx.openBluetoothAdapter({ //调用微信小程序api 打开蓝牙适配器接口
              success: function (res) {
                resolved('success')
              },
              fail: function (res) { //如果手机上的蓝牙没有打开,可以提醒用户
                rejected('fail')
                if (isFirestShow) {
                  warning("请开启蓝牙")
                } else {
                  // setTimeout(function () {
                  //   rejected(initBlue())
                  //   // initBlue();
                  // }, 3000)
                }
              }
            })
          },
          fail: err => {
            if (isFirestShow) {
              warning("该设备不支持蓝牙")
            }
            rejected('noBlue')
          }
        });
      })
    }
    // // 开始搜索
    export function starBlue() {
      return new Promise((resolved, rejected) => {
        let init = () => {
          wx.startBluetoothDevicesDiscovery({
            allowDuplicatesKey: true,
            success: function (res) {
              resolved('success')
            },
            fail: err => {
              rejected('fail')
            }
          });
        }
    
        if (app.globalData.successDeviceId) {
          wx.closeBLEConnection({
            deviceId: app.globalData.successDeviceId,
            success: (res) => {
              app.globalData.successDeviceId = null
              app.globalData.blueStatus = {
                deviceId: null,
                connected: false
              }
              init()
            },
            fail: () => {
              app.globalData.successDeviceId = null
              app.globalData.blueStatus = {
                deviceId: null,
                connected: false
              }
              init()
            }
          })
        } else {
          init()
        }
      })
    }
    
    export function inArray(arr, key, val) {
      for (let i = 0; i < arr.length; i++) {
        if (arr[i][key] === val) {
          return i;
        }
      }
      return -1;
    }
    // // 获取蓝牙搜索列表
    export function getBule() {
      return new Promise((resolved, rejected) => {
        wx.getBluetoothDevices({
          success: function (res) {
            if (res.errMsg == 'getBluetoothDevices:ok') {
              resolved(res)
            } else {
              rejected('fail')
            }
          },
          fail: function () {
            rejected('fail')
    
          }
        });
      });
    
    }
    
    // // 蓝牙一键连接步骤 Quick为一键连接 无值则分步惭怍
    // // 连接蓝牙
    export function createBlue(deviceId, Quick) {
    
      return new Promise((resolved, rejected) => {
        wx.stopBluetoothDevicesDiscovery({
          success: function (res) {}
        })
        let createBlue = () => {
          wx.offBLEConnectionStateChange()
          wx.createBLEConnection({
            deviceId: deviceId,
            success: function (res) {
              getTheBlueDisConnectWithAccident(); //监听蓝牙是否会异常断开
              app.globalData.successDeviceId = deviceId
              if (Quick) {
                /* 获取设备的服务UUID */
                getBlueServe(deviceId, Quick).then(r => {
                  resolved(r)
                }).catch(err => {
                  rejected('fail')
                })
              } else {
                resolved('success')
              }
            },
            fail: (res) => {
              rejected('fail')
            },
          })
        }
        /* 开始连接蓝牙设备 */
        if (app.globalData.successDeviceId) {
          wx.closeBLEConnection({
            deviceId: app.globalData.successDeviceId,
            success: (res) => {
              app.globalData.successDeviceId = null
              app.globalData.blueStatus = {
                deviceId: null,
                connected: false
              }
              createBlue()
            },
            fail: () => {
              app.globalData.successDeviceId = null
              app.globalData.blueStatus = {
                deviceId: null,
                connected: false
              }
              createBlue()
            }
          })
        } else {
          createBlue()
        }
      })
    }
    // // 获取蓝牙特征  Quick是否一键连接
    export function getBlueServe(deviceId, Quick) {
      return new Promise((resolved, rejected) => {
        wx.getBLEDeviceServices({
          deviceId: deviceId,
          success: function (res) {
            if (Quick) {
              //取出所有的服务
              var all_UUID = res.services
              /* 遍历服务数组 */
              for (var index = 0; index < all_UUID.length; index++) {
                /* 判断是否是我们需要的FFE0 */
                if (all_UUID[index].isPrimary) {
                  // app.globalData.serviceId = all_UUID[index].uuid
                  Characteristics({
                    deviceId: deviceId,
                    serviceId: app.globalData.serviceId
                  }).then(res2 => {
                    resolved(res2)
                  }).catch(err => {
                    rejected('fail')
                  }); //调用获取特征值函数
                  break
                }
              };
            } else {
              resolved(res)
            }
          },
          fail: function (err) {
            rejected('fail')
          },
    
        });
      })
    }
    // // 获取到特征值
    export function Characteristics(o, Quick) {
      return new Promise((resolved, rejected) => {
        wx.getBLEDeviceCharacteristics({
          deviceId: o.deviceId,
          serviceId: o.serviceId,
          success: function (res) {
            app.globalData.blueStatus = {
              deviceId: o.deviceId,
              connected: true
            }
            if (Quick) {
              warning('重新连接成功')
            }
            var c_list = res.characteristics; //获取到所有特征值
            app.globalData.characteristicsList = c_list
            // if (Quick) {
            /* 遍历获取characteristicsId */
            for (var i = 0; i < c_list.length; i++) {
              if (c_list[i].properties.write) {
                app.globalData.characteristicsId = c_list[i].uuid
              }
              if (c_list[i].properties.notify || c_list[i].properties.indicate) {
                wx.readBLECharacteristicValue({
                  deviceId: o.deviceId,
                  serviceId: o.serviceId,
                  characteristicId: c_list[i].uuid,
                  success: function (res) {
                    console.log(res, '------notify---readBLECharacteristicValue');
                  },
                  fail: res => {
                    console.log(res, '---notify--shibai----readBLECharacteristicValue');
                  }
                })
                let uuid = c_list[i].uuid
                app.globalData.startNoticeUUid = uuid
    
              }
              // 此处执行 发送 接收信息准备
    
            };
    
            startNotice()
            resolved({
              data: res,
              type: 'success'
            })
          },
          fail: err => {
            rejected('fail')
          }
        })
      })
    }
    
    
    // 接收信息  ---接收 调用只能接收一个
    export function startNotice() {
    
      wx.notifyBLECharacteristicValueChange({
        state: true, // 启用 notify 功能
        deviceId: app.globalData.successDeviceId,
        serviceId: app.globalData.serviceId,
        characteristicId: app.globalData.startNoticeUUid, //第一步 开启监听 notityid  第二步发送指令 write
        success: function (res) {
          wx.onBLECharacteristicValueChange(function (res) {
            let val = arrayBufferToString(res.value);
            console.log(val, '-------接收返回值-----onBLECharacteristicValueChange');
            save(val)
          })
          // 设备返回的方法
        },
        fail: res => {
          // rejected('fail')
        }
      })
    }
    // 存放值蓝牙返回值
    let valStr = ''
    // 分别存放蓝牙数据返回 处理
    function save(val) {
      if (val == 'start') {
        valStr = ''
        return
      }
      if (val != 'end') {
        if (val.indexOf('0000##node_id##0000') != -1) {
          console.log(val, '-------------------------app.setOnlinSuccess()');
          //入网后判断是否能接收信息
          app.setOnlinSuccess(true)
        } else if (val.substring(0, 7) == 'znode##') {
          let nodeId = val.split('\r\n')[0]
          //254为调试盒子
          console.log(nodeId, '-------nodeId');
          if (nodeId.substring(13, 16) == '254') {
            // 证明入网成功
            console.log(nodeId, '-------app.globalData.statusManage.onlinSuccess');
            app.setOnlinSuccess(true)
          }
          app.getZigbeeList(nodeId)
        } else if (val.substring(4, 17) == '##send-fail##') {
          let nodeId = val.split('\r\n')[0]
          app.getZigbeeFailList(nodeId)
        } else if (val.substring(0, 6) == 'node##') {
          // 调光
          let nodeId = val.substring(6, val.length).split('\r\n')[0]
          if (!app.globalData.statusManage.nodes.includes(nodeId)) {
            app.globalData.statusManage.nodes.push(nodeId)
          }
        } else {
          valStr += val
        }
        return
      }
    
      if (val == 'end') {
        console.log(valStr, '------end --val');
        if (valStr.indexOf('line##') != -1) {
          console.log(valStr, '-------------------------line');
          let saveVal= valStr.split('\r\n')[0]
          console.log('------saveVal-',saveVal);
          app.saveMatchVal(saveVal)
        }else if (valStr == 'ok\r\n') {
          app.globalData.statusManage.status = valStr
        } else if (valStr.substring(0, 6) == 'uuid##') {
          app.globalData.statusManage.roomUUid = valStr.substring(6, valStr.length).split('\r\n')[0] //获取UUID
        } else if (valStr.substring(0, 6) == 'ssid##') {
          app.globalData.statusManage.RoomInfo = valStr //设备信息
        } else if (valStr.substring(0, 8) == 'online##') {
          app.globalData.statusManage.onlineList = valStr //设备信息
        } else if (valStr.substring(0, 6) == 'type##') {
          app.globalData.statusManage.type = valStr.substring(6, valStr.length).split('\r\n')[0] //设备信息
        }
      }
    }
    
    //监听蓝牙设备是否会异常断开 重新打开 ---- 待定
    export function getTheBlueDisConnectWithAccident() {
      wx.onBLEConnectionStateChange(function (res) {
        app.globalData.blueStatus = res
        if (!res.connected) {
          warning('当前调试盒子已断开')
          // monitorTheBlue()
        }
      })
    }
    //监听手机蓝牙的开关  ---- 待定
    export function monitorTheBlue(cb) {
      wx.onBluetoothAdapterStateChange(function (res) {
        if (res.available) {
          if (app.globalData.blueStatus.connected == false) {
            wx.closeBluetoothAdapter({
              success: function (r) {
                wx.openBluetoothAdapter({ //调用微信小程序api 打开蓝牙适配器接口
                  success: function () {
                    let d = app.globalData.successDeviceId
                    if (d) {
                      createBlue(d, true)
                    }
                  }
                })
              }
            })
          }
        } else {
          warning("蓝牙已关闭")
        }
      })
    }
    
    // 获取离线列表
    export function getOnline(val) {
      let v = val.split('\r\n')[0].split('online##')[1]
      let a = v.split('##')
      let arr = []
      a.forEach(v => {
        if (v) {
          arr.push(v)
        }
      })
      return arr
    }
    // 获取设备信息  读取配置,返回wifi账号密码、UUID、版本号
    export function getConfig(val) {
      let obj = {}
      let arr = val.split('\r\n')
      arr.forEach(v => {
        if (v) {
          let arrInfo = v.split('##')
          obj[arrInfo[0]] = arrInfo[1]
        }
      })
      return obj
    }
    // 传入对象转换成##连接的字符串
    export function objtoString(obj) {
      let str = ''
      for (let key in obj) {
        str += `##${key}##${obj[key]}`
      }
      return str
    }
    // 数组变成##连接的字符串
    export function arrToBlueString(arr) {
      let str = ''
      arr.forEach(v => {
        str += v + "##"
      })
      return str
    }
    
    //timesTotal 发送次数  errTimesTotal 发送重发次数
    const timesTotal = 2,
      errTimesTotal = 5
    let errTimes = 0,
      index = 0,
      times = 0,
      changeTimes = 0
    // 发送模板
    function sendTab(tmpBuffer) {
      wx.writeBLECharacteristicValue({
        deviceId: app.globalData.successDeviceId,
        serviceId: app.globalData.serviceId,
        characteristicId: app.globalData.characteristicsId,
        value: tmpBuffer,
        success: (res) => {
          index++
        },
        fail: (error) => {
          errTimes++
        }
      })
    }
    // 循环发送命令
    function forEachSend(str) {
      index = 0;
      let strArr = []
      let length = str.length
      changeTimes = Math.ceil(length / 20)
      for (var i = 0; i < str.length; i += 20) {
        let s = str.substring(i, i + 20)
        strArr.push(stringToHexBuffer(s))
      }
      strArr.forEach(v => {
        sendTab(v)
      })
    }
    export function send_getType() {
      var val = '0000##get-type\r\n';
      errTimes = 0;
      times = 0;
      return new Promise((resolved, rejected) => {
        if (!app.globalData.blueStatus.connected) {
          warning("请先前往连接蓝牙")
          rejected('openBlue')
          return
        }
        app.globalData.statusManage.type = null
        let returnVal = () => {
          setTimeout(() => {
            console.log(val, index, changeTimes, '----index,changeTimes', app.globalData.statusManage.type);
            if (index == changeTimes && app.globalData.statusManage.type) {
              console.log('成功回调', val);
              resolved('success')
            } else {
              if (times < timesTotal) {
                times++
                forEachSend(val)
                returnVal()
              } else {
                rejected('fail')
              }
            }
          }, 2000);
        }
        forEachSend(val)
        returnVal()
      })
    }
    
    // 返回OK的封装
    // 发送 Wifi账号密码、发送房间号、发送启动配置、停止配置、开始配置其他设备、停止配置、发送继电器状态
    export function send_ReturnOk(str) {
      console.log(str);
      errTimes = 0;
      times = 0;
      return new Promise((resolved, rejected) => {
        if (!app.globalData.blueStatus.connected) {
          warning("请先前往连接蓝牙")
          rejected('openBlue')
          return
        }
        app.globalData.statusManage.status = null
        let returnVal = () => {
          setTimeout(() => {
            console.log(str, index, changeTimes, '----index,changeTimes', app.globalData.statusManage.status);
    
            if (index == changeTimes && app.globalData.statusManage.status == 'ok\r\n') {
              console.log('成功回调', str);
              resolved('success')
            } else {
              if (times < timesTotal) {
                times++
                forEachSend(str)
                returnVal()
              } else {
                rejected('fail')
              }
            }
          }, 2000);
        }
        forEachSend(str)
        returnVal()
      })
    }
    // /获取UUID
    export function send_getUUid(roomNumber) {
      let str = bluePrefix(roomNumber) + "##uuid\r\n";
      errTimes = 0;
      times = 0;
      console.log(str, '------------send_getUUid');
      return new Promise((resolved, rejected) => {
        if (!app.globalData.blueStatus.connected) {
          warning("请先前往连接蓝牙")
          rejected('openBlue')
          return
        }
        app.globalData.statusManage.roomUUid = null
        let returnVal = () => {
          setTimeout(() => {
            console.log(index, changeTimes, '----index,changeTimes');
            if (index == changeTimes && app.globalData.statusManage.roomUUid) {
              if (app.globalData.statusManage.roomUUid.length == 36) {
                resolved('success')
              } else {
                if (times < timesTotal) {
                  times++
                  forEachSend(str)
                  returnVal()
                } else {
                  rejected('fail')
                }
              }
            } else {
              if (times < timesTotal) {
                times++
                forEachSend(str)
                returnVal()
              } else {
                rejected('fail')
              }
            }
          }, 2000);
        }
        forEachSend(str)
        returnVal()
      })
    }
    
    
    // /获取设备信息
    export function get_config(str) {
      errTimes = 0;
      times = 0;
      return new Promise((resolved, rejected) => {
        if (!app.globalData.blueStatus.connected) {
          warning("请先前往连接蓝牙")
          rejected('openBlue')
          return
        }
        app.globalData.statusManage.RoomInfo = null
        let returnVal = () => {
          setTimeout(() => {
            console.log(index, changeTimes, '----index,changeTimes');
            if (index == changeTimes && app.globalData.statusManage.RoomInfo) {
              resolved('success')
            } else {
              if (times < timesTotal) {
                times++
                forEachSend(str)
                returnVal()
              } else {
                rejected('fail')
              }
            }
          }, 2000);
        }
        forEachSend(str)
        returnVal()
    
      })
    
    }
    
    // 轮询设备是否在线
    export function get_onlineList(str) {
      errTimes = 0;
      times = 0;
      return new Promise((resolved, rejected) => {
        if (!app.globalData.blueStatus.connected) {
          warning("请先前往连接蓝牙")
          rejected('openBlue')
          return
        }
        app.globalData.statusManage.onlineList = null
        let returnVal = () => {
          setTimeout(() => {
            console.log(index, changeTimes, '----index,changeTimes');
            if (index == changeTimes && app.globalData.statusManage.onlineList) {
              resolved('success')
            } else {
              if (times < timesTotal) {
                times++
                forEachSend(str)
                returnVal()
              } else {
                rejected('fail')
              }
            }
          }, 2000);
        }
        forEachSend(str)
        returnVal()
      })
    }
    
    // 调光
    export function get_nodeList(str) {
      errTimes = 0;
      times = 0;
      return new Promise((resolved, rejected) => {
        if (!app.globalData.blueStatus.connected) {
          warning("请先前往连接蓝牙")
          rejected('openBlue')
          return
        }
        // app.globalData.statusManage.nodes = []
        let returnVal = () => {
          setTimeout(() => {
            console.log(index, changeTimes, '----index,changeTimes');
            if (index == changeTimes && app.globalData.statusManage.nodes.length > 0) {
              resolved('success')
            } else {
              if (times < timesTotal) {
                times++
                forEachSend(str)
                returnVal()
              } else {
                rejected('fail')
              }
            }
          }, 2000);
        }
        forEachSend(str)
        returnVal()
      })
    }
    // Zigbee
    export function get_scan_NodeList(str) {
      errTimes = 0;
      times = 0;
      return new Promise((resolved, rejected) => {
        if (!app.globalData.blueStatus.connected) {
          warning("请先前往连接蓝牙")
          rejected('openBlue')
          return
        }
        // app.globalData.statusManage.nodes = []
        let returnVal = () => {
          setTimeout(() => {
            if (index == changeTimes && app.globalData.statusManage.zigbeeList.length > 0) {
              resolved('success')
            } else {
              if (times < timesTotal) {
                times++
                forEachSend(str)
                returnVal()
              } else {
                rejected('fail')
              }
            }
          }, 2000);
        }
        forEachSend(str)
        returnVal()
      })
    }
    
    
    // 字符串转buffer
    export function stringToHexBuffer(str) {
      var bytes = new Array();
      var len, c;
      len = str.length;
      for (var i = 0; i < len; i++) {
        c = str.charCodeAt(i);
        if (c >= 0x010000 && c <= 0x10FFFF) {
          bytes.push(((c >> 18) & 0x07) | 0xF0);
          bytes.push(((c >> 12) & 0x3F) | 0x80);
          bytes.push(((c >> 6) & 0x3F) | 0x80);
          bytes.push((c & 0x3F) | 0x80);
        } else if (c >= 0x000800 && c <= 0x00FFFF) {
          bytes.push(((c >> 12) & 0x0F) | 0xE0);
          bytes.push(((c >> 6) & 0x3F) | 0x80);
          bytes.push((c & 0x3F) | 0x80);
        } else if (c >= 0x000080 && c <= 0x0007FF) {
          bytes.push(((c >> 6) & 0x1F) | 0xC0);
          bytes.push((c & 0x3F) | 0x80);
        } else {
          bytes.push(c & 0xFF);
        }
      }
      var array = new Int8Array(bytes.length);
      for (var i in bytes) {
        array[i] = bytes[i];
      }
      return array.buffer;
    }
    //buffer 十六进制 转字符串
    export function arrayBufferToString(arr) {
      if (typeof arr === 'string') {
        return arr;
      }
      var dataview = new DataView(arr);
      var ints = new Uint8Array(arr.byteLength);
      for (var i = 0; i < ints.length; i++) {
        ints[i] = dataview.getUint8(i);
      }
      arr = ints;
      var str = '',
        _arr = arr;
      for (var i = 0; i < _arr.length; i++) {
        var one = _arr[i].toString(2),
          v = one.match(/^1+?(?=0)/);
        if (v && one.length == 8) {
          var bytesLength = v[0].length;
          var store = _arr[i].toString(2).slice(7 - bytesLength);
          for (var st = 1; st < bytesLength; st++) {
            store += _arr[st + i].toString(2).slice(2);
          }
          str += String.fromCharCode(parseInt(store, 2));
          i += bytesLength - 1;
        } else {
          str += String.fromCharCode(_arr[i]);
        }
      }
      return str;
    }
    export function bin_to_hex(str) {
      let hex_array = [{
          key: 0,
          val: "0000"
        }, {
          key: 1,
          val: "0001"
        }, {
          key: 2,
          val: "0010"
        }, {
          key: 3,
          val: "0011"
        }, {
          key: 4,
          val: "0100"
        }, {
          key: 5,
          val: "0101"
        }, {
          key: 6,
          val: "0110"
        }, {
          key: 7,
          val: "0111"
        },
        {
          key: 8,
          val: "1000"
        }, {
          key: 9,
          val: "1001"
        }, {
          key: 'a',
          val: "1010"
        }, {
          key: 'b',
          val: "1011"
        }, {
          key: 'c',
          val: "1100"
        }, {
          key: 'd',
          val: "1101"
        }, {
          key: 'e',
          val: "1110"
        }, {
          key: 'f',
          val: "1111"
        }
      ]
      let value = ''
      let list = []
      if (str.length % 4 !== 0) {
        let a = "0000"
        let b = a.substring(0, 4 - str.length % 4)
        str = b.concat(str)
      }
      while (str.length > 4) {
        list.push(str.substring(0, 4))
        str = str.substring(4);
      }
      list.push(str)
      for (let i = 0; i < list.length; i++) {
        for (let j = 0; j < hex_array.length; j++) {
          if (list[i] == hex_array[j].val) {
            value = value.concat(hex_array[j].key)
            break
          }
        }
      }
      return value
    }
    
    
    // 蓝牙房间号等 参数 四位封装
    export function bluePrefix(val, Leg = 4) {
      val = val ? val : ''
      if (typeof (val) == 'number') {
        val = val.toString()
      }
      let returnVal = '';
      if (val.length < Leg) {
        let iLength = Leg - val.length
        for (let i = 0; i < iLength; i++) {
          returnVal += '0'
        }
      }
      returnVal += val
      return returnVal
    }
    

    展开全文
  • 微信小程序API2.蓝牙部分的API可以到微信公众平台去找,都是官方文件。Android从微信6.5.7开始支持蓝牙程序,iOS从微信6.5.6开始支持。3.之前自己稍微整理过一个流程。4.蓝牙流程2.BLE4.05.BLE4.0是现在流行的一种...
  • 微信小程序蓝牙BLE开发实战——API及流程介绍(一)

    千次阅读 多人点赞 2019-11-06 16:48:56
    微信小程序蓝牙BLE开发(一) 迟来的更新。上半年4月份以来项目中断续在对接好几个产品关于蓝牙BLE设备,通过蓝牙与设备之间通信进行使用产品。开发中也遇到不少问题哈,后面抽时间续篇。写得不好,请各位大神多多...
  • 微信小程序蓝牙功能

    千次阅读 多人点赞 2021-01-25 10:36:35
    微信小程序目前只支持低功耗蓝牙(BLE),文档中的两套API是可以混合使用的,请大家不用再去社区问这些问题了。 微信的文档 已经很详细了,不懂的主要是流程,本文主要介绍流程怎样提交和接收数据,也就是通信。 1....
  • 使用微信小程序兼容Android、Ios双平台上线与蓝牙硬件的交互。具体实现文章结尾会放上源码。 1、蓝牙定位 在使用扫描前一定要先查看蓝牙和定位是否全部开启,否则就会导致没有反应。 2、UUID Android和Ios有所不同...
  • 微信小程序蓝牙控制开门

    千次阅读 2020-01-10 15:37:46
    小程序低功耗蓝牙控制开门 整体流程 初始化蓝牙模块openBluetoothAdapter 获取本机蓝牙适配器状态getBluetoothAdapterState 搜索外围蓝牙设备startBluetoothDevicesDiscovery 监听寻找到新设备...
  • 答:有蓝牙版本有关,在BLE 4.2以上版本有一个新特性叫DLE(Data length Extension),在芯片与手机连接的时候会先交互这个,如果两边都支持DLE的话,就可以发送大于20字节的包,如果有任意一个设备不支持,就会拆
  • 微信小程序蓝牙使用总结

    千次阅读 2019-02-27 17:51:22
    微信小程序获取蓝牙流程 注意点: wx.openBluetoothAdapter(Object object):初始化蓝牙模块。 其他蓝牙相关 API 必须在 wx.openBluetoothAdapter 调用之后使用。否则 API 会返回错误(errCode=10000)。 在...
  • 微信小程序蓝牙标签打印/标签云打印开放云平台(下面简称“平台” www.herro.cn 技术服务TEL:15759216805),支持开发者通过API调用完成标签蓝牙打印或标签云打印功能。平台支持的功能请微信搜索小程序“标签快印”...
  • @微信小程序蓝牙打印—分包发送(安卓和苹果手机均兼容)解决中文乱码 需求 由于公司业务需求,在原APP(H5开发)的基础上,设计一套小程序版本的项目(小程序内嵌H5开发)。为此顺便学习了一下小程序的开发以及连接...
  • 最近开发的一个小程序里需要对接热敏打印机打印小票,在此记录一下对接的过程 项目开发注意点: 1、因为项目中有多个页面的数据是需要进行打印的,为了保持蓝牙的...微信小程序蓝牙打印 项目效果图 打印效果图 项.
  • 微信小程序蓝牙BLE开发实战(二) 上篇主要介绍在开发过程中应用到相关API操作。接下来介绍个人在项目开发中应用蓝牙BLE一些事情。 由于时间比较仓促, 有些注释没那么详细。请理解~写的不好欢迎各位大神指。 项目...
  • 文章目录一、前言二、设备核心代码2.1 蓝牙控制2.2 WiFi控制2.3 外设驱动三、微信小程序核心代码3.1 蓝牙搜索3.2 蓝牙服务发现四、感谢另外,不要把我的博客作为学习标准,我的只是笔记,难有疏忽之处,如果有,请指...
  • 微信小程序--Ble蓝牙

    2021-03-29 19:56:17
    蓝牙总共增加了18个api接口。 2.Api分类 搜索类 连接类 通信类 3.API的具体使用 详细见官网: https://mp.weixin.qq.com/debug/wxadoc/dev/api/bluetooth.html#wxgetconnectedbluethoothdevicesobject 4. 案例实现 ...
  • 欢迎点击「算法与编程之美」↑关注我们!本文首发于微信公众号:"算法与编程之美",欢迎关注,及时了解更多此系列文章。欢迎加入团队圈子!与作者面对面!直接点击!1、扫码的插入...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 2,760
精华内容 1,104
关键字:

微信小程序蓝牙api

微信小程序 订阅
友情链接: 牛顿_拉夫逊法.zip