uni-app开发微信小程序使用BLE低功耗蓝牙正确步骤

文章目录

  • 前言
  • 连接逻辑
  • 建议

参考资料:https://www.hc01.com/downloads
在这里插入图片描述

前言

微信小程序通过蓝牙连接设备,所以需要使用到BLE连接。
思路:
小程序连接BLE的步骤+已经知道设备的BLE名称、服务id、特征值ID。需要根据蓝牙模块提供商的说明书去选择相应的服务、特征值。

注意:监听和写入不一定是同一个特征值。

连接逻辑

假设设备的蓝牙名称是MAX-8080
1、扫一扫二维码获取蓝牙名称;
2、连接BLE准备;
3、根据蓝牙名称链接BLE;
4、连接成功监听特征值;
5、收发数据。

代码:

<script>
export default {
	data() {
		return {
			connected:null,
			deviceId:null,
			scan_result:null,
			// 蓝牙适配器参数
			adapterState: {
				discovering: false,
				available: false
			},  
			// 搜索出来的蓝牙设备列表
			devicesLsits: [],
			/**
			 * 定时器
			*/
			_discoveryTimer: null,
			_discoveryTimeout: 30000, // 搜索设备超时时间,单位ms
			HC02CharacteristicNotifyUUID:"49535343-1E4D-4BD9-BA61-23C647249616",
			HC02ServiceUUID:'49535343-FE7D-4AE5-8FA9-9FAFD205E455',
			}
		},
		methods: {

			/**
			 * 扫一扫调用接口,如果执行成功,app.scan_result会有值
			 */
			scan_weixi() {
				uni.scanCode({
					success: (res) => {
						// 取出扫码的设备名称 MAX-8080
						const result = res.result.split("?")[1];
						this.scan_result = result;
						this.closeBLEConnection();
						this.openBluetoothAdapter();
					},
					fail: (err) => {
						// 如果失败返回空
					}
				});
			},
			/**
			 * 	断开蓝牙连接
			 */
			async closeBLEConnection(OBJECT) {
				try {
					const state = uni.getStorageSync('bluetoothAdapterState');
					if (state) {
						console.log("===断开连接操作===");
						uni.removeStorageSync('bluetoothAdapterState');
						await uni.closeBLEConnection({
							deviceId: this.deviceId,
							success(res) {
								console.log("===蓝牙已断开===", res)
							}
						})

					}
				} catch (e) {
					// error
				}
				// 关闭蓝牙特征值的监听
				wx.offBLECharacteristicValueChange();
			},
			/**
			 * 初始化蓝牙设备
			 */
			openBluetoothAdapter() {
				const that = this;
				console.log("初始化log_scan_result", this.scan_result);
				uni.openBluetoothAdapter({
					success: e => {
						try {
							uni.setStorageSync('bluetoothAdapterState', true);
						} catch (e) {
							// error
						}
						console.log('初始化蓝牙成功:' + JSON.stringify(e));
					},
					fail: e => {
						try {
							uni.setStorageSync('bluetoothAdapterState', false);
						} catch (err) {
							// error
						}
						console.log(e)
						console.log('初始化蓝牙失败,错误码:' + (e.errCode || e.errMsg));
					},
					complete: () => {
						wx.offBluetoothAdapterStateChange();
						// 语法将结果res传入到handleBluetoothAdapterStateChange方法中
						wx.onBluetoothAdapterStateChange(this.handleBluetoothAdapterStateChange);

						/** 监听蓝牙连接 */
						// console.log('【监听蓝牙连接...】')
						wx.offBLEConnectionStateChange();
						wx.onBLEConnectionStateChange(this.handleBLEConnectionStateChange);

						/** 开始搜索附近设备 */
						this.onDevicesDiscovery()
					}
				});
			},
			/**
			 * 蓝牙适配器状态改变(例如手动关闭蓝牙)
			 */
			async handleBluetoothAdapterStateChange(res) {
				console.log("BLE适配器发生变化", res, this.scan_result);
				// available 蓝牙适配器是否可用
				// discovering 蓝牙适配器是否处于搜索状态
				const {
					available
				} = res
				const originState = wx.getStorageSync('bluetoothAdapterState')
				wx.setStorageSync('bluetoothAdapterState', available)
				if (!available) {
					this.offDevicesDiscovery()
					uni.showToast({
						title: '请打开手机蓝牙',
						icon: "error",
						duration: 2000
					});
				} else if (!originState) {
					this.onDevicesDiscovery();
				}
			},
			/** 开启搜索附近设备 */
			onDevicesDiscovery() {
				console.log('【开始搜索附近设备...】')
				if (wx.getStorageSync('bluetoothAdapterState')) {
					wx.startBluetoothDevicesDiscovery({
						allowDuplicatesKey: true, // 重复上报发现设备
						powerLevel: 'height',
						interval: 1000,
						success: () => {
							// this._deviceIdsList = []
							// this.setData({
							// 	devicesList: []
							// })
							/** 发现设备 */
							wx.onBluetoothDeviceFound(this.handleFoundBluetoothDevices)
							/** 超时关闭搜索 */
							this._discoveryTimer = setTimeout(() => {
								this.offDevicesDiscovery();
							}, this._discoveryTimeout)
						},
						fail: err => {
							console.error(err)
						}
					})
				}
			},
			/**
			 * 搜索附近设备回调
			 */
			handleFoundBluetoothDevices({
				devices
			}) {
				console.log("发现的设备列表devices", devices, this.scan_result);
				for (let item of devices) {
					if (this.scan_result == item.localName) {
						// 保存在全局变量中
						this.connectDevice = item;
						this.offDevicesDiscovery();
						console.log("找到设备", item, this.scan_result);
						if (!this.connected && this.connectDetermine(item.localName) && wx.getStorageSync(
								'bluetoothAdapterState')) {
							console.log("==开始连接==", item.localName);
							this.createBLEConnection();
						} else {
							console.log("校验失败,不给予连接:", app.connected, wx.getStorageSync(
								'bluetoothAdapterState'));
						}
					}
				}
			},
			/**
			 * 连接低功耗蓝牙(连接开始)
			 */
			async createBLEConnection() {
				let that = this;
				let deviceId = this.deviceId;
				// 弹窗
				uni.showToast({
					title: '连接蓝牙中...',
					icon: 'loading',
					duration: 2000
				});
				await uni.createBLEConnection({
					deviceId,
					success: res => {
						console.log("createBLEConnection连接蓝牙成功", res);
						uni.hideLoading();
						uni.showToast({
							title: '连接成功',
							icon: 'success',
							duration: 1500
						});
						// this.getSystemInfo();
						this.setMTU();

						setTimeout(() => {
							// 订阅特征值
							this.getBLESC();
						}, 500)

					},
					fail: e => {
						let res = JSON.stringify(e);
						console.log('连接低功耗蓝牙失败,错误码:' + res);
						// 表示已经连接,不能再次连接的错误提示
						if (res.errCode == -1 && res.errno == 1509007) {
							app.connected = true;
						}
					}
				});
			},
			/**
			 * 获取服务(Services)和特征值(Characteristics)
			 * 必须的一步:IOS要调用特征值之后才能监听 notifyBLECharacteristicValueChange,否则会报错(找不到服务/特征值)
			 */
			getBLESC() {
				const that = this;
				console.log("====进入getBLESC====", this.deviceId, this.HC02ServiceUUID);
				uni.getBLEDeviceServices({
					// 这里的 deviceId 需要已经通过 createBLEConnection 与对应设备建立链接
					deviceId: this.deviceId,
					success(res) {
						console.log('获取服务类别device services:', res.services)
					},
					fail(e) {
						console.log('getBLEDeviceServices失败', e);
					}
				})
				uni.getBLEDeviceCharacteristics({
					// 这里的 deviceId 需要已经通过 createBLEConnection 与对应设备建立链接
					deviceId: this.deviceId,
					// 这里的 serviceId 需要在 getBLEDeviceServices 接口中获取
					serviceId: this.HC02ServiceUUID,
					success(res) {
						console.log('获取特征值device getBLEDeviceCharacteristics:', res
							.characteristics)
						that.notifyBLECharacteristicValueChange();
					},
					fail(e) {
						console.log('getBLEDeviceCharacteristics失败', e);
						that.getBLESC();
					}
				})
			},
			/**
			 * 订阅操作成功后需要设备主动更新特征值的 value,才会触发 uni.onBLECharacteristicValueChange 回调。
			 */
			async notifyBLECharacteristicValueChange() {
				await uni.notifyBLECharacteristicValueChange({
					state: true, // 启用 notify 功能
					// 这里的 deviceId 需要已经通过 createBLEConnection 与对应设备建立链接
					deviceId: this.deviceId,
					// 固定写死
					serviceId: this.HC02ServiceUUID,
					// 固定写死
					characteristicId: this.HC02CharacteristicNotifyUUID,
					success: (res) => {
						console.log('notifyBLECharacteristicValueChange执行 success:' + res.errMsg);
						onBLECharacteristicValueChange();
					},
					fail: (err) => {
					}
				});
			},
			onBLECharacteristicValueChange(){
			console.log("==========调用监听蓝牙======");
				uni.onBLECharacteristicValueChange(function(res) {
					console.log("==========在Send方法收到蓝牙信息======", res);})
	},
	
}

建议

还是参考资料中的源码吧,我写的毕竟是定制需求,并非适合所有人。附链接:
微信小程序源码

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/514039.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Pycharm+Neo4j红楼梦人物关系图谱

欢迎来到我的主页~【蜡笔小新..】 本篇收录于专栏【Python】 如果对你有帮助&#xff0c;希望点赞收藏加关注啦~ 目录 前言 neo4j基础知识 Pycharm及代码实现 py2neo 数据集获取 代码介绍 前言 Python实验课时&#xff0c;老师提到用知识图谱构建红楼梦的人物关系图&…

实战webSocket压测(二)jmeter配置webSocket连接

背景 我们可以通过Jmeter添加插件实现webSocket脚本编写。WebSocket的插件较多&#xff0c;我选择以WebSocket Samplers by Peter Doornbosch为例来进行配置。 步骤1、WebSocket Samplers插件安装 下载地址&#xff1a;JMeter WebSocket Samplers&#xff0c;建议下载最新版本…

如何在pgAdmin中用替换的值更新jsonb列?(二)

上一篇提到怎么替换jsonb&#xff0c;链接如下&#xff1a; 如何在pgAdmin中用替换的值更新jsonb列&#xff1f;-CSDN博客 那么当jsonb嵌套jsonb应该怎么替换呢&#xff1f;像这样&#xff0c;类型依然是jsonb&#xff0c;只不过嵌套一层&#xff0c;JsonData&#xff1a;&qu…

C++ //练习 11.9 定义一个map,将单词与一个行号的list关联,list中保存的是单词所出现的行号。

C Primer&#xff08;第5版&#xff09; 练习 11.9 练习 11.9 定义一个map&#xff0c;将单词与一个行号的list关联&#xff0c;list中保存的是单词所出现的行号。 环境&#xff1a;Linux Ubuntu&#xff08;云服务器&#xff09; 工具&#xff1a;vim 代码块 /***********…

九河云:在AWS上实现跨region VPC互联

如何跨region实现不同VPC之间的对等链接&#xff1f;九河云为您介绍AWS跨region连接方案。 说明&#xff1a;VPC-A位于弗吉尼亚region&#xff0c;VPC-B位于俄勒冈region 本文将在同一账户的弗吉尼亚和俄勒冈VPC中各启用一台EC2&#xff08;本文已提前创建好VPC、EC2等资源&am…

hive的使用(本地数据上传到idea)

1.首先第一步是先启动hive&#xff0c;hive的启动指令如下 nohup hiveserver2 & 2.然后我们进入idea中 这里我们使用的是idea里的Apache Hive的插件&#xff0c;进行配置&#xff0c;等我们跟moba连接好后&#xff0c;就可以进行数据的导入了。 hive的sql和mysql里的sql语…

WPS二次开发系列:以自动播放模式打开PPT文档

在前面文章中 WPS SDK打开文档并实现保存回传 介绍了如何使用WPS SDK打开文档&#xff0c;那么我们是否能够实现在打开WPS 文档的时候能够传递一些参数来控制打开文档的行为呢&#xff0c;经过研究WPS SDK相关文档和API&#xff0c;最终实现了 以自动播放方式打开PPT文档功能。…

LeetCode-146. LRU 缓存【设计 哈希表 链表 双向链表】

LeetCode-146. LRU 缓存【设计 哈希表 链表 双向链表】 题目描述&#xff1a;解题思路一&#xff1a;双向链表&#xff0c;函数 get 和 put 必须以 O(1) 的平均时间复杂度运行。一张图&#xff1a;知识点__slots__ 解题思路二&#xff1a;0解题思路三&#xff1a;0 题目描述&am…

【Web】2024红明谷CTF初赛个人wp(2/4)

目录 ezphp playground 时间原因只打了2个小时&#xff0c;出了2道&#xff0c;简单记录一下 ezphp 参考文章 PHP filter chains: file read from error-based oracle https://github.com/synacktiv/php_filter_chains_oracle_exploit 用上面的脚本爆出部分源码&#xff…

uniapp开发app使用谷歌地图(ios跟安卓)

前提条件&#xff1a; 谷歌地图需要翻墙&#xff0c;否则无法加载 谷歌地图说明 文档地址&#xff1a;概览 | Maps JavaScript API | Google for Developers 设置地图语言 <script asyncsrc"https://maps.googleapis.com/maps/api/js?keyYOUR_API_KEY&lang…

HarmonyOS NEXT应用开发之ForEach:循环渲染

ForEach接口基于数组类型数据来进行循环渲染&#xff0c;需要与容器组件配合使用&#xff0c;且接口返回的组件应当是允许包含在ForEach父容器组件中的子组件。例如&#xff0c;ListItem组件要求ForEach的父容器组件必须为 List组件 。 说明&#xff1a; 从API version 9开始&a…

vue3+echarts:echarts地图打点显示的样式

colorStops是打点的颜色和呼吸灯、label为show是打点是否显示数据、rich里cnNum是自定义的过滤模板用来改写显示数据的样式 series: [{type: "effectScatter",coordinateSystem: "geo",rippleEffect: {brushType: "stroke",},showEffectOn: &quo…

外链工具源码版V2

请将zip文件全部解压缩即可访问&#xff01; 源码全部开源&#xff0c;支持上传二级目录访问 #已更新增加大量高质量外链&#xff08;若需要增加修改其他外链请打开txt文件&#xff09; #修复优化页面端 源码下载地址&#xff1a;外链工具源码版V2

记录一次官网访问很慢的情况

客户查看云监控,带宽未超限,客户取的是1分钟的原生值,也就是1分钟也是个平均值。 但是客户的原始值&#xff0c;其实就是1分钟内的平均值。所以客户的瞬时超限&#xff0c;其实是看不出来的。但是后端同事从实时监控里面可以看到超限的情况。 客户升带宽后&#xff0c; 发现还…

二维动画制作软件 Animate 2024 for mac激活版

Animate 2024 for Mac是一款功能强大的二维动画制作软件&#xff0c;专为Mac用户打造。它提供了丰富的动画编辑功能&#xff0c;使用户能够轻松创建出生动逼真的动画作品。无论是短片、广告还是游戏等应用领域&#xff0c;Animate 2024都能发挥出出色的表现。 软件下载&#xf…

Vue和FastAPI实现前后端分离

前言 近期接触了一些开源大模型应用服务&#xff0c;发现很多用的都是FastAPI web框架&#xff0c;于是乎研究了一下它的优势&#xff0c;印象最深有两个&#xff1a;一个是它的异步处理性能比较好&#xff0c;二是它可以类似java swagger的API交互文档&#xff0c;这个对应前…

微服务连接不上rabbitmq解决

1.把端口port: 15672改成port&#xff1a;5672 2&#xff1a;virtual-host: my_vhost一定对应上

VSCode安装及Python、Jupyter插件安装使用

VSCode 介绍 Visual Studio Code&#xff08;简称VSCode&#xff09;是一个由微软开发的免费、开源的代码编辑器。VSCode是一个轻量级但是非常强大的代码编辑器&#xff0c;它支持多种编程语言&#xff08;如C,C#&#xff0c;Java&#xff0c;Python&#xff0c;PHP&#xff0…

云存储中常用的相同子策略的高效、安全的基于属性的访问控制的论文阅读

参考文献为2022年发表的Efficient and Secure Attribute-Based Access Control With Identical Sub-Policies Frequently Used in Cloud Storage 动机 ABE是实现在云存储中一种很好的访问控制手段&#xff0c;但是其本身的计算开销导致在实际场景中应用收到限制。本论文研究了…

Raven:一款功能强大的CICD安全分析工具

关于Raven Raven是一款功能强大的CI/CD安全分析工具&#xff0c;该工具旨在帮助广大研究人员对GitHub Actions CI工作流执行大规模安全扫描&#xff0c;并将发现的数据解析并存储到Neo4j数据库中。 Raven&#xff0c;全称为Risk Analysis and Vulnerability Enumeration for C…