当前位置: 首页 > news >正文

第二百二十六回

文章目录

  • 1. 概念介绍
  • 2. 具体细节
    • 2.1 发现服务
    • 2.2 发现特征值
    • 2.3 发送数据
    • 2.4 接收数据
  • 3. 代码与效果
    • 3.1
    • 3.2 运行效果
  • 4. 经验总结

我们在上一章回中介绍了"连接蓝牙设备的细节"相关的内容,本章回中将介绍通过蓝牙发送数据的细节.闲话休提,让我们一起Talk Flutter吧。

1. 概念介绍

我们在本章回中介绍的通过蓝牙设备发送数据仍然使用flutter_blue_plus包提供的接口,我们在第一百一十九回章回中介过通过蓝牙发送数据的方法,不过还有一些
细节问题需要注意,本章回中将详细介绍通过蓝牙发送数据的细节内容。

2. 具体细节

通过蓝牙发送数据的细节主要包含发现服务(BluetoothService)和特征值(Characteristic),发送数据和接收数据。我们把这些内容分成各个小节来介绍。

2.1 发现服务

发现服务使用包中的discoverServices()方法就可以,不过蓝牙设备的服务比较多,需要进行遍历操作,在遍历过程中找到需要操作的服务,通常是通过服务的uuid
来判断服务是否是我们需要操作的某个服务。此外,蓝牙设备的服务具有读写特性,也可以依据读写特性来区分服务。

2.2 发现特征值

发现特征值不需要专门的方法,通过服务的characteristics属性就可以获取到该服务的特征值,该属性是一个列表,包含服务中的多个特征值。我们需要对特征值列表
进行遍历操作,在遍历过程中找到需要操作的特征值,通常是通过特征值的uuid来判断特征值是否是我们需要操作的某个特征值。此外,蓝牙设备的特征值类似服务,也
具有读写特性,也可以依据读写特性来区分不同的特征值。

2.3 发送数据

2.4 接收数据

通过蓝牙设备读写数据有两种方法,一种是读写Characteristics,另外一种是读写Descriptor.我们在本章回中介绍的读写数据本质上是读写Characteristics。
flutter_blue_plus包提供了相关的接口去读写Characteristics,本章回中将介绍如何使用这些接口去读写数据。

  1. 获取服务,通过包中的discoverServices()方法来获取服务;
  2. 通过服务的characteristics属性获取characteristics;
  3. 使用characteristics中的read()和write()方法来读写数据;
  4. 使用characteristics中的onValueReceived属性监听读写结果,
  5. 该属性是Stream类型,和蓝牙连接状态的监听方法一样;

3. 代码与效果

3.1

上面小节中介绍的实现方法比较抽象,接下来我们通过具体的代码来演示如何给蓝牙设备读写数据;

  Future<List<BluetoothService>> discoverServices(BluetoothDevice device) async {List<BluetoothService> services = await device.discoverServices();List<BluetoothCharacteristic> characteristics;Stream<List<int>> readValueChanged;Stream<List<int>> writeValueChanged;for (var element in services) {// log.i("service: ${element.toString()}");characteristics = element.characteristics;for(var char in characteristics) {if(char.properties.read) {readValueChanged = char.onValueReceived;readValueChanged.listen((event) {log.i('read chara feedback: ${event.toString()}');});readCharacteristics(char);}if(char.properties.write) {writeValueChanged = char.onValueReceived;writeValueChanged.listen((event) {log.i('write chara feedback: ${getNiceHexArray(event)}');},onError:(e){log.i('write chara error: ${e.toString()}');},onDone: () => log.i('write chara done'),);writeCharacteristics(char);}}}return services;}///依据指定的UUID读取特征值void readCharacteristics (BluetoothCharacteristic characteristic) async{if(PrivateKey.searchServiceUuid != characteristic.characteristicUuid.toString()) {return null;}List<int> value =  await characteristic.read();log.w('read characteristic:  ${value.toString()}');}///依据指定的UUID写入特征值void writeCharacteristics (BluetoothCharacteristic characteristic) async{if(PrivateKey.writeCharacteristicUuid != characteristic.characteristicUuid.toString()) {return null;}List<int> value = [12,13,14];await characteristic.write(value,withoutResponse: false);log.w('write characteristic:  ${value.toString()}');}

3.2 运行效果

上面示例代码中把读写操作封装成了独立的方法,这样可以降低代码的耦合性。同时还指定了characteristic的uuid。这样可以对特定uuid的characteristic进
行读写操作。 我们还在代码中监听了读写操作的结果,以便我们了解读写操作的情况。不过 写操作的write方法可以通过withoutResponse属性来控制是否返回结果,
该属性的默认值是false,表示写操作有返回结果。

4. 经验总结

  • Service,Characteristic和Descriptor都是蓝牙设备的属性,而且每个蓝牙都有这些属性;
  • Service,Characteristic和Descriptor环环相扣:获取到Service后才能获取Characteristic,获取到Characteristic后才能获取Descriptor;
  • 一个蓝牙设备可能会有多个service,我们可以通过它的uuid来区分不同的service;
  • 一个serice可能会有多个characteristic,我们可以通过它的uuid来区分不同的characteristic;
  • 一个characteristic可以具备读写属性中的任意一种,或者二种属性都具备;
    分享完这些经验后,我们回头再看看代码中的各种for循环和if条件判断语句,它们都是为了遍历多个值.
    看官们,与"通过蓝牙发送数据的细节"相关的内容就介绍到这里,欢迎大家在评论区交流与讨论!

相关文章:

第二百二十六回

文章目录 1. 概念介绍2. 具体细节2.1 发现服务2.2 发现特征值2.3 发送数据2.4 接收数据 3. 代码与效果3.13.2 运行效果 4. 经验总结 我们在上一章回中介绍了"连接蓝牙设备的细节"相关的内容&#xff0c;本章回中将介绍通过蓝牙发送数据的细节.闲话休提&#xff0c;让…...

ubuntu常用指令

Ubuntu是一个基于Linux的操作系统&#xff0c;它使用了大量的命令行指令。这些指令对于管理系统、处理文件、监控资源和执行各种任务都非常有用。以下是一些常用的Ubuntu命令&#xff1a; 系统管理 sudo&#xff1a;提供管理员权限执行命令&#xff08;例如 sudo apt update&a…...

Quartz.NET 事件监听器

1、调度器监听器 调度器本身收到的一些事件通知&#xff0c;接口ISchedulerListener&#xff0c;如作业的添加、删除、停止、挂起等事件通知&#xff0c;调度器的启动、关闭、出错等事件通知&#xff0c;触发器的暂停、挂起等事件通知&#xff0c;接口部分定义如下&#xff1a…...

2024-AI人工智能学习-安装了pip install pydot但是还是报错

2024-AI人工智能学习-安装了pip install pydot但是还是报错 出现这样子的错误&#xff1a; /usr/local/bin/python3.11 /Users/wangyang/PycharmProjects/studyPython/tf_model.py 2023-12-24 22:59:02.238366: I tensorflow/core/platform/cpu_feature_guard.cc:182] This …...

在使用mapstruct,想忽略掉List<DTO>字段里面的,`data` 字段的映射, 如何写ignore: 使用@IterableMapping

在使用mapstruct,想忽略掉List字段里面的,data 字段的映射, 如何写ignore 代码如下: public interface AssigmentFileMapper {AssigmentFileDTO assigmentFileToAssigmentFileDTO(AssigmentFile assigmentFile);AssigmentFile assigmentFileDTOToAssigmentFile(Assigment…...

ansible-playbook的Temlates模块 tags模块 Roles模块

Temlates模块 jinja模板架构&#xff0c;通过模板可以实现向模板文件传参(python转义)把占位符参数传到配置文件中去,生产一个目标文本文件&#xff0c;传递变量到需要的配置文件当中 &#xff08;web开发&#xff09; nginx.conf.j2 早文件当中配置的是占位符&#xff08;声明…...

Canal使用详解

Canal介绍 Canal是阿里巴巴开发的MySQL binlog增量订阅&消费组件&#xff0c;Canal是基于MySQL二进制日志的高性能数据同步系统。在阿里巴巴集团中被广泛使用&#xff0c;以提供可靠的低延迟增量数据管道。Canal Server能够解析MySQL Binlog并订阅数据更改&#xff0c;而C…...

【经典LeetCode算法题目专栏分类】【第8期】滑动窗口:最小覆盖子串、字符串排列、找所有字母异位词、 最长无重复子串

《博主简介》 小伙伴们好&#xff0c;我是阿旭。专注于人工智能AI、python、计算机视觉相关分享研究。 ✌更多学习资源&#xff0c;可关注公-仲-hao:【阿旭算法与机器学习】&#xff0c;共同学习交流~ &#x1f44d;感谢小伙伴们点赞、关注&#xff01; 《------往期经典推荐--…...

C#和.Net常见问题记录

什么是.NET框架&#xff0c;.NET框架与C#(C Sharp)是什么关系&#xff1f; .NET框架是由Microsoft设计和维护的软件开发框架&#xff0c;.NET框架提供了C#(编程语言)开发的所有基础设施和支持。通过使用C#和.NET框架&#xff0c;开发者可以轻松地开发高质量、高效率的应…...

FAQ:Container Classes篇

1、Why should I use container classes rather than simple arrays?&#xff08;为什么应该使用容器类而不是简单的数组&#xff1f;&#xff09; In terms of time and space, a contiguous array of any kind is just about the optimal construct for accessing a sequen…...

每日一题(LeetCode)----栈和队列--滑动窗口最大值

每日一题(LeetCode)----栈和队列–滑动窗口最大值 1.题目&#xff08;239. 滑动窗口最大值&#xff09; 给你一个整数数组 nums&#xff0c;有一个大小为 k 的滑动窗口从数组的最左侧移动到数组的最右侧。你只可以看到在滑动窗口内的 k 个数字。滑动窗口每次只向右移动一位。 …...

13.bash shell中的if-then语句

文章目录 shell中的流控制if语句if语句if-then语句if-then-else 语句 test命令数值比较字符串比较文件比较case语句 欢迎访问个人网络日志&#x1f339;&#x1f339;知行空间&#x1f339;&#x1f339; shell中的流控制if语句 简单的脚本可以只包含顺序执行的命令&#xff0…...

深入了解 Python 的 import 语句

在 Python 中&#xff0c;import 语句是一个关键的功能&#xff0c;用于在程序中引入模块和包。本文将深入讨论 import 语句的各种用法、注意事项以及一些高级技巧&#xff0c;以帮助你更好地理解和使用这一功能。 概念介绍 package 通常对应一个文件夹&#xff0c;下面可以有…...

接口测试 — 11.logging日志模块处理流程

1、概括理解 了解了四大组件的基本定义之后&#xff0c;我们通过图示的方式来理解下信息的传递过程&#xff1a; 也就是获取的日志信息&#xff0c;进入到Logger日志器中&#xff0c;传递给处理器确定要输出到哪里&#xff0c;然后进行过滤器筛选&#xff0c;通过后再按照定义…...

Hago 的 Spark on ACK 实践

作者&#xff1a;华相 Hago 于 2018 年 4 月上线&#xff0c;是欢聚集团旗下的一款多人互动社交明星产品。Hago 融合优质的匹配能力和多样化的垂类场景&#xff0c;提供互动游戏、多人语音、视频直播、 3D 虚拟形象互动等多种社交玩法&#xff0c;致力于为用户打造高效、多样、…...

mac传输文件到windows

前言 由于mac系统与windows系统文件格式不同&#xff0c;通过U盘进行文件拷贝时&#xff0c;导致无法拷贝。官方解决方案如下&#xff0c;但是描述的比较模糊。看我的操作步骤即可。 https://support.apple.com/zh-cn/guide/mac-help/mchlp1657/12.0/mac/12.6 前提条件 mac与…...

trtc-electron-sdk的demo中添加更新功能以及出现的报错问题

1、官网demo下载地址 点击下载 按照官网demo说明文档进行安装和运行 2、添加electron-updater npm install electron-updater根据项目需求安装对应的版本&#xff0c;建议使用5.2.1 3、创建一个handleUpdater.js文件&#xff0c;和package.json同级 // const { ipcMain } …...

什么是流量攻击? 流量攻击怎么处理?

由于DDoS攻击往往采取合法的数据请求技术&#xff0c;再加上傀儡机器&#xff0c;造成DDoS攻击成为最难防御的网络攻击之一。据美国最新的安全损失调查报告&#xff0c;DDoS攻击所造成的经济损失已经跃居第一。 传统的网络设备和周边安全技术&#xff0c;例如防火墙和IDSs(Intr…...

【大数据】NiFi 的基本使用

NiFi 的基本使用 1.NiFi 的安装与使用1.1 NiFi 的安装1.2 各目录及主要文件 2.NiFi 的页面使用2.1 主页面介绍2.2 面板介绍 3.NiFi 的工作方式3.1 基本方式3.2 选择处理器3.3 组件状态3.4 组件的配置3.4.1 SETTINGS&#xff08;通用配置&#xff09;3.4.2 SCHEDULING&#xff0…...

5 分钟内搭建一个免费问答机器人:Milvus + LangChain

搭建一个好用、便宜又准确的问答机器人需要多长时间&#xff1f; 答案是 5 分钟。只需借助开源的 RAG 技术栈、LangChain 以及好用的向量数据库 Milvus。必须要强调的是&#xff0c;该问答机器人的成本很低&#xff0c;因为我们在召回、评估和开发迭代的过程中不需要调用大语言…...

[特殊字符] 智能合约中的数据是如何在区块链中保持一致的?

&#x1f9e0; 智能合约中的数据是如何在区块链中保持一致的&#xff1f; 为什么所有区块链节点都能得出相同结果&#xff1f;合约调用这么复杂&#xff0c;状态真能保持一致吗&#xff1f;本篇带你从底层视角理解“状态一致性”的真相。 一、智能合约的数据存储在哪里&#xf…...

测试微信模版消息推送

进入“开发接口管理”--“公众平台测试账号”&#xff0c;无需申请公众账号、可在测试账号中体验并测试微信公众平台所有高级接口。 获取access_token: 自定义模版消息&#xff1a; 关注测试号&#xff1a;扫二维码关注测试号。 发送模版消息&#xff1a; import requests da…...

Xshell远程连接Kali(默认 | 私钥)Note版

前言:xshell远程连接&#xff0c;私钥连接和常规默认连接 任务一 开启ssh服务 service ssh status //查看ssh服务状态 service ssh start //开启ssh服务 update-rc.d ssh enable //开启自启动ssh服务 任务二 修改配置文件 vi /etc/ssh/ssh_config //第一…...

React第五十七节 Router中RouterProvider使用详解及注意事项

前言 在 React Router v6.4 中&#xff0c;RouterProvider 是一个核心组件&#xff0c;用于提供基于数据路由&#xff08;data routers&#xff09;的新型路由方案。 它替代了传统的 <BrowserRouter>&#xff0c;支持更强大的数据加载和操作功能&#xff08;如 loader 和…...

最新SpringBoot+SpringCloud+Nacos微服务框架分享

文章目录 前言一、服务规划二、架构核心1.cloud的pom2.gateway的异常handler3.gateway的filter4、admin的pom5、admin的登录核心 三、code-helper分享总结 前言 最近有个活蛮赶的&#xff0c;根据Excel列的需求预估的工时直接打骨折&#xff0c;不要问我为什么&#xff0c;主要…...

postgresql|数据库|只读用户的创建和删除(备忘)

CREATE USER read_only WITH PASSWORD 密码 -- 连接到xxx数据库 \c xxx -- 授予对xxx数据库的只读权限 GRANT CONNECT ON DATABASE xxx TO read_only; GRANT USAGE ON SCHEMA public TO read_only; GRANT SELECT ON ALL TABLES IN SCHEMA public TO read_only; GRANT EXECUTE O…...

srs linux

下载编译运行 git clone https:///ossrs/srs.git ./configure --h265on make 编译完成后即可启动SRS # 启动 ./objs/srs -c conf/srs.conf # 查看日志 tail -n 30 -f ./objs/srs.log 开放端口 默认RTMP接收推流端口是1935&#xff0c;SRS管理页面端口是8080&#xff0c;可…...

Java入门学习详细版(一)

大家好&#xff0c;Java 学习是一个系统学习的过程&#xff0c;核心原则就是“理论 实践 坚持”&#xff0c;并且需循序渐进&#xff0c;不可过于着急&#xff0c;本篇文章推出的这份详细入门学习资料将带大家从零基础开始&#xff0c;逐步掌握 Java 的核心概念和编程技能。 …...

[Java恶补day16] 238.除自身以外数组的乘积

给你一个整数数组 nums&#xff0c;返回 数组 answer &#xff0c;其中 answer[i] 等于 nums 中除 nums[i] 之外其余各元素的乘积 。 题目数据 保证 数组 nums之中任意元素的全部前缀元素和后缀的乘积都在 32 位 整数范围内。 请 不要使用除法&#xff0c;且在 O(n) 时间复杂度…...

Hive 存储格式深度解析:从 TextFile 到 ORC,如何选对数据存储方案?

在大数据处理领域&#xff0c;Hive 作为 Hadoop 生态中重要的数据仓库工具&#xff0c;其存储格式的选择直接影响数据存储成本、查询效率和计算资源消耗。面对 TextFile、SequenceFile、Parquet、RCFile、ORC 等多种存储格式&#xff0c;很多开发者常常陷入选择困境。本文将从底…...