当前位置: 首页 > 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;因为我们在召回、评估和开发迭代的过程中不需要调用大语言…...

地震勘探——干扰波识别、井中地震时距曲线特点

目录 干扰波识别反射波地震勘探的干扰波 井中地震时距曲线特点 干扰波识别 有效波&#xff1a;可以用来解决所提出的地质任务的波&#xff1b;干扰波&#xff1a;所有妨碍辨认、追踪有效波的其他波。 地震勘探中&#xff0c;有效波和干扰波是相对的。例如&#xff0c;在反射波…...

C++_核心编程_多态案例二-制作饮品

#include <iostream> #include <string> using namespace std;/*制作饮品的大致流程为&#xff1a;煮水 - 冲泡 - 倒入杯中 - 加入辅料 利用多态技术实现本案例&#xff0c;提供抽象制作饮品基类&#xff0c;提供子类制作咖啡和茶叶*//*基类*/ class AbstractDr…...

shell脚本--常见案例

1、自动备份文件或目录 2、批量重命名文件 3、查找并删除指定名称的文件&#xff1a; 4、批量删除文件 5、查找并替换文件内容 6、批量创建文件 7、创建文件夹并移动文件 8、在文件夹中查找文件...

java 实现excel文件转pdf | 无水印 | 无限制

文章目录 目录 文章目录 前言 1.项目远程仓库配置 2.pom文件引入相关依赖 3.代码破解 二、Excel转PDF 1.代码实现 2.Aspose.License.xml 授权文件 总结 前言 java处理excel转pdf一直没找到什么好用的免费jar包工具,自己手写的难度,恐怕高级程序员花费一年的事件,也…...

UDP(Echoserver)

网络命令 Ping 命令 检测网络是否连通 使用方法: ping -c 次数 网址ping -c 3 www.baidu.comnetstat 命令 netstat 是一个用来查看网络状态的重要工具. 语法&#xff1a;netstat [选项] 功能&#xff1a;查看网络状态 常用选项&#xff1a; n 拒绝显示别名&#…...

04-初识css

一、css样式引入 1.1.内部样式 <div style"width: 100px;"></div>1.2.外部样式 1.2.1.外部样式1 <style>.aa {width: 100px;} </style> <div class"aa"></div>1.2.2.外部样式2 <!-- rel内表面引入的是style样…...

拉力测试cuda pytorch 把 4070显卡拉满

import torch import timedef stress_test_gpu(matrix_size16384, duration300):"""对GPU进行压力测试&#xff0c;通过持续的矩阵乘法来最大化GPU利用率参数:matrix_size: 矩阵维度大小&#xff0c;增大可提高计算复杂度duration: 测试持续时间&#xff08;秒&…...

基于 TAPD 进行项目管理

起因 自己写了个小工具&#xff0c;仓库用的Github。之前在用markdown进行需求管理&#xff0c;现在随着功能的增加&#xff0c;感觉有点难以管理了&#xff0c;所以用TAPD这个工具进行需求、Bug管理。 操作流程 注册 TAPD&#xff0c;需要提供一个企业名新建一个项目&#…...

MySQL 索引底层结构揭秘:B-Tree 与 B+Tree 的区别与应用

文章目录 一、背景知识&#xff1a;什么是 B-Tree 和 BTree&#xff1f; B-Tree&#xff08;平衡多路查找树&#xff09; BTree&#xff08;B-Tree 的变种&#xff09; 二、结构对比&#xff1a;一张图看懂 三、为什么 MySQL InnoDB 选择 BTree&#xff1f; 1. 范围查询更快 2…...

Scrapy-Redis分布式爬虫架构的可扩展性与容错性增强:基于微服务与容器化的解决方案

在大数据时代&#xff0c;海量数据的采集与处理成为企业和研究机构获取信息的关键环节。Scrapy-Redis作为一种经典的分布式爬虫架构&#xff0c;在处理大规模数据抓取任务时展现出强大的能力。然而&#xff0c;随着业务规模的不断扩大和数据抓取需求的日益复杂&#xff0c;传统…...