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系统的&#…...
Java 语言特性(面试系列2)
一、SQL 基础 1. 复杂查询 (1)连接查询(JOIN) 内连接(INNER JOIN):返回两表匹配的记录。 SELECT e.name, d.dept_name FROM employees e INNER JOIN departments d ON e.dept_id d.dept_id; 左…...
Appium+python自动化(十六)- ADB命令
简介 Android 调试桥(adb)是多种用途的工具,该工具可以帮助你你管理设备或模拟器 的状态。 adb ( Android Debug Bridge)是一个通用命令行工具,其允许您与模拟器实例或连接的 Android 设备进行通信。它可为各种设备操作提供便利,如安装和调试…...
Linux简单的操作
ls ls 查看当前目录 ll 查看详细内容 ls -a 查看所有的内容 ls --help 查看方法文档 pwd pwd 查看当前路径 cd cd 转路径 cd .. 转上一级路径 cd 名 转换路径 …...
【决胜公务员考试】求职OMG——见面课测验1
2025最新版!!!6.8截至答题,大家注意呀! 博主码字不易点个关注吧,祝期末顺利~~ 1.单选题(2分) 下列说法错误的是:( B ) A.选调生属于公务员系统 B.公务员属于事业编 C.选调生有基层锻炼的要求 D…...
GitHub 趋势日报 (2025年06月08日)
📊 由 TrendForge 系统生成 | 🌐 https://trendforge.devlive.org/ 🌐 本日报中的项目描述已自动翻译为中文 📈 今日获星趋势图 今日获星趋势图 884 cognee 566 dify 414 HumanSystemOptimization 414 omni-tools 321 note-gen …...
C++ 求圆面积的程序(Program to find area of a circle)
给定半径r,求圆的面积。圆的面积应精确到小数点后5位。 例子: 输入:r 5 输出:78.53982 解释:由于面积 PI * r * r 3.14159265358979323846 * 5 * 5 78.53982,因为我们只保留小数点后 5 位数字。 输…...
【JavaSE】绘图与事件入门学习笔记
-Java绘图坐标体系 坐标体系-介绍 坐标原点位于左上角,以像素为单位。 在Java坐标系中,第一个是x坐标,表示当前位置为水平方向,距离坐标原点x个像素;第二个是y坐标,表示当前位置为垂直方向,距离坐标原点y个像素。 坐标体系-像素 …...
SQL慢可能是触发了ring buffer
简介 最近在进行 postgresql 性能排查的时候,发现 PG 在某一个时间并行执行的 SQL 变得特别慢。最后通过监控监观察到并行发起得时间 buffers_alloc 就急速上升,且低水位伴随在整个慢 SQL,一直是 buferIO 的等待事件,此时也没有其他会话的争抢。SQL 虽然不是高效 SQL ,但…...
【从零学习JVM|第三篇】类的生命周期(高频面试题)
前言: 在Java编程中,类的生命周期是指类从被加载到内存中开始,到被卸载出内存为止的整个过程。了解类的生命周期对于理解Java程序的运行机制以及性能优化非常重要。本文会深入探寻类的生命周期,让读者对此有深刻印象。 目录 …...
Linux nano命令的基本使用
参考资料 GNU nanoを使いこなすnano基础 目录 一. 简介二. 文件打开2.1 普通方式打开文件2.2 只读方式打开文件 三. 文件查看3.1 打开文件时,显示行号3.2 翻页查看 四. 文件编辑4.1 Ctrl K 复制 和 Ctrl U 粘贴4.2 Alt/Esc U 撤回 五. 文件保存与退出5.1 Ctrl …...
