• uniapp 小程序低功耗蓝牙配网 ble配网 物联网


     1.获取蓝牙列表  bleList.vue

    1. <script>
    2. export default {
    3. data() {
    4. return {
    5. bluetoohList: [],
    6. };
    7. },
    8. onLoad: function (options) {
    9. this.startSearch();
    10. },
    11. methods: {
    12. // 连接蓝牙
    13. startSearch() {
    14. let that = this;
    15. that.$ble.openBluetoothAdapter(
    16. (res) => {
    17. that.$ble.getBluetoothAdapterState((res) => {
    18. if (res.available) {
    19. if (res.discovering) {
    20. that.$ble.stopBluetoothDevicesDiscovery();
    21. } else {
    22. that.getBluetoothDevices();
    23. }
    24. that.checkPemission();
    25. } else {
    26. that.$tip.toast("本机蓝牙不可用");
    27. }
    28. });
    29. },
    30. (err) => {
    31. that.openSetting();
    32. }
    33. );
    34. },
    35. openSetting() {
    36. let params = {
    37. title: "检测到您没打开蓝牙权限,是否去设置打开?",
    38. showCancel: true,
    39. };
    40. this.$tip.showModal(params, (res) => {
    41. if (res.confirm) {
    42. this.$ble.openSetting();
    43. }
    44. });
    45. },
    46. checkPemission() {
    47. //android 6.0以上需授权地理位置权限
    48. var that = this;
    49. const sys = uni.getSystemInfoSync();
    50. if (sys.platform == "ios") {
    51. that.getBluetoothDevices();
    52. } else if (sys.platform == "android") {
    53. console.log(
    54. app
    55. .getSystem()
    56. .substring(
    57. app.getSystem().length - (app.getSystem().length - 8),
    58. app.getSystem().length - (app.getSystem().length - 8) + 1
    59. )
    60. );
    61. if (
    62. app.globalData
    63. .getSystem()
    64. .substring(
    65. app.globalData.getSystem().length -
    66. (app.globalData.getSystem().length - 8),
    67. app.globalData.getSystem().length -
    68. (app.globalData.getSystem().length - 8) +
    69. 1
    70. ) > 5
    71. ) {
    72. uni.getSetting({
    73. success: (res) => {
    74. console.log(res);
    75. if (!res.authSetting["scope.userLocation"]) {
    76. uni.authorize({
    77. scope: "scope.userLocation",
    78. complete: (res) => {
    79. that.getBluetoothDevices();
    80. },
    81. });
    82. } else {
    83. that.getBluetoothDevices();
    84. }
    85. },
    86. });
    87. }
    88. }
    89. },
    90. //获取蓝牙设备信息
    91. getBluetoothDevices() {
    92. that.$tip.loading("蓝牙搜索中");
    93. this.$ble.getBluetoothDevices((res) => {
    94. this.bluetoohList = res;
    95. this.$tip.loaded();
    96. });
    97. },
    98. // 连接蓝牙 跳转到连接页面
    99. openControl(item) {
    100. let params = {
    101. list: this.bluetoohList,
    102. info: item,
    103. };
    104. this.$tip.redirectTo("/pages/ble/ble", params);
    105. },
    106. },
    107. };
    108. script>
    109. <style scoped>
    110. .content-pop {
    111. width: 100vw;
    112. max-height: 55vh;
    113. padding: 0 30rpx;
    114. }
    115. .bluetoothItem {
    116. padding: 20rpx 0;
    117. font-weight: 400;
    118. font-size: 28rpx;
    119. border-bottom: 1rpx solid #f4f4f4;
    120. text-align: left;
    121. }
    122. .textItem {
    123. display: block;
    124. margin-bottom: 10rpx;
    125. }
    126. style>

    2.选择蓝牙进行连接  ble.vue

    1. <style scoped>
    2. .zai-box {
    3. padding: 0;
    4. margin: 0;
    5. height: 100%;
    6. background-color: #fff;
    7. }
    8. .container {
    9. padding: 30rpx;
    10. margin: 0;
    11. font-size: 28rpx;
    12. color: #20212b;
    13. background-color: #fff;
    14. text-align: left;
    15. font-weight: 400;
    16. }
    17. image {
    18. width: 362rpx;
    19. height: 362rpx;
    20. margin-top: 30rpx;
    21. }
    22. .textTitle {
    23. display: block;
    24. font-size: 36rpx;
    25. font-weight: bold;
    26. color: #20212b;
    27. display: block;
    28. margin-bottom: 30rpx;
    29. }
    30. .textItem {
    31. display: block;
    32. font-size: 24rpx;
    33. font-weight: 400;
    34. color: #999999;
    35. line-height: 36rpx;
    36. }
    37. style>

    3. 蓝牙连接WiFi  bleWifi.vue

    1. <script>
    2. import APToast from "@/util/APToast.js";
    3. export default {
    4. data() {
    5. return {
    6. SSID: "your SSID",
    7. password: "",
    8. connected: true,
    9. wifiCountDown: 0,
    10. wifiCountInterval: null, // 定时器
    11. blefiInfo: {},
    12. };
    13. },
    14. // 二级页面清除
    15. onUnload() {
    16. this.$ble.offBLEConnectionStateChange();
    17. this.clearIntervalWifi();
    18. },
    19. onLoad(options) {
    20. this.blefiInfo = uni.getStorageSync("blefiInfo");
    21. let sys = uni.getStorageSync("phoneInfo");
    22. if (sys.platform == "android") {
    23. // this.$ble.onBLEMTUChange((res) => {
    24. // console.log(res, "androidMTU");
    25. // });
    26. // this.$ble.getBLEMTU(this.blefiInfo.deviceId, (res) => {
    27. // console.log(res, "mtu");
    28. // });
    29. // 安卓要手动更改MTU值
    30. const mtu = 512;
    31. this.$ble.setBLEMTU(
    32. this.blefiInfo.deviceId,
    33. mtu,
    34. (res) => {
    35. console.log(res);
    36. },
    37. (err) => {
    38. console.log(err);
    39. }
    40. );
    41. }
    42. this.$ble.getBLEDeviceServices(this.blefiInfo.deviceId, (res) => {
    43. this.$ble.getBLEDeviceCharacteristics(
    44. this.blefiInfo.deviceId,
    45. this.blefiInfo.serveiceId,
    46. (res) => {
    47. // 部分不需要开启notify,开启会监听不到返回信息,自行判断
    48. this.$ble.notifyBLECharacteristicValueChange(
    49. true,
    50. this.blefiInfo.deviceId,
    51. this.blefiInfo.serveiceId,
    52. this.blefiInfo.readCharId,
    53. (res) => {
    54. console.log("启用notify成功");
    55. }
    56. );
    57. }
    58. );
    59. });
    60. this.$ble.onBLEConnectionStateChange((res) => {
    61. this.connected = res.connected;
    62. if (!res.connected) {
    63. this.$tip.loaded();
    64. // 蓝牙连接失败,跳转到失败页面
    65. this.$tip.redirectTo("/pages/ble/bleFail");
    66. }
    67. });
    68. // 接收配网打印机回传的数据
    69. this.$ble.onBLECharacteristicValueChange((res) => {
    70. if (!res || res.value.byteLength == 0) return;
    71. this.clearIntervalWifi();
    72. this.$tip.loaded();
    73. let num = new Int32Array(res.value)[0];
    74. console.log(num, "NUM");
    75. // 失败原因
    76. let tip = APToast.find((item) => item.id == num);
    77. if (num == 0) {
    78. // 连接wifi成功
    79. this.$tip.redirectTo("/pages/ble/WifiSuccess");
    80. } else {
    81. // 连接WiFi失败
    82. this.$tip.redirectTo("/pages/ble/WifiFile",tip);
    83. }
    84. });
    85. },
    86. methods: {
    87. settiing() {
    88. this.startSMSTimer("60");
    89. this.$tip.loading("连接中");
    90. if (this.connected) {
    91. this.sendWifi();
    92. } else {
    93. this.$tip.loaded();
    94. // 蓝牙连接失败,跳转到失败页面
    95. this.$tip.redirectTo("/pages/ble/bleFail");
    96. }
    97. },
    98. // 转UTF-8
    99. sendWifi() {
    100. let msg = {
    101. event: "network",
    102. data: { ssid: this.SSID, password: this.password, authmode: 4 },
    103. };
    104. let buffer = this.stringToUint8Array(JSON.stringify(msg));
    105. this.bleSendWifi(buffer);
    106. },
    107. // json字符串数据转Uint8Array
    108. stringToUint8Array(str) {
    109. // 方法一
    110. // var arr = [];
    111. // for (var i = 0, j = str.length; i < j; ++i) {
    112. // arr.push(str.charCodeAt(i));
    113. // }
    114. // var tmpUint8Array = new Uint8Array(arr);
    115. // return tmpUint8Array.buffer;
    116. // 方法二
    117. let buffer = new ArrayBuffer(str.length);
    118. let dataView = new DataView(buffer);
    119. for (var i = 0; i < str.length; i++) {
    120. dataView.setUint8(i, str.charCodeAt(i));
    121. }
    122. return buffer;
    123. },
    124. bleSendWifi(payload) {
    125. if (this.connected) {
    126. this.$ble.writeBLECharacteristicValueOnce(
    127. this.blefiInfo.deviceId,
    128. this.blefiInfo.serveiceId,
    129. this.blefiInfo.writecharId,
    130. payload
    131. );
    132. if (this.blefiInfo.readCharId) {
    133. this.$ble.readBLECharacteristicValue(
    134. this.blefiInfo.deviceId,
    135. this.blefiInfo.serveiceId,
    136. this.blefiInfo.readCharId
    137. );
    138. }
    139. }
    140. },
    141. startSMSTimer(val) {
    142. this.wifiCountDown = val;
    143. this.wifiCountInterval = setInterval(() => {
    144. this.wifiCountDown--;
    145. // console.log(this.wifiCountDown);
    146. if (this.wifiCountDown <= 0) {
    147. clearInterval(this.wifiCountInterval);
    148. this.wifiCountInterval = null;
    149. this.$tip.loaded();
    150. // 连接WiFi失败
    151. this.$tip.redirectTo("/pages/ble/WifiFile");
    152. }
    153. }, 1000);
    154. },
    155. clearIntervalWifi() {
    156. this.wifiCountDown = 0;
    157. if (this.wifiCountInterval) {
    158. clearInterval(this.wifiCountInterval);
    159. this.wifiCountInterval = null;
    160. }
    161. },
    162. },
    163. };
    164. script>

    4. 手机连接蓝牙失败、蓝牙连接WiFi成功/失败(关闭蓝牙连接)

    5.ble.js

    1. class ble {
    2. openBluetoothAdapter(success, failure) {
    3. uni.openBluetoothAdapter({
    4. success: (res) => {
    5. success(res);
    6. },
    7. fail: (err) => {
    8. failure(err);
    9. },
    10. });
    11. }
    12. getBluetoothAdapterState(success) {
    13. uni.getBluetoothAdapterState({
    14. success: (res) => {
    15. success(res);
    16. },
    17. });
    18. }
    19. //停止搜寻附近的蓝牙外围设备
    20. stopBluetoothDevicesDiscovery() {
    21. uni.stopBluetoothDevicesDiscovery();
    22. }
    23. //获取蓝牙设备信息
    24. getBluetoothDevices(success) {
    25. // 开始搜寻附近的蓝牙外围设备
    26. uni.startBluetoothDevicesDiscovery({
    27. success: (res) => {
    28. setTimeout(() => {
    29. // 获取搜索到的设备信息
    30. uni.getBluetoothDevices({
    31. success: (res) => {
    32. let bluetoohList = [];
    33. var num = 0;
    34. for (var i = 0; i < res.devices.length; ++i) {
    35. if (res.devices[i].name != "未知设备") {
    36. bluetoohList[num] = res.devices[i];
    37. num++;
    38. }
    39. }
    40. this.stopBluetoothDevicesDiscovery();
    41. success(bluetoohList);
    42. },
    43. });
    44. }, 5000);
    45. // that.onBluetoothDeviceFound();
    46. },
    47. });
    48. }
    49. openSetting() {
    50. uni.openSetting({
    51. //opensetting是调起设置页面的
    52. success: (res) => {
    53. if (res.authSetting == true) {
    54. //判断res.authsetting的值是true还是false
    55. uni.openBluetoothAdapter();
    56. }
    57. },
    58. });
    59. }
    60. //断开与低功耗蓝牙设备的连接
    61. closeBLEConnection(deviceId) {
    62. uni.closeBLEConnection({
    63. deviceId: deviceId,
    64. });
    65. }
    66. offBLEConnectionStateChange() {
    67. wx.offBLEConnectionStateChange();
    68. }
    69. //连接低功耗蓝牙设备
    70. createBLEConnection(deviceId, success, failure) {
    71. uni.createBLEConnection({
    72. deviceId: deviceId,
    73. success: (res) => {
    74. success(res);
    75. },
    76. fail: (err) => {
    77. failure(err);
    78. },
    79. });
    80. }
    81. //获取蓝牙设备所有服务
    82. getBLEDeviceServices(deviceId, success, failure) {
    83. wx.getBLEDeviceServices({
    84. deviceId: deviceId,
    85. success: (res) => {
    86. success(res);
    87. },
    88. fail(err) {
    89. failure(err);
    90. },
    91. });
    92. }
    93. //获取蓝牙设备某个服务中所有特征值
    94. getBLEDeviceCharacteristics(deviceId, serviceId, success, failure) {
    95. wx.getBLEDeviceCharacteristics({
    96. deviceId: deviceId,
    97. serviceId: serviceId,
    98. success: (res) => {
    99. success(res);
    100. },
    101. fail(err) {
    102. failure(err);
    103. },
    104. });
    105. }
    106. notifyBLECharacteristicValueChange(
    107. state,
    108. deviceId,
    109. serviceId,
    110. characteristicId,
    111. success
    112. ) {
    113. wx.notifyBLECharacteristicValueChange({
    114. state: state,
    115. deviceId: deviceId,
    116. serviceId: serviceId,
    117. characteristicId: characteristicId,
    118. success: function (res) {
    119. success(res);
    120. },
    121. });
    122. }
    123. onBLEConnectionStateChange(success) {
    124. wx.onBLEConnectionStateChange((res) => {
    125. success(res);
    126. });
    127. }
    128. // 接收配网打印机回传的数据
    129. onBLECharacteristicValueChange(success) {
    130. wx.onBLECharacteristicValueChange((res) => {
    131. success(res);
    132. });
    133. }
    134. //关闭蓝牙模块
    135. closeBluetoothAdapter() {
    136. wx.closeBluetoothAdapter();
    137. }
    138. // 不分包写入蓝牙
    139. writeBLECharacteristicValueOnce(
    140. deviceId,
    141. serviceId,
    142. characteristicId,
    143. value
    144. ) {
    145. wx.writeBLECharacteristicValue({
    146. deviceId: deviceId,
    147. serviceId: serviceId,
    148. characteristicId: characteristicId,
    149. value: value,
    150. });
    151. }
    152. readBLECharacteristicValue(deviceId, serviceId, characteristicId) {
    153. wx.readBLECharacteristicValue({
    154. deviceId: deviceId,
    155. serviceId: serviceId,
    156. characteristicId: characteristicId,
    157. });
    158. }
    159. getBLEMTU(deviceId, success) {
    160. wx.getBLEMTU({
    161. deviceId: deviceId,
    162. writeType: "write",
    163. success(res) {
    164. success(res.mtu);
    165. },
    166. });
    167. }
    168. onBLEMTUChange(success) {
    169. wx.onBLEMTUChange(function (res) {
    170. success(res.mtu);
    171. });
    172. }
    173. setBLEMTU(deviceId, mtu, success, failure) {
    174. wx.setBLEMTU({
    175. deviceId: deviceId,
    176. mtu: mtu,
    177. success: (res) => {
    178. success(res);
    179. },
    180. fail: (res) => {
    181. failure(res);
    182. },
    183. });
    184. }
    185. }
    186. const bleDevice = new ble();
    187. export default bleDevice;

    6.APToast.js

    1. const message = [
    2. {
    3. id:0,
    4. type:"WIFI_REASON_SUCCESS",
    5. message:"打印机连接成功"
    6. },
    7. {
    8. id:2,
    9. type:"WIFI_REASON_AUTH_EXPIRE",
    10. message:"身份验证超时"
    11. },
    12. {
    13. id:3,
    14. type:"WIFI_REASON_AUTH_LEAVE",
    15. message:"连接中断"
    16. },
    17. {
    18. id:8,
    19. type:"WIFI_REASON_ASSOC_LEAVE",
    20. message:"连接中断"
    21. },
    22. {
    23. id:15,
    24. type:"WIFI_REASON_4WAY_HANDSHAKE_TIMEOUT",
    25. message:"密码错误"
    26. },
    27. {
    28. id:201,
    29. type:"WIFI_REASON_NO_AP_FOUND",
    30. message:"未找到可用的网络"
    31. },
    32. {
    33. id:202,
    34. type:"WIFI_REASON_AUTH_FAIL",
    35. message:"密码错误或身份验证超时"
    36. },
    37. {
    38. id:203,
    39. type:"WIFI_REASON_ASSOC_FAIL",
    40. message:"设备无法与WiFi成功关联"
    41. },
    42. {
    43. id:204,
    44. type:"WIFI_REASON_HANDSHAKE_TIMEOUT",
    45. message:"密码错误"
    46. },
    47. {
    48. id:205,
    49. type:"WIFI_REASON_CONNECTION_FAIL",
    50. message:"连接失败"
    51. },
    52. ]
    53. export default message;

    7.tip.js

    1. export default class Tips {
    2. /**
    3. * 弹出提示框
    4. */
    5. static success(title, duration = 1000) {
    6. setTimeout(() => {
    7. uni.showToast({
    8. title: title,
    9. icon: "success",
    10. mask: true,
    11. duration: duration,
    12. });
    13. }, 300);
    14. if (duration > 0) {
    15. return new Promise((resolve, reject) => {
    16. setTimeout(() => {
    17. resolve();
    18. }, duration);
    19. });
    20. }
    21. }
    22. /**
    23. * 弹出加载提示
    24. */
    25. static loading(title = "加载中") {
    26. if (Tips.isLoading) {
    27. return;
    28. }
    29. Tips.isLoading = true;
    30. uni.showLoading({
    31. title: title,
    32. mask: true,
    33. });
    34. }
    35. /**
    36. * 加载完毕
    37. */
    38. static loaded() {
    39. if (Tips.isLoading) {
    40. Tips.isLoading = false;
    41. uni.hideLoading();
    42. }
    43. }
    44. /**
    45. * 关闭当前页面,跳转到新页面
    46. */
    47. static redirectTo(urls, item) {
    48. uni.redirectTo({
    49. url: item
    50. ? urls + "?info=" + encodeURIComponent(JSON.stringify(item))
    51. : urls, // JSON.parse(decodeURIComponent(option.info));
    52. });
    53. }
    54. /**
    55. * 弹出确认窗口
    56. */
    57. static showModal(val, success) {
    58. uni.showModal({
    59. title: val.title ? val.title : "",
    60. content: val.content ? val.content : "",
    61. showCancel: val.showCancel,
    62. confirmText: val.confirmText ? val.confirmText : "确定",
    63. cancelText: val.cancelText ? val.cancelText : "取消",
    64. cancelColor: "#999999", //取消按钮颜色
    65. confirmColor: "#00A0E9", //确定按钮颜色
    66. success: (res) => {
    67. success(res);
    68. },
    69. });
    70. }
    71. }
    72. /**
    73. * 静态变量,是否加载中
    74. */
    75. Tips.isLoading = false;

    8.main.js

    1. import ble from "./common/util/ble.js";
    2. import tip from "./common/util/tip.js";
    3. // ble
    4. Vue.prototype.$ble = ble;
    5. // tip
    6. Vue.prototype.$tip = tip;

  • 相关阅读:
    第5篇 vue的通信框架axios和ui框架-element-ui以及node.js
    用vue2-ace-editor做个代码编辑界面
    Django更改超级用户密码
    记录自签tomcat所用TLS1.2链接所需SSL证书
    05 【动静分离和URLRewrite】
    java通过用户id寻找下级
    STM32H743XX/STM32H563XX芯片烧录一次后,再次上电无法烧录
    Docker查看容器的初始启动命令参数的常见几种方式
    Apache Doris 2.0.0 版本正式发布:盲测性能 10 倍提升,更统一多样的极速分析体验
    Python数据分析与可视化期末简答题复习
  • 原文地址:https://blog.csdn.net/future_1_/article/details/138580287