uniapp微信小程序蓝牙连接与设备数据对接
蓝牙连接并通信方法封装大致步骤。
- 初始化蓝牙并搜索;
- 获取并启用service服务;
- 数据读取和监听设备返回数据
需要使用uniapp官方提供api:
// 关闭蓝牙
uni.closeBluetoothAdapter({})
// 打开蓝牙
uni.openBluetoothAdapter({})
// 搜索附近的蓝牙
uni.startBluetoothDevicesDiscovery({})
// 停止搜索
uni.stopBluetoothDevicesDiscovery({})
// 连接低功耗BLE蓝牙
uni.createBLEConnection({})
// 获取蓝牙设备所有服务(service)
uni.getBLEDeviceServices({})
// 获取蓝牙特征值
uni.getBLEDeviceCharacteristics({})
// 启用低功耗蓝牙设备特征值变化时的 notify 功能,订阅特征值
uni.notifyBLECharacteristicValueChange({})
// 监听低功耗蓝牙设备的特征值变化事件
uni.onBLECharacteristicValueChange({})
// 读取低功耗蓝牙设备的特征值的二进制数据值
uni.readBLECharacteristicValue({})
1、开启蓝牙适配器初始化蓝牙模块,获取手机蓝牙是否打开
const getBluetoothState = () => {return new Promise((resolve, reject) => {uni.openBluetoothAdapter({mode: 'central', // 主机模式success: (r) => {console.log("蓝牙初始化成功");// 获取蓝牙的匹配状态uni.getBluetoothAdapterState({success: function(row) {console.log('蓝牙状态:', row.available);if (row.available) {// 蓝牙连接成功,开启蓝牙设备搜索resolve();} else {// 请开启蓝牙uni.showToast({title: "请开启蓝牙",icon: 'none',duration: 2000});reject();}},fail: function(err) {// 请开启蓝牙uni.showToast({title: "请开启蓝牙",icon: 'none',duration: 2000});reject();}})},fail: () => {// 请开启蓝牙uni.showToast({title: "请开启蓝牙",icon: 'none',duration: 2000});reject();}});});
}
2、开启蓝牙设备搜索
const discoveryBluetooth = () => {return new Promise((resolve) => {uni.startBluetoothDevicesDiscovery({success(res) {uni.showLoading({title: "正在搜索设备",icon:"none",duration: 2000});console.log('搜索蓝牙外围设备完成', res)setTimeout(() => {// 监听寻找到的蓝牙设备resolve();}, 2000);}});});
}
3、获取搜索到的设备信息
const getBluetoothDevices = () => {return new Promise((resolve, reject) => {uni.getBluetoothDevices({success(res) {// 过滤掉name为空或者未知设备的设备let devices = res.devices.filter(function(obj) {return obj.name !== "" && obj.name !== "未知设备"});devices && devices.forEach(item => {// 获取指定连接deviceIdif(item.name && item.name.substring(0, 5) === 'aaaa-'){// aaaa-*********蓝牙设备型号,根据需求选择设备型号// item.deviceId;}});},fail: function() {console.log('搜索蓝牙设备失败');reject();},complete: function() {console.log("蓝牙搜索完成");resolve();}});});
}
4、关闭蓝牙搜索
const stopDiscoveryBluetooth = () => {uni.stopBluetoothDevicesDiscovery({success(r) {console.log("停止搜索蓝牙设备", r);}});
};
5、连接蓝牙
const connectBluetooth = () => {return new Promise((resolve, reject) => {uni.createBLEConnection({deviceId: deviceId, // 设备idsuccess() {// 蓝牙连接成功后关闭蓝牙搜索并获取服务idstopDiscoveryBluetooth();resolve();// 获取服务idgetServiceId();},fail() {console.log("蓝牙连接失败");reject();}});});
};
6、获取服务id
const getServiceId = () => {uni.getBLEDeviceServices({deviceId: deviceId,success(res) {console.log("获取服务Id", res)// serviceId固定,获取蓝牙设备某个服务中的所有特征值【读写属性】let model = res.services[0];serviceId = model.uuid;// 调用蓝牙监听和写入功能getCharacteId();},fail(err){console.log('获取服务失败', err);}})
};
7、获取蓝牙低功耗设备某个服务中所有特征
const getCharacteId = () => {uni.getBLEDeviceCharacteristics({deviceId: deviceId, // 蓝牙设备idserviceId: serviceId, // 蓝牙服务UUIDsuccess(res) {console.log('数据监听', res);res.characteristics.forEach(item => {// 003if (item.properties.notify === true) {// 监听notify = item.uuid;}// 002if (item.properties.write === true) {// 写入let writeId = item.uuid;}});},fail(err) {console.log("数据监听失败", err)}})
};
8、监听设备返回数据,启用低功耗蓝牙设备特征值变化时的notify功能
const startNotice = () => {uni.notifyBLECharacteristicValueChange({characteristicId: notify,deviceId: deviceId,serviceId: serviceId,state: true,success(res) {// 监听低功耗蓝牙设备的特征值变化uni.onBLECharacteristicValueChange(result => {console.log("监听低功耗蓝牙设备的特征值变化", result);if (result.value) {console.log('设备返回数据', result.value)}})}});
};
9、向蓝牙设备发送数据
const writeData = (buffer) => {return new Promise((resolve, reject) => {uni.writeBLECharacteristicValue({characteristicId: uni.getStorageSync("writeId"),deviceId: deviceId,serviceId: serviceId,value: buffer,success(res) {console.log("writeBLECharacteristicValue success", res);resolve();},fail(err) {console.log("报错了", err);reject();}});});
};
封装完整方法:
import { TextDecoder } from 'text-encoding-utf-8';
let bluetoothOpen = false; // 手机蓝牙是否打开
let bluetoothConnect = false; // 设备和蓝牙是否连接
let isHaveDevice = false; // 是否查找到设备
let deviceId = null; // 设备id
let serviceId = null; // 服务id
let notify = null; // 监听uuid
let writeId = null; // 写入uuid
/*** 获取手机蓝牙是否打开*/
const getBluetoothState = () => {// 主机模式return new Promise((resolve, reject) => {uni.openBluetoothAdapter({mode: 'central',success: (r) => {console.log("蓝牙初始化成功");// 获取蓝牙的匹配状态uni.getBluetoothAdapterState({success: function(row) {console.log('蓝牙状态:', row.available);if (row.available) {bluetoothOpen = true;resolve();} else {// 请开启蓝牙bluetoothOpen = false;bluetoothConnect = false;reject();}},fail: function(err) {// 请开启蓝牙bluetoothOpen = false;bluetoothConnect = false;reject();}})},fail: () => {// 请开启蓝牙bluetoothOpen = false;bluetoothConnect = false;reject();}});});
};
/*** 开始搜索蓝牙设备*/
const discoveryBluetooth = () => {return new Promise((resolve) => {uni.startBluetoothDevicesDiscovery({success(res) {console.log('搜索蓝牙外围设备完成', res)setTimeout(() => {resolve();}, 2000);}});})
};
// 关闭蓝牙搜索
const stopDiscoveryBluetooth = () => {uni.stopBluetoothDevicesDiscovery({success(r) {console.log("停止搜索蓝牙设备", r);}});
};
/*** 获取搜索到的设备信息*/
const getBluetoothDevices = () => {return new Promise((resolve, reject) => {uni.getBluetoothDevices({success(res) {bluetoothConnect = false;// 过滤掉name为空或者未知设备的设备let devices = res.devices.filter(function(obj) {return obj.name !== "" && obj.name !== "未知设备"});devices && devices.forEach(item => {if(item.name && item.name.substring(0, 5) === 'aaaa-'){deviceId = item.deviceId;}});},fail: function() {console.log('搜索蓝牙设备失败');bluetoothConnect = false;reject();},complete: function() {console.log("蓝牙搜索完成");// 是否具有当前设备if (deviceId) {isHaveDevice = true;} else {isHaveDevice = false;}resolve(isHaveDevice);}});});
}
/*** 连接蓝牙* deviceId 蓝牙设备id*/
const connectBluetooth = () => {return new Promise((resolve, reject) => {uni.createBLEConnection({deviceId: deviceId, // 设备idsuccess() {bluetoothConnect = true;// 蓝牙连接成功后关闭蓝牙搜索stopDiscoveryBluetooth();resolve();// 获取服务idgetServiceId();},fail() {bluetoothConnect = false;console.log("蓝牙连接失败");reject();}});});
};
// 获取服务id
const getServiceId = () => {uni.getBLEDeviceServices({deviceId: deviceId,success(res) {console.log("获取服务Id", res)let model = res.services[0];serviceId = model.uuid;// 调用蓝牙监听和写入功能getCharacteId();}})
};
// 获取蓝牙低功耗设备某个服务中所有特征
const getCharacteId = () => {uni.getBLEDeviceCharacteristics({deviceId: deviceId, // 蓝牙设备idserviceId: serviceId, // 蓝牙服务UUIDsuccess(res) {console.log('数据监听', res);res.characteristics.forEach(item => {// 003if (item.properties.notify === true) {// 监听notify = item.uuid;startNotice();}// 002if (item.properties.write === true) {// 写入let writeId = item.uuid;uni.setStorageSync("writeId", item.uuid);}});},fail(err) {console.log("数据监听失败", err)}})
};
// 启用低功耗蓝牙设备特征值变化时的notify功能
const startNotice = () => {uni.notifyBLECharacteristicValueChange({characteristicId: notify,deviceId: deviceId,serviceId: serviceId,state: true,success(res) {// 监听低功耗蓝牙设备的特征值变化uni.onBLECharacteristicValueChange(result => {console.log("监听低功耗蓝牙设备的特征值变化", result);if (result.value) {let decoder = new TextDecoder('utf-8');let data = decoder.decode(result.value);console.log('帽子返回数据', data)}})}});
};
// 蓝牙发送数据
const writeData = (buffer) => {return new Promise((resolve, reject) => {uni.writeBLECharacteristicValue({characteristicId: uni.getStorageSync("writeId"),deviceId: deviceId,serviceId: serviceId,value: buffer,success(res) {console.log("writeBLECharacteristicValue success", res);resolve();},fail(err) {console.log("报错了", err);reject();}});});
};
export default {getBluetoothState,discoveryBluetooth,stopDiscoveryBluetooth,getBluetoothDevices,connectBluetooth,getServiceId,getCharacteId,startNotice,writeData
};
使用案例:
<template><view class="device_container"></view>
</template><script>import bluetooth from '../bluetooth.js';export default {data() {return {bluetoothStatus: false, // 蓝牙连接状态}},methods: {// 获取蓝牙和设备是否已连接initBluetooth() {let _this = this;// 初始化蓝牙bluetooth.getBluetoothState().then(() => {// 搜索外围蓝牙设备bluetooth.discoveryBluetooth().then(() => {this.discoveryLoading = true;// 获取蓝牙设备bluetooth.getBluetoothDevices().then((isHaveDevice) => {if (isHaveDevice) {// 搜索到指定设备,连接蓝牙bluetooth.connectBluetooth().then(() => {_this.bluetoothStatus = true;}, () => {_this.bluetoothStatus = false;});} else {// 未搜到设备_this.bluetoothStatus = false;}}, () => {// 蓝牙搜索失败_this.bluetoothStatus = false;});});}, () => {// 未开启蓝牙_this.bluetoothStatus = false;});},// 向设备发送数据writeBlueData() {let obj = {cmd: 3,freq: 430125,speakable: 1};let objStr = JSON.stringify(obj);let buffer = new ArrayBuffer(objStr.length); // 每个字符占用2个字节let bufView = new Uint8Array(buffer);for (let i = 0; i < objStr.length; i++) {bufView[i] = objStr.charCodeAt(i);}bluetooth.writeData(buffer);}},onShow() {// 获取蓝牙和设备连接状态this.initBluetooth();},}
</script><style lang="scss">page {height: 100%;}
</style>
相关文章:

uniapp微信小程序蓝牙连接与设备数据对接
蓝牙连接并通信方法封装大致步骤。 初始化蓝牙并搜索;获取并启用service服务;数据读取和监听设备返回数据 需要使用uniapp官方提供api: // 关闭蓝牙 uni.closeBluetoothAdapter({}) // 打开蓝牙 uni.openBluetoothAdapter({}) // 搜索附近…...

HBase 计划外启动 Major Compaction 的原因
HBase 的 Compaction 有两个线程池,一个是为 Minor Compaction 准备的, 一个是为 Major Compaction 准备的,hbase.regionserver.thread.compaction.throttle 是决定 Compaction 请求放入哪个线程池的阈值,当待合并文件的总大小小于这个阈值时,就是一个 Minor Compaction,…...

设计模式-桥接模式
概念 用于把抽象化与实现化解耦使得二者可以独立变化 演示 class ColorShape {yellowCircle() {console.log(yellow circle)}redCircle() {console.log(red circle)}yellowTriangle() {console.log(yellow triangle)}redTriangle() {console.log(red triangle)} }// 测试 le…...

arcgis地形分析全流程
主要内容:DEM的获取与处理、高程分析、坡度分析、坡向分析、地形起伏度分析、地表粗糙度分析、地表曲率分析; 主要工具:镶嵌至新栅格、按掩膜提取、投影栅格、坡度、坡向、焦点统计 一 DEM的获取与处理 1.1 DEM是什么? DEM(D…...

mapper.xml中的sql标签
在MyBatis中,mapper.xml文件是用于定义数据库操作的映射文件,其中的<sql>标签用于定义可重用的SQL片段。这些SQL片段可以在<select>, <update>, <insert>, <delete>等操作中被引用,以避免在多个地方重复编写相…...

重启redis的步骤
要重启 Redis,需要使用以下步骤: 登录到您的服务器:使用 SSH 或其他远程访问方式登录到托管 Redis 的服务器。 停止 Redis 服务器:您可以使用以下命令停止 Redis 服务器: redis-cli shutdown 这将向 Redis 服务器发送…...

第二证券:如何选股票的龙头股?
在股票商场中,每个出资者的方针都是可以出资到那些未来可以表现出色并带领整个工作开展的龙头股。选股关于出资者来说非常要害,由于选股不妥或许会导致出资失利。那么,怎么选股票的龙头股呢?本文从多个角度进行剖析,协…...

【华为OD机考B卷 | 100分】统计监控、需要打开多少监控器(JAVA题解——也许是全网最详)
前言 本人是算法小白,甚至也没有做过Leetcode。所以,我相信【同为菜鸡的我更能理解作为菜鸡的你们的痛点】。 题干 OD,B 卷 100 分题目【OD 统一考试(B 卷)】 1. 题目描述 某长方形停车场每个车位上方都有一个监控…...

Python Django 详解(基础)
文章目录 1 概述1.1 安装 django1.2 创建 django 项目1.3 创建 app 2 启动 Django2.1 settings.py:注册 app2.2 view.py:URL和视图对应2.3 启动 Django2.4 访问 3 快速上手3.1 templates:html 模板3.2 static:静态文件3.3 模板语法…...

C语言内存函数
目录 memcpy(Copy block of memory)使用和模拟实现memcpy的模拟实现 memmove(Move block of memory)使用和模拟实现memmove的模拟实现: memset(Fill block of memory)函数的使用扩展 memcmp(Compare two blocks of memory)函数的使用 感谢各位大佬对我的支持,如果我的文章对你有…...

【Docker】Docker-compose及Consul多容器编排工具
使用一个Dockerfile模版文件可以定义一个单独的应用容器,当需要定义多个容器时就需要编排 docker swarm(管理跨节点) 编排工具——docker compose Dockerfile可以让用户管理一个单独的应用容器;而Compose则允许用户在一个模板&…...

Unity网络同步方案帧同步和状态同步
网络同步方案 介绍开始我们使用的状态同步(实时状态同步)后来采用的帧同步 状态同步优点缺点 帧同步顺序执行追帧重连优点缺点 总结 这两年做的都是帧同步和状态同步的项目,正好最近有时间总结一下什么是帧同步和状态同步,之前在做…...

【Monorepo实战】pnpm+turbo+vitepress构建公共组件库文档系统
Monorepo架构可以把多个独立的系统放到一起联调,本文记录基于pnpm > workspace功能,如何构建将vitepress和组件库进行联调,并且使用turbo进行任务顺序编排。 技术栈清单: pnpm 、vitepress 、turbo 一、需求分析 1、最终目标…...

CentOS 编译安装Redis
一、编译配置hiredis.h C来操作redis数据库。通过hiredis接口来实现,目前只能在Linux环境使用。 下载hiredis.h hiredis的下载地址为:https://github.com/redis/hiredis 解压并编译hiredis [rootlocalhost source_code]# pwd /usr/local/source_…...

可拓展的低代码全栈框架
尽管现在越来越多的人开始对低代码开发感兴趣,但已有低代码方案的局限性仍然让大家有所保留。其中最常见的担忧莫过于低代码缺乏灵活性以及容易被厂商锁定。 显然这样的担忧是合理的,因为大家都不希望在实现特定功能的时候才发现低代码平台无法支持&…...

C++11 智能指针
目录 智能指针 异常导致执行流乱跳 智能指针解决问题 auto_ptr unique_ptr sharded_ptr weak_ptr 智能指针 由于C11引入异常之后,执行流乱跳,所以导致之前 malloc/new 的空间很容易没有被释放,导致内存泄露问题。 所以这时候&#x…...

二、WebGPU阶段间变量(inter-stage variables)
二、WebGPU阶段间变量(inter-stage variables) 在上一篇文章中,我们介绍了一些关于WebGPU的基础知识。在本文中,我们将介绍阶段变量(inter-stage variables)的基础知识。 阶段变量在顶点着色器和片段着色…...

【Linux】31个普通信号
文章目录 1.每种信号的含义2.两种不能被忽略的信号3.两种不能被捕捉的信号 1.每种信号的含义 信号编号信号名信号含义1SIGHUP如果终端接口检测到一个连接断开,则会将此信号发送给与该终端相关的控制进程,该信号的默认处理动作是终止进程。2SIGINT当用户…...

Mac电脑交互式原型设计 Axure RP 8汉化最新 for mac
Axure RP 8是一款专业且快速的原型设计工具,主要用于定义需求、规格、设计功能和界面。这款工具主要适用于用户体验设计师、交互设计师、业务分析师、信息架构师、可用性专家和产品经理等职业。 Axure RP 8的主要特性包括能够快速设计出应用软件或Web网站的线框图、…...

在线免费无时长限制录屏工具 - 录猎在线版
需要录屏的小伙伴注意啦,想要长时间录制又不想花钱的,可以看下这款在线版录屏软件 —— 录猎在线版,一个录屏软件所需要的基本功能它都有,设置录制范围、录制的声音来源、摄像头也能录制的。同时它是支持Windows和Mac系统的&#…...

c语言文件操作详解:fgetc,fputc,fgets,fputs,fscanf,,fprintf,fread,fwrite的使用和区别
前言:在对于c语言的学习中,我们为了持续使用一些数据,为了让我们的数据可以在程序退出后仍然保存并且可以使用,我们引入了文件的概念和操作,本文旨在为大家分享在文件操作中常用的输入输出函数的使用方式和技巧&#x…...

Harmony装饰器
1、装饰器 装饰器是用于装饰类、结构、方法以及变量,并赋予其特殊的含义。如: Component表示自定义组件Entry表示该自定义组件为入口组件State表示组件中的状态变量,状态变量变化会触发UI刷新。 2 、语法范式 Builder/BuilderParam&#…...

如何加快Chrome谷歌浏览器下载速度?
用Chrome打开chrome://flags/...

使用kubectl连接远程Kubernetes(k8s)集群
使用kubectl连接远程Kubernetes集群 环境准备下载kubectl下载地址 安装kubectl并处理配置文件Windows的安装配置安装kubectl拉取配置文件安装kubectl拉取配置文件kubectl命令自动补全 Linux的安装配置安装kubectl拉取配置文件kubectl命令自动补全 环境准备 你需要准备一个Kube…...

Kubernetes革命:云原生时代的应用编排和自动化
文章目录 什么是Kubernetes以及为何它备受欢迎?云原生应用和K8s的关系Kubernetes的核心概念:Pods、Services、ReplicaSets等部署、扩展和管理应用程序的自动化容器编排的演进:Docker到Kubernetes实际用例:企业如何受益于K8s的应用…...

mysql.mongoDb,neo4j数据库对比
#Mysql与MongoDb和Neo4j的一些对比 主要区别 MySQL: 1.MySQL是一种关系型数据库管理系统(RDBMS),广泛用于处理结构化数据。 2.它支持SQL语言,具备成熟的事务处理和数据一致性能力。 3.MySQL适用于大多数传统的基于表…...

unity使用UniStorm 5.1.0.unitypackage增加天气
添加天天气组件unistorm 然后添加一个player 导入包会报错,需要修改代码 using UnityEngine; using UnityEngine.PostProcessing;namespace UnityEditor.PostProcessing {[CustomPropertyDrawer(typeof(UnityEngine.PostProcessing.MinAttribute))]sealed class MinDrawer : …...

Flink实现kafka到kafka、kafka到doris的精准一次消费
1 流程图 2 Flink来源表建模 --来源-城市topic CREATE TABLE NJ_QL_JC_SSJC_SOURCE ( record string ) WITH (connector kafka,topic QL_JC_SSJC,properties.bootstrap.servers 172.*.*.*:9092,properties.group.id QL_JC_SSJC_NJ_QL_JC_SSJC_SOURCE,scan.startup.mode …...

Outlook屏蔽Jira AI提醒
前言:最近不知道为什么jira上的ai小助手抽风,一周发个几千封邮件…导致我现在都不想在邮箱里面跟找垃圾一样找消息了。实在忍无可忍,决定屏蔽AI小助手,方法很简单,follow me~~ 第一步:双击打开电脑版Outloo…...

毛玻璃 has 选择器卡片悬停效果
效果展示 页面结构 从上述的效果展示可以看到,页面是由多个卡片组成,并且鼠标悬停在卡片上时,会旋转用户图片并且韩式对应的用户信息框。 CSS3 知识点 :has 属性的运用 实现页面整体结构 <div class"container"><div…...