【微信小程序】连接蓝牙设备
1、检查小程序是否授权蓝牙功能
initBluetooth() {const that = thiswx.getSetting({success: (res) => {if (res.authSetting.hasOwnProperty('scope.bluetooth')) {//'scope.bluetooth'属性存在,且为falseif (!res.authSetting['scope.bluetooth']) {wx.showModal({title: '温馨提示',showCancel: false,content: '获取蓝牙授权失败,需要手动授权'})} else {that.openBluetooth();}} else {//'scope.bluetooth'属性不存在,需要授权that.openBluetooth();}}})},
wx.getSetting()方法获取用户的设置信息res.authSetting包含scope.bluetooth属性,表示已经获取到了蓝牙权限的设置信息scope.bluetooth的值为false,即用户没有授权蓝牙权限,为true,即用户已经授权蓝牙权限,调用openBluetooth()方法打开蓝牙功能
打开授权
openBluetooth() {const that = thiswx.closeBluetoothAdapter({success(res) {wx.openBluetoothAdapter({success: function (res) {/*getBluetoothAdapterState() 获取本机蓝牙适配器状态,判断是否可用,available为false则因为用户没有开启系统蓝牙*/wx.getBluetoothAdapterState({success: function (res) {that.setData({findBluetoothState: setInterval(() => {if (!that.data.theBluetoothState) {that.initBluetooth()clearInterval(that.data.findTimer)}wx.getBluetoothAdapterState({success: function (res) {if (!res.available) {...}},fail: function (res) {...}})}, 1000)})// res.available==true适配器可用 res.available==false适配器不可用if (res.available) {that.findBluetooth()} else {wx.showModal({title: '温馨提示',showCancel: false,content: '蓝牙设备不可用',success(res) {...}})}},fail: function (res) {wx.showModal({title: '温馨提示',showCancel: false,content: '蓝牙设备不可用',success(res) {if (res.confirm) {wx.hideLoading()}}})}})},fail: function (err) {console.log(err);wx.showModal({title: '温馨提示',showCancel: false,content: '蓝牙初始化失败,请确认蓝牙功能已开启',success(res) {...}})}})}})},
wx.closeBluetoothAdapter()方法关闭蓝牙适配器,在成功关闭蓝牙适配器后的回调函数中,调用wx.openBluetoothAdapter()方法打开蓝牙适配器。先关闭再打开的方式来初始化蓝牙功能,确保蓝牙适配器工作在一个可靠的状态下,这种做法可以帮助解决一些潜在的问题,比如之前可能存在的连接问题、缓存状态或其他异常情况wx.getBluetoothAdapterState()方法获取本机蓝牙适配器的状态- 蓝牙适配器可用(
res.available 为 true),则去查找蓝牙设备;不可用(res.available 为 false),则给出提示
2、搜索附近蓝牙设备并匹配
findBluetooth() {const that = thiswx.startBluetoothDevicesDiscovery({services: [],allowDuplicatesKey: false,success: function () {//获取蓝牙设备输出信息列表let aaa = setInterval(() => {wx.getBluetoothDevices({success: function (res) {res.devices.forEach(item => {if (item.advertisData !== '') {if (...) {console.log('匹配到设备:deviceName-' + item.deviceName + ',deviceId-' + item.deviceId);that.creatDevice(item.deviceId)clearInterval(aaa)}}})}})}, 1000)},fail: function (err) {wx.showModal({title: '温馨提示',showCancel: false,content: '搜索蓝牙失败,请检测手机蓝牙,定位功能是否已开启',success(res) {if (res.confirm) {...}}})}});},
wx.startBluetoothDevicesDiscovery()方法开始搜索附近的蓝牙设备setInterval()方法每隔一段时间执行一次蓝牙设备搜索操作,在每次执行时,使用wx.getBluetoothDevices()方法获取附近的蓝牙设备列表,根据匹配的条件,找到对应的设备,拿到设备的deviceId去与该设备进行连接,注意及时清理定时器
拓展:
wx.getBluetoothDevices() 和 wx.onBluetoothDeviceFound 是小程序中用于搜索蓝牙设备的两种不同方法,它们有以下区别:
1、wx.getBluetoothDevices
- 用来主动搜索附近的蓝牙设备,调用该方法后会返回附近的蓝牙设备列表
- 是一个一次性的操作,即调用一次就会返回当前时刻附近的蓝牙设备列表,之后如果需要重新搜索需要再次调用该方法
- 适用于需要手动触发搜索蓝牙设备的场景,比如用户点击搜索按钮时
2、wx.onBluetoothDeviceFound
- 用来监听附近蓝牙设备的发现事件,当有新的蓝牙设备被发现时会触发该事件,从而可以实时获取附近蓝牙设备的信息
- 是一个被动的操作,即当有新的蓝牙设备被发现时,会触发相应的事件回调函数,无需手动触发搜索
- 适用于需要实时监测附近蓝牙设备变化的场景,比如展示附近蓝牙设备列表并实时更新
3、连接蓝牙设备
creatDevice(deviceId) {const that = thiswx.getConnectedBluetoothDevices({services: [this.data.serviceId],success(res) {console.log(res);if (res.devices.length > 0) {that.getServices(deviceId)} else {wx.createBLEConnection({deviceId,success: function (res) {console.log('连接成功输出信息', res)wx.onBLEConnectionStateChange(function (res) {// 该方法回调中可以用于处理连接意外断开等异常情况console.log(`device ${res.deviceId} state has changed, connected: ${res.connected}`)if (!res.connected) {console.log('连接断开');wx.offBLEConnectionStateChange()clearTimeout(that.data.doLinkAgainTimer)that.setData({doLinkAgainTimer: setTimeout(() => {that.creatDevice(deviceId)}, 200),})}})that.getServices(deviceId)},fail: function (err) {console.log(err, '连接失败')},})}},fail(err) {console.log(err);}})
},
- 使用
wx.getConnectedBluetoothDevices()方法获取已连接的蓝牙设备列表 - 如果已连接的设备列表中包含了符合特定服务 UUID 的设备,则直接去获取服务
- 如果未找到已连接的符合条件的设备,则调用
wx.createBLEConnection()方法尝试连接指定的设备 - 如果连接成功,则会设置一个监听器
wx.onBLEConnectionStateChange()来监测蓝牙连接状态的变化。如果连接意外断开,会在回调函数中重新尝试连接,并设置一个定时器来控制重新连接的时间间隔。
4、获取服务和特征值
getServices(deviceId) {const that = thiswx.getBLEDeviceServices({// 这里的 deviceId 需要已经通过 wx.createBLEConnection 与对应设备建立连接deviceId,success(res) {console.log('获取服务:', res)that.getServicesCharacteristics(deviceId)},fail(err) {console.log('获取服务失败:', err);}})
},
getServicesCharacteristics(deviceId) {const that = thiswx.getBLEDeviceCharacteristics({// 这里的 deviceId 需要已经通过 wx.createBLEConnection 与对应设备建立连接deviceId,serviceId: this.data.serviceId,success(res) {console.log('获取特征值:', res);let characteristics = res.characteristics.find(item => item.properties.notify)that.startNotice(characteristics.uuid)},fail(err) {console.log('获取特征值失败:', err);}})},
wx.getBLEDeviceServices获取到服务列表,里面每一条数据代表一个服务,UUID是用来唯一标识一个蓝牙服务的字符串wx.getBLEDeviceCharacteristics获取该服务的所有特征值列表,用properties来区分,代表该特征值支持的操作类型
5、启动蓝牙服务值变化监听及监听特征值变化
startNotice(uuid){var that = this;wx.notifyBLECharacteristicValueChange({state: true, // 启用 notify 功能deviceId: that.data.deviceid,serviceId: that.data.services,characteristicId: uuid, //第一步 开启监听 notityid 第二步发送指令 writesuccess: function (res) {wx.onBLECharacteristicValueChange(function (res) {}})
},
wx.notifyBLECharacteristicValueChang用于启用蓝牙特征值变化通知wx.onBLECharacteristicValueChange用于监听蓝牙设备特征值变化,当特征值发生变化时,会触发这个函数,并可以在这里获取变化后的值并进行相应的处理
6、建立长连接
蓝牙设备通常需要建立长连接才能进行稳定的数据传输和控制。默认情况下,微信小程序与蓝牙设备的连接会在一定时间内保持活跃,如果超过一定时间没有数据交互或者没有持续发送心跳包等保持连接的机制,连接可能会自动断开。
获取随机数并进行外部认证通常用于建立安全连接
获取随机数:设备A生成一个随机数,并将其发送给设备B进行外部认证:设备B收到随机数后,可能会使用预共享密钥或其他加密算法对随机数进行处理,然后将处理后的结果发送给设备A验证认证结果:设备A收到处理后的结果后,进行验证以确保通信双方的身份和通信的完整性
相关文章:
【微信小程序】连接蓝牙设备
1、检查小程序是否授权蓝牙功能 initBluetooth() {const that thiswx.getSetting({success: (res) > {if (res.authSetting.hasOwnProperty(scope.bluetooth)) {//scope.bluetooth属性存在,且为falseif (!res.authSetting[scope.bluetooth]) {wx.showModal({tit…...
基于R语言BIOMOD2 及机器学习方法的物种分布模拟与案例分析实践技术
BIOMOD2是一个R软件包,用于构建和评估物种分布模型(SDMs)。它集成了多种统计和机器学习方法,如GLM、GAM、SVM等,允许用户预测和分析物种在不同环境条件下的地理分布。通过这种方式,BIOMOD帮助研究者评估气候…...
Objective-C之通过协议提供匿名对象
概述 通过协议提供匿名对象的设计模式,遵循了面向对象设计的多项重要原则: 接口隔离原则:通过定义细粒度的协议来避免实现庞大的接口。依赖倒置原则:高层模块依赖于抽象协议,而不是具体实现。里氏替换原则࿱…...
C语言基础(一)
C语言基础 一、标准输出(格式化输出):1、概念:2、注意语法点:3、格式控制符:4、调试技巧:5、代码风格:6、实例: 二、数据类型:1、整型概念:语法&a…...
机器学习_决策树与随机森林
决策树是一种常用的监督学习算法,既可以用于分类任务也可以用于回归任务。决策树通过递归地将数据集划分成更小的子集,逐步建立树结构。每个节点对应一个特征,树的叶子节点表示最终的预测结果。构建决策树的关键是选择最佳的特征来分割数据&a…...
嵌入式系统日志轮转:实现与性能考量
日志轮转是嵌入式系统中管理日志文件的一种常用技术,它通过创建新的日志文件来替代旧的日志文件,从而避免日志文件无限增长,占用过多存储空间。本文将探讨日志轮转的实现方法以及在嵌入式系统中实现日志轮转时需要考虑的性能因素。 一、日志…...
麦肯锡:ChatGPT等生成式AI应用激增,大中华区增长最快
全球顶级咨询公司麦肯锡(McKinsey & Company)在官网发布了《he state of AI in early 2024:Gen AI adoption spikes and starts to generate value》,一份关于生成式AI应用的调查报告。 麦肯锡对多个国家/地区的1,363位管理者进行了调查…...
Vue Router 使用教程
Vue Router 是 Vue.js 的官方路由管理器,它提供了一种方便的方式来管理应用的路由。在本教程中,我们将介绍 Vue Router 的一些常见用法和示例。 一、安装 Vue Router 使用 Vue Router 之前,需要先安装它。可以使用以下命令通过 npm 安装&am…...
银河麒麟解压命令
银河麒麟(Kylin)操作系统是基于Linux的操作系统分支之一,其使用的解压命令与Linux系统中的命令基本相同。 在银河麒麟系统中,常用的解压命令有以下几种: 对于.tar文件: tar -xvf file.tar对于.tar.gz或.…...
VSCode打开文件总是在当前标签页打开,不是新增标签页
修改 VS Code 设置 打开设置: 按 Ctrl , 或者点击右下角的齿轮图标,然后选择 “Settings”。 搜索设置: 在设置搜索栏中输入 workbench.editor.enablePreview。 禁用预览模式: 找到 Workbench > Editor: Enable Preview 选…...
Django redirect()函数实现页面重定向
1,通过路由反向解析进行重定向 1.1 添加视图函数 myshop/app2/views.py from django.http import HttpResponse from django.shortcuts import render from django.urls import reverse def index(request):return HttpResponse("app2 的index")# 反向…...
【运维项目经历|029】NTP精准时间同步系统优化项目
🍁博主简介: 🏅云计算领域优质创作者 🏅2022年CSDN新星计划python赛道第一名 🏅2022年CSDN原力计划优质作者 🏅阿里云ACE认证高级工程师 🏅阿里云开发者社区专家博主 💊交流社区:CSDN云计算交流社区欢迎您的加入! 目...
机房网络运维服务项目难点与关键点分析
随着信息技术的飞速发展,机房作为支撑企业信息化建设的核心枢纽,其网络运维服务的重要性日益凸显。然而,在实际运维过程中,运维团队常常面临诸多难点和挑战。本文将围绕机房网络运维服务项目的难点和关键点进行深入分析࿰…...
MKS AX7680 SERIES 电源使用说明手侧
MKS AX7680 SERIES 电源使用说明手侧...
DVWA-XSS(Reflected)
反射型XSS可以用来窃取cookie Low 输入1111进行测试,发现1111被打印 输入<script>alert(document.cookie)</script>,出现弹窗,获得cookie Medium 查看后端代码,发现对<script>进行了转义,但是…...
Python自动化办公2.0 即将发布
第一节课:数据整理与清洗 第二节课:数据筛选、过滤与排序 第三节课:高级数据处理技巧 第四节课:数据可视化与实践案例 第五节课:统计分析与报表 第六节:常见的Excel报表 与下方的课程形成知识体系&…...
【面试宝藏】Redis 常见面试题解析其二
Redis 高级面试题解析 20. 说说 Redis 哈希槽的机制? Redis 集群采用哈希槽(Hash Slot)机制来分布和管理数据。整个哈希空间被划分为 16384 个槽,每个键通过 CRC16 校验后取模映射到一个哈希槽。每个节点负责一部分哈希槽&#…...
智慧公厕厂家+智能厕所小程序,构建数字化公厕新体系
在现代社会的诸多场景中,公厕扮演着重要却常常被忽视的角色。尤其是在传统的楼宇中,公厕存在着一系列痛点问题。 一、传统公厕问题 传统楼宇公厕常常面临着布局不合理的困境,导致使用者寻找困难,浪费时间和精力。卫生状况也是一大…...
使用迁移助手 (SSMA for Oracle) 将Oracle19c数据库迁移到SQL Server2022
如何使用适用于 Oracle 的 SQL Server 迁移助手Microsoft SQL Server Migration Assistant for Oracle (SSMA for Oracle) 将 Oracle 数据库迁移到 SQL Server Microsoft SQL Server Migration Assistant (SSMA) for Oracle is a tool to automate migration from Oracle data…...
LabVIEW开发EOL功能测试系统
LabVIEW开发EOL功能测试系统 介绍了一种基于LabVIEW开发的EOL功能测试系统方案,涵盖软件架构、工作流程、模块化设计、低耦合性、易于修改与维护、稳定性及硬件选型。系统通过高效的CAN通信实现对电机控制器的全面测试,确保运行可靠并支持未来的升级需求…...
C++:std::is_convertible
C++标志库中提供is_convertible,可以测试一种类型是否可以转换为另一只类型: template <class From, class To> struct is_convertible; 使用举例: #include <iostream> #include <string>using namespace std;struct A { }; struct B : A { };int main…...
Swift 协议扩展精进之路:解决 CoreData 托管实体子类的类型不匹配问题(下)
概述 在 Swift 开发语言中,各位秃头小码农们可以充分利用语法本身所带来的便利去劈荆斩棘。我们还可以恣意利用泛型、协议关联类型和协议扩展来进一步简化和优化我们复杂的代码需求。 不过,在涉及到多个子类派生于基类进行多态模拟的场景下,…...
基于当前项目通过npm包形式暴露公共组件
1.package.sjon文件配置 其中xh-flowable就是暴露出去的npm包名 2.创建tpyes文件夹,并新增内容 3.创建package文件夹...
Module Federation 和 Native Federation 的比较
前言 Module Federation 是 Webpack 5 引入的微前端架构方案,允许不同独立构建的应用在运行时动态共享模块。 Native Federation 是 Angular 官方基于 Module Federation 理念实现的专为 Angular 优化的微前端方案。 概念解析 Module Federation (模块联邦) Modul…...
多种风格导航菜单 HTML 实现(附源码)
下面我将为您展示 6 种不同风格的导航菜单实现,每种都包含完整 HTML、CSS 和 JavaScript 代码。 1. 简约水平导航栏 <!DOCTYPE html> <html lang"zh-CN"> <head><meta charset"UTF-8"><meta name"viewport&qu…...
select、poll、epoll 与 Reactor 模式
在高并发网络编程领域,高效处理大量连接和 I/O 事件是系统性能的关键。select、poll、epoll 作为 I/O 多路复用技术的代表,以及基于它们实现的 Reactor 模式,为开发者提供了强大的工具。本文将深入探讨这些技术的底层原理、优缺点。 一、I…...
使用Spring AI和MCP协议构建图片搜索服务
目录 使用Spring AI和MCP协议构建图片搜索服务 引言 技术栈概览 项目架构设计 架构图 服务端开发 1. 创建Spring Boot项目 2. 实现图片搜索工具 3. 配置传输模式 Stdio模式(本地调用) SSE模式(远程调用) 4. 注册工具提…...
【深度学习新浪潮】什么是credit assignment problem?
Credit Assignment Problem(信用分配问题) 是机器学习,尤其是强化学习(RL)中的核心挑战之一,指的是如何将最终的奖励或惩罚准确地分配给导致该结果的各个中间动作或决策。在序列决策任务中,智能体执行一系列动作后获得一个最终奖励,但每个动作对最终结果的贡献程度往往…...
Cursor AI 账号纯净度维护与高效注册指南
Cursor AI 账号纯净度维护与高效注册指南:解决限制问题的实战方案 风车无限免费邮箱系统网页端使用说明|快速获取邮箱|cursor|windsurf|augment 问题背景 在成功解决 Cursor 环境配置问题后,许多开发者仍面临账号纯净度不足导致的限制问题。无论使用 16…...
【Qt】控件 QWidget
控件 QWidget 一. 控件概述二. QWidget 的核心属性可用状态:enabled几何:geometrywindows frame 窗口框架的影响 窗口标题:windowTitle窗口图标:windowIconqrc 机制 窗口不透明度:windowOpacity光标:cursor…...
