草庐IT

微信小程序连接蓝牙设备并传递数据

听听你说的-- 2023-12-26 原文

流程图

分步详解

wx.getSystemInfo(Object object) 获取系统信息 获取操作系统及版本 页面加载的时候(或者app.js中 )

初始化蓝牙模块 wx.openBluetoothAdapter(Object object)

在用户蓝牙开关未开启或者手机不支持蓝牙功能的情况下,通过错误码(errCode=10001),提示打开蓝牙或蓝牙功能不可用。此时小程序蓝牙模块已经初始化完成,可通过 wx.onBluetoothAdapterStateChange监听手机蓝牙是否可用或是否在搜索状态。

关闭蓝牙模块wx.closeBluetoothAdapter。调用该方法将断开所有已建立的连接并释放系统资源。建议在使用蓝牙流程后,以及onhideonUnload

开始搜索蓝牙 wx.startBluetoothDevicesDiscovery(OBJECT) 开始搜寻附近的蓝牙外围设备,初始化完成或点击事件里调用。此操作比较耗费系统资源,请在搜索并连接到设备后调用 wx.stopBluetoothDevicesDiscovery方法停止搜索,以及onhideonUnload

监听寻找到新设备的事件wx.onBluetoothDeviceFound(CALLBACK)
通过设备名(设备方提供)过滤设备,deviceId一般不作为判断条件,因为开发者工具和 Android 上获取到的deviceId为设备 MAC 地址;iOS 上则为设备 uuid。

但是如果附近有多个同名的设备时,就需要通过mac地址来匹配对应的蓝牙设备了。ios不同手机搜索到的设备deviceId经过处理后是不同的。如果需要处理这种情况可以联系蓝牙设备硬件方,将mac地址存入当前蓝牙设备的广播数据段中的 ManufacturerData 数据段中,我们通过res.devices.advertisData的值去匹配&连接蓝牙。

⚠️ 安卓下部分机型需要有位置权限才能搜索到设备,需留意是否开启了位置权限

连接低功耗蓝牙设备wx.createBLEConnection(OBJECT) 

若小程序在之前已有搜索过某个蓝牙设备,并成功建立连接,可直接传入之前搜索获取的 deviceId 直接尝试连接该设备,无需进行搜索操作。 

断开连接:wx.closeBLEConnection(),在onhideonUnload时候;

wx.onBLEConnectionStateChange(function callback) 
监听低功耗蓝牙连接状态的改变事件。包括开发者主动连接或断开连接,设备丢失,连接异常断开等等

获取蓝牙设备所有服务(service) wx.getBLEDeviceServices(OBJECT) 
过滤出需要的service uuid,设备方提供,比如包含某一个字段

获取蓝牙设备某个服务中的所有 characteristic(特征值)wx.getBLEDeviceCharacteristics(OBJECT)

过滤特征值,找到 用来写入/读取的特征值的 uuid 设备方提供  

特征值是什么:每个服务都包含了一组特征值用来描述服务的一些属性,跟蓝牙通信时需要这些特征值ID来传递数据。

启用低功耗蓝牙设备特征值变化时的 notify 功能,订阅特征值  wx.notifyBLECharacteristicValueChange(OBJECT),这里需要用来读取的特征值的 uuid

注意⚠️ :必须设备的特征值支持 notify 或者 indicate 才可以成功调用。

写入wx.writeBLECharacteristicValue(OBJECT) 向低功耗蓝牙设备特征值中写入数据,需写入二进制数据。注意:必须设备的特征值支持 write 才可以成功调用。

wx.onBLECharacteristicValueChange 监听低功耗蓝牙设备的特征值变化事件(返回的多个数据包)

监听低功耗蓝牙设备的特征值变化事件。必须先启用 wx.notifyBLECharacteristicValueChange 接口才能接收到设备推送的 notification。

BLE

小程序蓝牙是搜索不到手机蓝牙的。

经典蓝牙和BLE(Bluetooth Low Energy)低功耗蓝牙的区别
蓝牙是一种短距的无线通讯技术,可实现固定设备、移动设备之间的数据交换。一般将蓝牙3.0之前的BR/EDR蓝牙称为传统蓝牙,而将蓝牙4.0规范下的LE蓝牙称为低功耗蓝牙。区别于传统模块,最大的特点就是成本和功耗降低,应用于实时性要求比较高。

蓝牙低功耗(BLE)功能,是利用蓝牙低功耗特性新发展的技术。
手机上要利用蓝牙低功耗技术,一般是通过 BLE 配件厂商发布的 BLE 配件和其配套 APP,配合使用。比如:BLE 运动手环、运动手表、体重计、计步器、智能腕带等。

二进制相关数据类型

ArrayBuffer & TypedArray

ArrayBuffer对象、TypedArray视图和DataView视图是 JavaScript 操作二进制数据的一个接口。ES6 将它们纳入了 ECMAScript 规格,并且增加了新的方法。它们都是以数组的语法处理二进制数据,所以统称为二进制数组。但是,二进制数组并不是真正的数组,而是类似数组的对象。

(1)ArrayBuffer对象:代表内存之中的一段二进制数据,可以通过“视图”进行操作。“视图”部署了数组接口,这意味着,可以用数组的方法操作内存。

(2)TypedArray视图:共包括 9 种类型的视图。比如Uint8ArrayInt16ArrayFloat32Array数组视图等等。 Uint8Array 代表数组的每一项是无符号整型 8代表数据的每一项占 8 个比特位,即一个字节(8bits=1byte)

通过 Uint8Array,即可知道其他视图如 Uint16ArrayInt8Array 等所代表的意义。

  • Int8Array 8位有符号整数的数组
  • Uint16Array 16位无符号整数数组 16代表数据的每一项占 16 个比特位,即2个字节
  • Int16Array 16位有符号整数数组
  • ...

小概括

简单说,ArrayBuffer对象代表原始的二进制数据,「并且只读」,而TypedArray 视图可以进行改写操作。

// new ArrayBuffer 1
var cmdBuffer1 = new ArrayBuffer(15) // new ArrayBuffer(Bytelength); 15个字节
//cmdBuffer1
ArrayBuffer(15) {}
    [[Int8Array]]: Int8Array(15)[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
    [[Uint8Array]: Uint8Array(15)[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] 
    byteLength: (...)  
    __proto__: ArrayBuffer
       
// new ArrayBuffer 2
var cmdBuffer2 = new ArrayBuffer(16)
// cmdBuffer2
ArrayBuffer(16) {}
    [[Int8Array]]: Int8Array(16) [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
    [[Int16Array]]: Int16Array(8)[0, 0, 0, 0, 0, 0, 0, 0]  
    [[Int32Array]]: Int32Array(4) [0, 0, 0, 0]   
    [[Uint8Array]]: Uint8Array(16)[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]   
    byteLength: (...)
    __proto__: ArrayBuffer
        
// ArrayBuffer -> TypedArray
var cmd1 = new Uint8Array(cmdBuffer1)
//cmd1
Uint8Array(15) [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]

// TypedArray -> ArrayBuffer
cmd1.buffer
// cmd1.buffer
ArrayBuffer(15) {}
    [[Int8Array]]: Int8Array(15)[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
    [[Uint8Array]]: Uint8Array(15)[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
    byteLength: (...)
    __proto__: ArrayBuffer

数据写入和读取

数据写入

0x是16进制的前缀,H是16进制的后缀。另后缀

  • B,Binary(二进制);
  • H,Hex(十六进制);
  • O,Octal(八进制);
  • D,Decimal(十进制)。
// eg.
cmd1[10] = 0x20 // (数据定义来自产品说明)高四位是用户组数:2表示用户组号是P2;低四位是用户身体素质;0:普通人;1:业余运动员;2:专业运动员;

0x20转换为二进制为100000,即00100000,从左到右为高位到低位。高四位是用户组数,即0010转换为10进制是2,表示用户组号是P2,低四位是用户身体素质,0000转换为10进制是0,表示普通人,所以是0x20是p2 普通人

数据读取

BLE数据包传输规定了一次只能传输20byte,所以如果数据量较大,需要做分包传输处理

小程序生命周期

隐藏/卸载 显示/加载

onLoad: wx.navigateTowx.redirectTowx.reLaunch
onShow: wx.navigateTowx.redirectTowx.navigateBackwx.reLaunch、选择照片

onHide: wx.navigateTo、选择照片
onUnload:wx.redirectTowx.navigateBackwx.reLaunch

小概括

wx.navigateBack只会onshow 不会onload,其余(除了wx.switchTab) 两者都会
wx.navigateTo只会onhide不会onunload,其余都是onunload

小程序官方文档-蓝牙api

https://developers.weixin.qq.com/miniprogram/dev/api/device/bluetooth/wx.openBluetoothAdapter.html

有关微信小程序连接蓝牙设备并传递数据的更多相关文章

  1. ruby - 解析 RDFa、微数据等的最佳方式是什么,使用统一的模式/词汇(例如 schema.org)存储和显示信息 - 2

    我主要使用Ruby来执行此操作,但到目前为止我的攻击计划如下:使用gemsrdf、rdf-rdfa和rdf-microdata或mida来解析给定任何URI的数据。我认为最好映射到像schema.org这样的统一模式,例如使用这个yaml文件,它试图描述数据词汇表和opengraph到schema.org之间的转换:#SchemaXtoschema.orgconversion#data-vocabularyDV:name:namestreet-address:streetAddressregion:addressRegionlocality:addressLocalityphoto:i

  2. ruby - 续集在添加关联时访问many_to_many连接表 - 2

    我正在使用Sequel构建一个愿望list系统。我有一个wishlists和itemstable和一个items_wishlists连接表(该名称是续集选择的名称)。items_wishlists表还有一个用于facebookid的额外列(因此我可以存储opengraph操作),这是一个NOTNULL列。我还有Wishlist和Item具有续集many_to_many关联的模型已建立。Wishlist类也有:selectmany_to_many关联的选项设置为select:[:items.*,:items_wishlists__facebook_action_id].有没有一种方法可以

  3. ruby - 无法在 60 秒内获得稳定的 Firefox 连接 (127.0.0.1 :7055) - 2

    我使用的是Firefox版本36.0.1和Selenium-Webdrivergem版本2.45.0。我能够创建Firefox实例,但无法使用脚本继续进行进一步的操作无法在60秒内获得稳定的Firefox连接(127.0.0.1:7055)错误。有人能帮帮我吗? 最佳答案 我遇到了同样的问题。降级到firefoxv33后一切正常。您可以找到旧版本here 关于ruby-无法在60秒内获得稳定的Firefox连接(127.0.0.1:7055),我们在StackOverflow上找到一个类

  4. ruby - Ruby 有 `Pair` 数据类型吗? - 2

    有时我需要处理键/值数据。我不喜欢使用数组,因为它们在大小上没有限制(很容易不小心添加超过2个项目,而且您最终需要稍后验证大小)。此外,0和1的索引变成了魔数(MagicNumber),并且在传达含义方面做得很差(“当我说0时,我的意思是head...”)。散列也不合适,因为可能会不小心添加额外的条目。我写了下面的类来解决这个问题:classPairattr_accessor:head,:taildefinitialize(h,t)@head,@tail=h,tendend它工作得很好并且解决了问题,但我很想知道:Ruby标准库是否已经带有这样一个类? 最佳

  5. ruby - rails 3 redirect_to 将参数传递给命名路由 - 2

    我没有找到太多关于如何执行此操作的信息,尽管有很多关于如何使用像这样的redirect_to将参数传递给重定向的建议:action=>'something',:controller=>'something'在我的应用程序中,我在路由文件中有以下内容match'profile'=>'User#show'我的表演Action是这样的defshow@user=User.find(params[:user])@title=@user.first_nameend重定向发生在同一个用户Controller中,就像这样defregister@title="Registration"@user=Use

  6. ruby-on-rails - 如何生成传递一些自定义参数的 `link_to` URL? - 2

    我正在使用RubyonRails3.0.9,我想生成一个传递一些自定义参数的link_toURL。也就是说,有一个articles_path(www.my_web_site_name.com/articles)我想生成如下内容:link_to'Samplelinktitle',...#HereIshouldimplementthecode#=>'http://www.my_web_site_name.com/articles?param1=value1¶m2=value2&...我如何编写link_to语句“alàRubyonRailsWay”以实现该目的?如果我想通过传递一些

  7. ruby - 我如何添加二进制数据来遏制 POST - 2

    我正在尝试使用Curbgem执行以下POST以解析云curl-XPOST\-H"X-Parse-Application-Id:PARSE_APP_ID"\-H"X-Parse-REST-API-Key:PARSE_API_KEY"\-H"Content-Type:image/jpeg"\--data-binary'@myPicture.jpg'\https://api.parse.com/1/files/pic.jpg用这个:curl=Curl::Easy.new("https://api.parse.com/1/files/lion.jpg")curl.multipart_form_

  8. 世界前沿3D开发引擎HOOPS全面讲解——集3D数据读取、3D图形渲染、3D数据发布于一体的全新3D应用开发工具 - 2

    无论您是想搭建桌面端、WEB端或者移动端APP应用,HOOPSPlatform组件都可以为您提供弹性的3D集成架构,同时,由工业领域3D技术专家组成的HOOPS技术团队也能为您提供技术支持服务。如果您的客户期望有一种在多个平台(桌面/WEB/APP,而且某些客户端是“瘦”客户端)快速、方便地将数据接入到3D应用系统的解决方案,并且当访问数据时,在各个平台上的性能和用户体验保持一致,HOOPSPlatform将帮助您完成。利用HOOPSPlatform,您可以开发在任何环境下的3D基础应用架构。HOOPSPlatform可以帮您打造3D创新型产品,HOOPSSDK包含的技术有:快速且准确的CAD

  9. ruby - 在 Ruby 中按名称传递函数 - 2

    如何在Ruby中按名称传递函数?(我使用Ruby才几个小时,所以我还在想办法。)nums=[1,2,3,4]#Thisworks,butismoreverbosethanI'dlikenums.eachdo|i|putsiend#InJS,Icouldjustdosomethinglike:#nums.forEach(console.log)#InF#,itwouldbesomethinglike:#List.iternums(printf"%A")#InRuby,IwishIcoulddosomethinglike:nums.eachputs在Ruby中能不能做到类似的简洁?我可以只

  10. 【鸿蒙应用开发系列】- 获取系统设备信息以及版本API兼容调用方式 - 2

    在应用开发中,有时候我们需要获取系统的设备信息,用于数据上报和行为分析。那在鸿蒙系统中,我们应该怎么去获取设备的系统信息呢,比如说获取手机的系统版本号、手机的制造商、手机型号等数据。1、获取方式这里分为两种情况,一种是设备信息的获取,一种是系统信息的获取。1.1、获取设备信息获取设备信息,鸿蒙的SDK包为我们提供了DeviceInfo类,通过该类的一些静态方法,可以获取设备信息,DeviceInfo类的包路径为:ohos.system.DeviceInfo.具体的方法如下:ModifierandTypeMethodDescriptionstatic StringgetAbiList​()Obt

随机推荐