Uni-App开发BLE低功耗蓝牙流程

2023-11-08

Uni-App开发BLE低功耗蓝牙步骤

示例文件已上传gitee:https://gitee.com/yan_rookie/uniapp_bluetooth.git
如果对你有记得点个赞哦!

注:微信小程序同样适用,只需吧前缀uni.修改为wx.

最全总结,看此一篇就够!!!!

开发蓝牙很多小伙伴刚开始一头雾水,不知道从何下手,网上可以查的资料少之又少,所以写这篇文章来总结一下BLE低功耗蓝牙开发流程,话不多说,仔细看!!

  1. 初始化蓝牙 uni.openBluetoothAdapter(OBJECT)
  2. 开始搜索蓝牙设备 uni.startBluetoothDevicesDiscovery(OBJECT)
  3. 发现外围设备 uni.onBluetoothDeviceFound(CALLBACK)
  4. 停止搜寻附近的蓝牙外围设备 uni.stopBluetoothDevicesDiscovery(OBJECT)
  5. 连接低功耗蓝牙设备 uni.createBLEConnection(OBJECT)
  6. 获取蓝牙设备所有服务 uni.getBLEDeviceServices(OBJECT)
  7. 获取蓝牙特征 uni.getBLEDeviceCharacteristics(OBJECT)
  8. 启用蓝牙设备特征值变化时的 notify 功能 uni.notifyBLECharacteristicValueChange(OBJECT)
  9. 监听低功耗蓝牙设备的特征值变化 uni.onBLECharacteristicValueChange(CALLBACK)
  10. 写入蓝牙 uni.writeBLECharacteristicValue(OBJECT)

基本使用步骤我们总结完了,那么接下来就介绍怎么使用

1.初始化蓝牙
这里主要目的就是检测一下手机蓝牙是否打开

uni.openBluetoothAdapter({
	success:(res)=> { //已打开
		uni.getBluetoothAdapterState({//蓝牙的匹配状态
			success:(res1)=>{
			console.log(res1,'“本机设备的蓝牙已打开”')	
			// 开始搜索蓝牙设备
			this.startBluetoothDeviceDiscovery()
			},
			fail(error) {
				uni.showToast({icon:'none',title: '查看手机蓝牙是否打开'	
			}
		});
		
	},
	fail:err=>{ //未打开 
		uni.showToast({icon:'none',title: '查看手机蓝牙是否打开'});
	}
})

2.开始搜索蓝牙设备

// 开始搜索蓝牙设备
startBluetoothDeviceDiscovery(){
	uni.startBluetoothDevicesDiscovery({
		success: (res) => {
			console.log('startBluetoothDevicesDiscovery success', res)
			// 发现外围设备
			this.onBluetoothDeviceFound()
		},fail:err=>{
			console.log(err,'错误信息')
		}
	})
}

3.发现外围设备
到这个位置就会搜索到设备了
这个地方重点就是获取到了 deviceId 这是连接蓝牙的重要ID,存起来到data里面后面我们会用到

// 发现外围设备
onBluetoothDeviceFound() {
	// console.log("zhixing")
	uni.onBluetoothDeviceFound((res) => {
		// console.log(res)
		// ["name", "deviceId"]
		// 吧搜索到的设备存储起来,方便我们在页面上展示
		if(this.list.indexOf(res.devices[0].deviceId)==-1){
			this.list.push(res.devices[0].deviceId)
		}
	})
}

4.点击选择自己需要连接的设备
在上面搜索到设备之后我们把设备存储到list里面,方便我们在页面展示,然后点击选择我们要连接的设备,吧deviceId传进来,保存起来,说明我们连接的是这个设备,下面还需要用到,我们存到data里面就行

//选择设备连接吧deviceId传进来
createBLEConnection(deviceId){
	let thit = this
	//data里面建立一个deviceId,存储起来
	this.deviceId = deviceId
	//连接蓝牙
	uni.createBLEConnection({
	// 这里的 deviceId 需要已经通过 createBLEConnection 与对应设备建立链接
	  deviceId:this.deviceId,
	  success(res) {
	  	//防止在这里面取不到this,古在外面用thit存储了this
		thit.stopBluetoothDevicesDiscovery()
		console.log(res)
		console.log("蓝牙连接成功")
		
	  },fail(res) {
		console.log("蓝牙连接失败",res)
	  }
	})
},

5.当我们连接成功的时候,一定要停止搜索外围设备,停止,停止,停止

// 停止搜寻蓝牙设备
stopBluetoothDevicesDiscovery(){ 
	uni.stopBluetoothDevicesDiscovery({ 
		success: e => {
			this.loading = false
			console.log('停止搜索蓝牙设备:' + e.errMsg); 
		},
		fail: e => {
			console.log('停止搜索蓝牙设备失败,错误码:' + e.errCode);
		}
	});
}

6.获取蓝牙设备所有服务
getBLEDeviceServices这个方法里面填一个参数deviceId就是我们刚刚获取到的
成功就会获取到了services uuid 同理也存储起来
等下来获取特征值

注:这个地方使用了setTimeout等待一秒种再去获取,直接获取我们可能出现获取不到的情况

//获取蓝牙的所有服务
getBLEDeviceServices(){
	setTimeout(()=>{
		uni.getBLEDeviceServices({
		  // 这里的 deviceId 需要已经通过 createBLEConnection 与对应设备建立链接
		  deviceId:this.deviceId,
		  success:(res)=>{
			// console.log("成功",res)
			console.log('device services:', res)
			//这里会获取到好多个services  uuid  我们只存储我们需要用到的就行,这个uuid一般硬件厂家会给我们提供
			res.services.forEach((item)=>{
				if(item.uuid.indexOf("AE00")!=-1){
					this.serviceId = item.uuid;
					//进入特征
					this.getBLEDeviceCharacteristics()
				}
			})
		  }
		})
	},1000)
},

7.获取蓝牙特征
这里需要穿2个参数了,就是上面的两个id,分别是deviceId、services
这里获取的特征值的uuid才是我们真正需要操作的uuid

//获取蓝牙特征
getBLEDeviceCharacteristics(){
	console.log("进入特征");
	setTimeout(()=>{
		uni.getBLEDeviceCharacteristics({
		  // 这里的 deviceId 需要已经通过 createBLEConnection 与对应设备建立链接
		  deviceId:this.deviceId,
		  // 这里的 serviceId 需要在 getBLEDeviceServices 接口中获取
		  serviceId:this.serviceId,
		  success:(res)=>{
			console.log(res,'特征getBLEDeviceCharacteristics')
			this.characteristics = res.characteristics
			console.log(this.characteristics)
			//循环所有的uuid
			
			// for(let i=0;i<3;i++){
			// 	this.notifyBLECharacteristicValueChange(res.characteristics[i].uuid)
			// 	console.log(res.characteristics[i].uuid)
			// 	console.log(i,'i')
			// }
			
			res.characteristics.forEach((item)=>{
				if(item.uuid.indexOf("AE02") != -1){
					console.log('characteristicId:', item.uuid)
					//利用传参的形势传给下面的notify,这里的uuid如果都需要用到,就不用做判断了,建议使用setTimeout进行间隔性的调用此方法
					this.notifyBLECharacteristicValueChange(item.uuid)
				}
			})
			
		  },
		  fail:(res)=>{
			console.log(res)
		  }
		})
	},1000)
},

8.启用蓝牙设备特征值变化时的 notify 功能
当我们启动notify功能,才能知道我们当前蓝牙的读写状态,
到这里蓝牙连接基本就完成了,然后就是需要自己用到读写操作

“properties”: {
“read”: true, //读
“write”: true, //写
“notify”: true, //广播
“indicate”: false
}

// 启用 notify 功能
notifyBLECharacteristicValueChange(characteristicId){
	console.log(characteristicId,'characteristicId')
	uni.notifyBLECharacteristicValueChange({
	  state: true, // 启用 notify 功能
	  // 这里的 deviceId 需要已经通过 createBLEConnection 与对应设备建立链接
	  deviceId:this.deviceId,
	  // 这里的 serviceId 需要在 getBLEDeviceServices 接口中获取
	  serviceId:this.serviceId,
	  // 这里的 characteristicId 需要在 getBLEDeviceCharacteristics 接口中获取
	  characteristicId:characteristicId,
	  success:(res)=> {
		console.log(res)
		// console.log(this.characteristicId)
		console.log('notifyBLECharacteristicValueChange success', res.errMsg)

	  },
	  fail:(res)=> {
		console.log('notifyBLECharacteristicValueChange success2', res.errMsg)
	  }
	})
	
},

9.再多介绍一个采坑的记录
那就是监听变化这个方法的使用
最开始我是写在了8.启用 notify 功能里面,可我发现只能监听一个,后来我就吧这个监听方法放在了6.获取蓝牙设备所有服务,这个地方可以监听到所有特征值的变化,所以我们的代码改进一下
就成了下面这段,读取成功就会在这个地方监听输出

//获取蓝牙的所有服务
getBLEDeviceServices(){
	setTimeout(()=>{
		uni.getBLEDeviceServices({
		  // 这里的 deviceId 需要已经通过 createBLEConnection 与对应设备建立链接
		  deviceId:this.deviceId,
		  success:(res)=>{
			// console.log("成功",res)
			console.log('device services:', res)
			res.services.forEach((item)=>{
				if(item.uuid.indexOf("AE00")!=-1){
					// this.serviceId = item.uuid;
					//存储到状态
					this.$store.commit("upserviceId",item.uuid)
					console.log(this.serviceId)
					// 这里获取回调,读取成功就的值就会在这个地方接收到!!!
					uni.onBLECharacteristicValueChange((res)=>{
						console.log("监听成功",res)
						//res.value是ArrayBuffer类型的,官方给了一个方法转16进制,我们再进行操作
						this.shiliu = this.ab2hex(res.value)
						
					})
					
					this.getBLEDeviceCharacteristics()
				}
			})
		  }
		})
	},1000)
}

到这里基本上就完成了蓝牙的连接
自己需要执行读写操作,就在下面读写就行,如果想默认读写操作,就可以在 8.启用 notify 功能 里面进行操作

追加更新

10.有小伙伴咨询不会写入数据到蓝牙,源码附上!

注意:写入一定要转换为ArrayBuffer类型

//获取蓝牙的所有服务
writeBLECharacteristicValue(e){
	// 转换成ArrayBuffer类型
	var typedArray = new Uint8Array(e.match(/[\da-f]{2}/gi).map(function (h) {
	return parseInt(h, 16)
	}))
	
	var buffer = typedArray.buffer
	uni.writeBLECharacteristicValue({
	  // 这里的 deviceId 需要在 getBluetoothDevices 或 onBluetoothDeviceFound 接口中获取
	  deviceId:this.deviceId,
	  // 这里的 serviceId 需要在 getBLEDeviceServices 接口中获取
	  serviceId:this.serviceId,
	  // 这里的 characteristicId 需要在 getBLEDeviceCharacteristics 接口中获取
	  characteristicId:this.characteristics[0].uuid,
	  // 这里的value是ArrayBuffer类型
	  value: buffer,
	  success(res) {
		// console.log(res)
		// console.log('writeBLECharacteristicValue success', res.errMsg)
		console.log("写入成功");		
	  },
	  fail(res) {
		console.log("写入失败")
		// 重新写入
		setTimeout(()=>{
			thit.writeBLECharacteristicValue(e)
		},100)
	  }
	})
}

就到这里了,如果对你有帮助,请点击喜欢

转载本文请备注地址!!!
转载本文请备注地址!!!
转载本文请备注地址!!!

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Uni-App开发BLE低功耗蓝牙流程 的相关文章

  • 如何在 Vuejs 中加载 Pixi 实例?

    我正在 VueJS 组件中学习 PixiJS 如下所示Pixi教程 https github com kittykatattack learningPixi我控制台显示此错误 vue runtime esm js 2b0e 619 Vue
  • Nuxt JS 插件是否可以只运行一次?

    我有几个 VueX 操作 仅在服务器上运行 并从nuxtServerInit 它们向外部服务发出 HTTP 请求 这会减慢 TTFB 的速度 我想实现一个缓存插件 可以从 Redis 存储和检索值 目的是避免在每个请求的操作中发出 HTTP
  • Vuejs2 Modal 与 vue-router 中的路线

    我正在尝试使用模态创建一条路由 当您使用路由器链接访问此路由器路径时 会在当前页面上方显示一个模态 或者如果我直接从 url 访问 则会出现上面带有模态的索引 例如 我在http localhost 个人资料 1 http localhos
  • Vue模板-渲染HTML特殊字符代码

    如何在我的 Vue 模板中完全渲染 HTML 特殊字符代码 例如我有这个 JSON 数据 id post91 slug null title Breakfast 038 Tea 我怎样才能转换Breakfast 038 Tea to Bre
  • 将 VueJs 组件添加到 Django 模板中

    我正在开发一个 Django 网站 我希望将一些 Vue 组件 散布 到 Django 渲染的模板中 我正在单个存储库中工作 并使用 webpack 设置来创建我在 Django 模板中使用的 style js 包 我正在努力让功能按照我想
  • Vue.js 动态图像路径未加载

    我试图在单个文件组件中动态加载图像 但收到错误消息 指出无法找到该模块 我想我正在尝试做同样的事情这个帖子 https stackoverflow com questions 40491506 vue js dynamic images n
  • 如何在 vuejs 中防止/停止点击传播

    我有一个递归列表 树 每个元素都有一个 click sayHello el id 现在的问题是 因为它是一个嵌套列表 例如 list element 0 01 list el 1 01 list el 2 01 list el 1 02 l
  • 如何使用vue.js获取点击时按钮的值

    我在页面上有几个按钮 它们连接到相同的方法webcamSendRequestButton
  • 在 ES6 中使用 import 和 require 的正确方法是什么?

    关于 import 和 require 及其差异有多个问题 像这些 JavaScript 中的 import 和 require 有什么区别 https stackoverflow com questions 51373933 what i
  • Vue 3:使用渲染函数将所有项目包装在一个自定义组件中

    我正在尝试建立自己的sortable成分 我想将项目列表传递到它的默认插槽 然后 可排序组件应该用自定义包装所有传递的项目v draggable成分
  • 可以用vue-chartjs打印图表吗?

    我正在使用 vue chartjs 在网络应用程序上渲染图表 我知道如果您使用原始版本 您可以打印图表library https canvasjs com docs charts methods chart print 但是我不知道如何使用
  • 如何在 Atom 中启用 .vue 文件的语法突出显示?

    我开始使用 Vue js 我遇到的第一个问题是我的 IDE Atom 无法美化我的 vue 文件 这一切都只是白色的文字 如何让 Atom 正确突出显示 vue 文件 语言 vue https atom io packages langua
  • 如何同时模拟Pinia和vue-i18n?

    我正在使用 Vue 3 的 Composition API 如下所示 store ts import ref Ref from vue import defineStore from pinia export const useStore
  • 不使用Vue可以使用Vuex吗? (Vuex 服务器端?)

    Vuex 抱怨如果不调用 Vue use Vuex 就无法创建新的 store 实例 虽然这通常没问题 但我正在摆弄使用同一商店编写后端 前端的想法 有人知道答案吗 Thanks TL DR 你可以在 Node 中完美使用 Vuex 无需浏
  • 未向导出的模块提供此上下文

    我对问题的提出感到不满意 受到鼓励提出改进建议 另外 请记住 由于无知 无知导致烦恼 我对问题的诊断可能有缺陷 对于那个很抱歉 In 这个答案 https stackoverflow com a 40893583 1525840建议使用th
  • 在新窗口中打开 VueJS 组件

    我有一个只有一页的基本 VueJS 应用程序 它不是 SPA 而且我不使用 vue router 我想实现一个按钮 单击该按钮时会使用我的 Vue 组件之一的内容执行 window open 函数 查看来自的文档window open ht
  • 个人Vue 3组件包缺少模板或渲染函数

    我最近将自己的 Vue 3 组件上传到 NPM 以供其他人使用 当在其他项目中使用它时 它会发出以下警告 Vue warn Component is missing template or render function at
  • Vue中有类似React.Fragment的东西吗?

    在 React 中我可以做这样的事情 parent component export default return div div 1 div div
  • VueJS 中数据无法正确显示

    我的 VueJS 代码有一个小问题 在 输出 压缩的 GS1 数字链接 URI 部分中 When there is no result it should have nothing display like this I have remo
  • 在渲染组件之前从 api 获取数据

    我在渲染页面之前发送 2 个 api 请求 const Profile template profile attributes null photos data function return attributes Profile attr

随机推荐

  • Centos/Linux在线环境下载安装包,到离线环境安装,并解决依赖问题

    在线环境下载rpm包 我们以yum utils包为例 在线环境使用下面的代码安装 sudo yum install y yum utils 离线环境需要的是安装包 因此下载yum utils的安装包的代码 mkdir ypm packet
  • 开关电源环路稳定性分析(01)-Buck变换器

    大家好 这里是大话硬件 说到开关电源不得不提的就是开关的环路稳定性 但是这一块目前用的DC DC芯片 很多厂家在芯片内部都已经做好了 所以对于使用的人来说 即使不太关注环路的稳定 按照手册中推荐的值设计产品也能正常使用 当然 仅仅是按照手册
  • 可充电点电池和不可充电电池区分?

    看到网上很多人都在问 碳性电池能充电吗 回答很明确 不可以 我们生活中使用的5号电池和7号电池分为可充电和不可充电两种 不可充电的5号电池和7号电池有碳性电池和碱性电池 碳性电池是一次电池 即干电池 是不能充电的 碳性电池价格比碱性电池便宜
  • Unity导入package简单操作流程

    Unity导入package简单操作流程 前言 在Unity 实际开发工作中 需要将一些现成的程序包或者插件导入到自己的工厂里 方便自己使用其中的一些现成的功能 方便自己开发 节约工作时间 这篇博客简单介绍下Unity导入package简单
  • C++ 判断磁盘是否为可移动磁盘

    传入参数path F bool isUsbDrv const wchar t path include
  • 数据库恢复技术

    数据库恢复技术和并发控制技术 事务 故障 1 事物内部的故障 2 系统故障 3 介质故障 4 计算机病毒 恢复的实现技术 1 数据存储 2 登录日志文件 各故障对应的恢复策略 1 事物故障的恢复 2 系统故障的恢复 3 介质故障的恢复 检查
  • 【华为机试刷题笔记】HJ14-字符串排序

    题目描述 给定 n 个字符串 请对 n 个字符串按照字典序排列 数据范围 1 n 1000 1 leq n leq 1000 1 n 1000 字符串长度满足
  • uniapp map 请求接口之后数据不渲染问题

    uniapp map 请求接口之后数据不渲染问题 我先说我遇到的问题 我使用uniapp 的 map 组件 组件所有绑定数据都有一个初始化 之后在 mounted 中请求服务器数据 不过在 map 组件里面没有渲染请求到的数据 使用 set
  • 千兆网线做法和网线接法注意事项

    据市场调查 目前千兆网线已经很 普遍了 但很多朋友对千兆网线水晶头接法还不是很了解 在制作网线的过程中会遇到各式各样的问题 有时会造成无法打开网页 在动手之前 我们要对于网线的制作有一个正确的认识 从而制作出我们需要的网线 网线由一定距离长
  • 区块链系列-----加密算法汇总

    背景 区块链背景下 对密码学技术要求需要有很深的研究 笔者以java语言为例 搜罗各种加密算法的相关使用 github地址 https github com niyuelin1990 mycrypto 简介 搜罗各种加密算法 电子邮件传输算
  • docker使用指南

    1 安装docker 使用如下命令可以安装docker 安装成功后docker version可以查看到docker的client和server信息 sudo apt install docker docker io y 为普通用户添加权限
  • mysql json类型最大长度限制_MySQL json 数据类型

    必须要5 7以上版本才能使用 写在开头 mysql json 的功能很强大 只是用来当一个储存数据的字段 就没什么意义了 使用proto做交互的话 只要JSON 写得好 用proro Unmarshal 就可以很方便的转换类型 可以精简很多
  • github 项目的基本结构以及git的使用方法

    github 项目的基本结构以及git的使用方法 介绍 根据README md 一般都在下面 阅读规则 每个团队根据队伍内部技术人员配置选择课题 课题在docs 目录下 对于docs 下非本组选择的课题文件不要进行任意修改 docs 下课题
  • 转onnx包问题

    pip install onnx 1 7 0 i https pypi tuna tsinghua edu cn simple 其实这一步已经可以了 pip install coremltools YOLOv5的pytorch模型文件转换为
  • redis的事务和watch机制

    这里写目录标题 第一章 redis事务和watch机制 1 1 redis事务 事务的三大命令 语法 开启事务 multi 语法 执行事务 exec 语法 取消事务 discard 1 2 redis事务的错误和回滚的情况 1 3 watc
  • Es6数组新增方法与字符串新增方法和新增数据类型

    1 数组新增方法 map方法 将数组中每一个元素依次取出 进行遍历 返回一个新的数组 let movies id 1 name 大话西游 author xxxx imgUrl http xxx douban com 1 jpg id 2 n
  • AST-解混淆 赋值语句嵌套三目表达式的优化

    处理前 0x4ae6ff 0x41bc28 4957228979 650037875 处理后 0x41bc28 0x4ae6ff 4957228979 0x4ae6ff 650037875 通用插件编写规则 const TransCondi
  • 2018年LeetCode高频算法面试题刷题笔记——搜索二维矩阵 II(开始之前)

    1 解答之前的碎碎念 这个题一开始我想的很简单 想着是个二维的二分查找 然后提交代码 果不其然出错了 因为并不能保证第i 1行的每个元素都大于第i行 不过想到了递归 也算是有点进步 虽然最后用递归写了一个没有通过 但是自己在vs里测试的没问
  • 论文快速回顾笔记 —— Supressing Uncertainties for Large-Scale FER

    前言 这是之前因为做项目而读过的一篇CVPR2020论文 有些细节还是挺有意思的 最近回顾一下 顺便做下笔记 以供后续查阅 Paper Suppressing Uncertainties for Large Scale Facial Exp
  • Uni-App开发BLE低功耗蓝牙流程

    Uni App开发BLE低功耗蓝牙步骤 示例文件已上传gitee https gitee com yan rookie uniapp bluetooth git 如果对你有记得点个赞哦 注 微信小程序同样适用 只需吧前缀uni 修改为wx