uniApp低功耗蓝牙一键开门、多对多查找、数组匹配数组、开锁
文章目录
- html
- JavaScript
- 坑
html
<view class="m_t_36"><view class="w_50_ h_100 lh_100 m_l_a m_r_a bc_409eff radius_10 color_fff ta_c" @click="openBluetoothAdapter()">一键开门</view>
</view>
JavaScript
export default {data() {return {timeout: undefined,// 后端保存蓝牙信息bluetooths: [{deviceId: "0A:45:32:0C:78:C6",name: "YX_0A45320C78C6",serviceId: '0000FFB0-0000-1000-8000-00805F9B34FB',notifyId: '0000FFB2-0000-1000-8000-00805F9B34FB',writeId: '0000FFB1-0000-1000-8000-00805F9B34FB',instruction: 'EE03E30100'},{deviceId: "5C:C3:36:8D:B9:FC",name: "RTK_BT_4.1v",serviceId: '0000FFB0-0000-1000-8000-00805F9B34FB',notifyId: '0000FFB2-0000-1000-8000-00805F9B34FB',writeId: '0000FFB1-0000-1000-8000-00805F9B34FB',instruction: 'EE03E30100'}],bluetooth: {}}},methods: {/*** 根据不同方法名调用方法,统一定时器的触发判断,* 当定时器触发时,无法确定当前调用的方法是哪个* @param {String} fnName */methodExecution(fnName = '') {if (this.timeout) {this[fnName]();} else {console.log('执行方法');}},// 数据初始化initInfo() {// 清除定时器无效的解决方案this.timeout = undefined;this.bluetooth = {};},// 初始化蓝牙模块openBluetoothAdapter() {let that = this;// 向低功耗蓝牙设备特征值中写入二进制数据。// 注意:必须设备的特征值支持 write 才可以成功调用。if (Object.keys(that.bluetooth).length) return that.writeBLECharacteristicValue();// 数据初始化that.initInfo();// 初始化蓝牙模块uni.openBluetoothAdapter({// 主服务的UUID是YX。传入这个参数,只搜索主服务UUID为YX的设备// services: ['YX'],success() {// 开始搜索附近的蓝牙设备that.startBluetoothDevicesDiscovery();},fail() {uni.showToast({icon: 'none',title: '查看手机蓝牙是否打开'});}});},// 开始搜索附近的蓝牙设备startBluetoothDevicesDiscovery() {let that = this;uni.showLoading({title: '加载中',mask: true});that.timeout = setTimeout(() => {// 数据初始化that.initInfo();uni.hideLoading();uni.showToast({icon: 'none',title: '开门失败'});}, 1000 * 20);// 开始搜索附近的蓝牙设备uni.startBluetoothDevicesDiscovery({success() {// 监听返回的蓝牙设备uni.onBluetoothDeviceFound(({devices}) => {if (devices.length) {let bluetooths = that.bluetooths;// 多对多查找for (let i = 0; i < devices.length; i++) {let itemI = devices[i];if (itemI.name) {for (let j = 0; j < bluetooths.length; j++) {let itemJ = bluetooths[i];if (itemI.deviceId === itemJ.deviceId && itemI.name === itemJ.name) {that.bluetooth = itemJ;setTimeout(() => { that.createBLEConnection() }, 0);return undefined;}}}}}});},fail() {that.methodExecution('startBluetoothDevicesDiscovery');}});},// 连接低功耗蓝牙设备createBLEConnection() {let that = this;// 连接低功耗蓝牙设备uni.createBLEConnection({deviceId: that.bluetooth.deviceId,success() {// 停止搜寻附近的蓝牙外围设备uni.stopBluetoothDevicesDiscovery({success() {// 获取蓝牙服务// that.getBLEDeviceServices();// 启用低功耗蓝牙设备特征值变化时的notify功能,订阅特征值that.notifyBLECharacteristicValueChange();},fail() { }});},fail() {// 连接低功耗蓝牙设备that.methodExecution('createBLEConnection');}});},// 启用低功耗蓝牙设备特征值变化时的notify功能,订阅特征值notifyBLECharacteristicValueChange() {let that = this,{ deviceId, serviceId, notifyId } = that.bluetooth;// 启用低功耗蓝牙设备特征值变化时的notify功能,订阅特征值uni.notifyBLECharacteristicValueChange({state: true,deviceId,serviceId,characteristicId: notifyId,success() {// 监听低功耗蓝牙设备的特征值变化事件。// 必须先启用 notifyBLECharacteristicValueChange 接口才能接收到设备推送的 notification。that.onBLECharacteristicValueChange();},fail() {// 启用低功耗蓝牙设备特征值变化时的notify功能,订阅特征值that.methodExecution('notifyBLECharacteristicValueChange');}});},// 监听低功耗蓝牙设备的特征值变化事件。// 必须先启用 notifyBLECharacteristicValueChange 接口才能接收到设备推送的 notification。onBLECharacteristicValueChange() {let that = this;// 监听低功耗蓝牙设备的特征值变化事件。// 必须先启用 notifyBLECharacteristicValueChange 接口才能接收到设备推送的 notification。uni.onBLECharacteristicValueChange(() => {that.writeBLECharacteristicValue();});},// 向低功耗蓝牙设备特征值中写入二进制数据。// 注意:必须设备的特征值支持 write 才可以成功调用。writeBLECharacteristicValue() {let that = this,{ deviceId, serviceId, writeId, instruction } = that.bluetooth,typedArray = new Uint8Array(instruction.match(/[\da-f]{2}/gi).map((h) => parseInt(h, 16))),buffer = typedArray.buffer;// 向低功耗蓝牙设备特征值中写入二进制数据。// 注意:必须设备的特征值支持 write 才可以成功调用。uni.writeBLECharacteristicValue({deviceId,serviceId,characteristicId: writeId,value: buffer,success() {uni.showToast({title: '开门成功',icon: 'none'});},fail() {uni.showToast({title: '开门失败',icon: 'none'});},complete() {clearTimeout(that.timeout);that.timeout = undefined;uni.hideLoading();}});},// 关闭(断开)蓝牙模块closeBluetoothAdapter() {let that = this;// 关闭(断开)蓝牙模块uni.closeBluetoothAdapter({success: () => {uni.showToast({title: '蓝牙已关闭',icon: 'none'});clearTimeout(that.timeout);that.timeout = undefined;uni.hideLoading();that.initInfo();},fail() {that.closeBluetoothAdapter();}});},// 监听页面隐藏onHide() {// 关闭(断开)蓝牙模块// this.closeBluetoothAdapter();},// 监听页面卸载onUnload() {// 关闭(断开)蓝牙模块this.closeBluetoothAdapter();}}
}
坑
1、
notifyBLECharacteristicValueChange方法用的是读取的特征值。
2、writeBLECharacteristicValue发送指令,返回成功,蓝牙设备无反应,大概率是指令问题。
3、关闭蓝牙有两个API,目前测试只有closeBluetoothAdapter彻底断开蓝牙。
4、setTimeout无法彻底清除定时器,需要手动设置属性值为undefined。
相关文章:
uniApp低功耗蓝牙一键开门、多对多查找、数组匹配数组、开锁
文章目录 htmlJavaScript坑 html <view class"m_t_36"><view class"w_50_ h_100 lh_100 m_l_a m_r_a bc_409eff radius_10 color_fff ta_c" click"openBluetoothAdapter()">一键开门</view> </view>JavaScript export…...
类和对象|六个默认成员函数|const成员函数|运算符重载
文章目录 默认成员构造函数1. 构造函数1.1 概念1.2 特性 2. 析构函数2.1 概念2.2 特性 3. 拷贝构造函数3.1 概念3.2 特性 4. 运算符重载4.1 赋值重载4.2 自增自减重载4.3 取地址操作符重载 5. const成员函数6. 取地址重载 默认成员构造函数 上一节我们说过,空类的大…...
从源码角度去深入分析关于Spring的异常处理ExceptionHandler的实现原理
ExceptionHandler的作用 ExceptionHandler是Spring框架提供的一个注解,用于处理应用程序中的异常。当应用程序中发生异常时,ExceptionHandler将优先地拦截异常并处理它,然后将处理结果返回到前端。该注解可用于类级别和方法级别,…...
04mysql查询语句之查询与分页02
1. 所有有门派的人员信息 ( A、B两表共有) INSERT INTO t_dept(deptName,address) VALUES(华山,华山); INSERT INTO t_dept(deptName,address) VALUES(丐帮,洛阳); INSERT INTO t_dept(deptName,address) VALUES(峨眉,峨眉山); INSERT INTO t_dept(deptN…...
原型模式——对象的克隆
1、简介 1.1、概述 可以通过一个原型对象克隆出多个一模一样的对象,该模式被称为原型模式。 在使用原型模式时,需要首先创建一个原型对象,再通过复制这个原型对象来创建更多同类型的对象。 1.2、定义 原型模式(Prototype Patt…...
[SQL挖掘机] - 多表连接
介绍: 在 SQL 中,多表连接是指将多个表根据某些条件进行联接,以获取相关联的数据。这允许我们跨多个表进行查询,并且根据表之间的关系获取所需的结果。 作用: 当在多个表中存储相关数据时,使用多表连接可以将这些表组合起来以获…...
Day 14 C++ 对象的初始化和清理
目录 为什么要进行对象的初始化和清理 构造函数和析构函数 构造函数(Constructor) 构造函数语法 调用时机 构造函数的调用方式 括号法 显式法 隐式转换法 构造函数分类 分类方式 按参数分为有参构造和无参构造 按类型分为普通构造和拷贝构造…...
Delphi7最佳登录窗体设计
Delphi7我们这里用登录窗体来做演示。输入正确用户名和密码后,登录窗体释放,显示主窗体。 方法/步骤 1.打开Delphi7集成开发环境,在默认工程的Form1窗体放置一个Label1控件,拖动控件边界调整大小,并将Object Inspect…...
动脑学院Jetpack Compose学习笔记
最近b站学习了一下Compose相关内容,整理了相关笔记,仅供大家参考。 资源链接如下,象征性收取1个积分 https://download.csdn.net/download/juliantem/88125198...
Qt中线程的使用
Qt中线程的使用 在qt中线程的使用有两种方式,第一种就是创建一个类继承QObject类,之后使用moveToThread函数将线程添加到类中。另一种就是创建一个类继承QThread类,在类中实现run函数。 第一种方式: 1、首先创建一个自定义的类…...
基于YOLOv8开发构建蝴蝶目标检测识别系统
在前面的一篇博文中已经很详细地描述了如何基于YOLOv8开发构建自己的个性化目标检测模型,感兴趣的话可以看下: 《基于YOLOv8开发构建目标检测模型超详细教程【以焊缝质量检测数据场景为例】》 本文的主要目的就是基于YOLOv8来开发构建细粒度的蝴蝶目标…...
【已解决】电脑连上网线但无法上网
文章目录 案例情况解决方案必要的解决方法简要概括详细步骤1、打开控制面板2、打开更改适配器设置3、 找Internet协议版本44、修改配置 可能有用的解决方法 问题解决原理Internet 协议版本 4(TCP/IPv4)确保IP地址和DNS服务器设置为自动获取 案例情况 网…...
Linux 学习记录57(ARM篇)
Linux 学习记录57(ARM篇) 本文目录 Linux 学习记录57(ARM篇)一、外部中断1. 概念2. 流程图框 二、相关寄存器1. GIC CPU Interface (GICC)2. GIC distributor (GICD)3. EXTI registers 三、EXTI 寄存器1. 概述2. 内部框图3. 寄存器功能描述4. EXTI选择框图5. EXTI_EXTICR1 &…...
Doris注意事项,Doris部署在阿里云,写不进去数据
1.Doris官网 Doris官网https://doris.apache.org/ 2.根本原因 本地idea访问FE,FE会返回BE的地址,但是在服务器上通过ip addr查看,发现只有局域网IP,所以FE返回了局域网的IP,导致idea连接不上BE 3.解决办法 重写Ba…...
502 Bad GateWay报错的解决方法
什么是502 bad gateway 报错 简单来说 502 是报错类型代码 bad gateway 错误的网关。是Web服务器作为网关或代理服务器时收到无效的响应。 用我们的口语说就是运行网站的服务器暂时挂了(不响应)。 产生错误的原因 1.连接超时 我们向服务器发送请求 由于服务器当前链接太多&am…...
openpnp - ReferenceStripFeeder 改版零件
文章目录 openpnp - ReferenceStripFeeder 改版零件概述笔记整体效果散料飞达主体磁铁仓盖板飞达编带中间压条飞达编带两边压条装配体用的8mm编带模型END openpnp - ReferenceStripFeeder 改版零件 概述 官方推荐了ReferenceStripFeeder的模型smd_strip_feeders_mod_tray.zip…...
VoxPoser:使用大语言模型(GPT-4)来对机器人操作的可组合三维值图【论文解读】
这是最近斯坦福的李飞飞团队的一篇论文:VoxPoser: Composable 3D Value Maps for Robotic Manipulation with Language Models 主要是通过大语言模型LLM和视觉语言模型VLM结合,来对机器人做各种日常操作,我们可以先来看下实际效果:大语言模型…...
RISC-V公测平台发布 · 第一个WEB Server “Hello RISC-V world!”
RISC-V公测平台Web Server地址:http://175.8.161.253:8081 一、前言 Web Server是互联网应用的基础设施,无论是用户访问网站,还是后端服务提供商和开发者构建各种应用程序,Web Server都在其中扮演着至关重要的角色。 显而易见…...
Linux 发行版 CentOS 于 Ubuntu 软件的安装、卸载、查找
CentOS于Ubuntu 内核都是Linux,是一样的。 CentOS 软件格式 .rpm sudo yum [-y] [ install | remove | search ] 软件名称 install 安装 remove 移除 search 搜索 Ubuntu 软件格式 .deb sudo apt [-y] [ install | remove | search ] 软件名称 install 安装 remove…...
cmd相关操作命令
1.根据端口号查询对应进程的PID netstat -ano | findstr 端口号 例如:netstat -ano | findstr 9080;该端口所属进程的PID为6684 2.根据PID查询对应进程 tasklist | findstr PID 例如:tasklist | findstr 6684;该PID所属进程名为…...
Docker 运行 Kafka 带 SASL 认证教程
Docker 运行 Kafka 带 SASL 认证教程 Docker 运行 Kafka 带 SASL 认证教程一、说明二、环境准备三、编写 Docker Compose 和 jaas文件docker-compose.yml代码说明:server_jaas.conf 四、启动服务五、验证服务六、连接kafka服务七、总结 Docker 运行 Kafka 带 SASL 认…...
高频面试之3Zookeeper
高频面试之3Zookeeper 文章目录 高频面试之3Zookeeper3.1 常用命令3.2 选举机制3.3 Zookeeper符合法则中哪两个?3.4 Zookeeper脑裂3.5 Zookeeper用来干嘛了 3.1 常用命令 ls、get、create、delete、deleteall3.2 选举机制 半数机制(过半机制࿰…...
STM32F4基本定时器使用和原理详解
STM32F4基本定时器使用和原理详解 前言如何确定定时器挂载在哪条时钟线上配置及使用方法参数配置PrescalerCounter ModeCounter Periodauto-reload preloadTrigger Event Selection 中断配置生成的代码及使用方法初始化代码基本定时器触发DCA或者ADC的代码讲解中断代码定时启动…...
【HTML-16】深入理解HTML中的块元素与行内元素
HTML元素根据其显示特性可以分为两大类:块元素(Block-level Elements)和行内元素(Inline Elements)。理解这两者的区别对于构建良好的网页布局至关重要。本文将全面解析这两种元素的特性、区别以及实际应用场景。 1. 块元素(Block-level Elements) 1.1 基本特性 …...
项目部署到Linux上时遇到的错误(Redis,MySQL,无法正确连接,地址占用问题)
Redis无法正确连接 在运行jar包时出现了这样的错误 查询得知问题核心在于Redis连接失败,具体原因是客户端发送了密码认证请求,但Redis服务器未设置密码 1.为Redis设置密码(匹配客户端配置) 步骤: 1).修…...
听写流程自动化实践,轻量级教育辅助
随着智能教育工具的发展,越来越多的传统学习方式正在被数字化、自动化所优化。听写作为语文、英语等学科中重要的基础训练形式,也迎来了更高效的解决方案。 这是一款轻量但功能强大的听写辅助工具。它是基于本地词库与可选在线语音引擎构建,…...
从“安全密码”到测试体系:Gitee Test 赋能关键领域软件质量保障
关键领域软件测试的"安全密码":Gitee Test如何破解行业痛点 在数字化浪潮席卷全球的今天,软件系统已成为国家关键领域的"神经中枢"。从国防军工到能源电力,从金融交易到交通管控,这些关乎国计民生的关键领域…...
Spring AI Chat Memory 实战指南:Local 与 JDBC 存储集成
一个面向 Java 开发者的 Sring-Ai 示例工程项目,该项目是一个 Spring AI 快速入门的样例工程项目,旨在通过一些小的案例展示 Spring AI 框架的核心功能和使用方法。 项目采用模块化设计,每个模块都专注于特定的功能领域,便于学习和…...
数学建模-滑翔伞伞翼面积的设计,运动状态计算和优化 !
我们考虑滑翔伞的伞翼面积设计问题以及运动状态描述。滑翔伞的性能主要取决于伞翼面积、气动特性以及飞行员的重量。我们的目标是建立数学模型来描述滑翔伞的运动状态,并优化伞翼面积的设计。 一、问题分析 滑翔伞在飞行过程中受到重力、升力和阻力的作用。升力和阻力与伞翼面…...
LangChain 中的文档加载器(Loader)与文本切分器(Splitter)详解《二》
🧠 LangChain 中 TextSplitter 的使用详解:从基础到进阶(附代码) 一、前言 在处理大规模文本数据时,特别是在构建知识库或进行大模型训练与推理时,文本切分(Text Splitting) 是一个…...
