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

《数据驱动防折叠:利用企微API与数据分析平台构建智能发送决策系统》

一、问题背景企微群发折叠与用户的历史互动行为紧密相关。对长期未交互的用户发送营销内容&#xff0c;折叠概率极高&#xff1b;而对活跃用户发送相似内容&#xff0c;则可能正常显示。因此&#xff0c;单纯从发送端进行策略优化是不够的&#xff0c;必须引入用户维度的数据&a…...

技术揭秘:QtScrcpy如何实现跨平台Android投屏与低延迟控制

技术揭秘&#xff1a;QtScrcpy如何实现跨平台Android投屏与低延迟控制 【免费下载链接】QtScrcpy Android实时投屏软件&#xff0c;此应用程序提供USB(或通过TCP/IP)连接的Android设备的显示和控制。它不需要任何root访问权限 项目地址: https://gitcode.com/barry-ran/QtScr…...

保姆级教程:在OBBDetection项目中为DOTA数据集定制检测结果可视化(mmdetection 2.2)

深度定制OBBDetection检测结果可视化&#xff1a;DOTA数据集高级实践指南 在旋转目标检测领域&#xff0c;DOTA数据集因其复杂的航拍场景和多角度目标特性&#xff0c;对结果可视化提出了独特挑战。本文将带您从零构建一套完整的可视化解决方案&#xff0c;涵盖从基础配置到高级…...

如何用网盘直链下载助手突破限制提升效率:5个实用技巧

如何用网盘直链下载助手突破限制提升效率&#xff1a;5个实用技巧 【免费下载链接】Online-disk-direct-link-download-assistant 一个基于 JavaScript 的网盘文件下载地址获取工具。基于【网盘直链下载助手】修改 &#xff0c;支持 百度网盘 / 阿里云盘 / 中国移动云盘 / 天翼…...

LeagueAkari:英雄联盟智能辅助工具完全指南

LeagueAkari&#xff1a;英雄联盟智能辅助工具完全指南 【免费下载链接】League-Toolkit 兴趣使然的、简单易用的英雄联盟工具集。支持战绩查询、自动秒选等功能。基于 LCU API。 项目地址: https://gitcode.com/gh_mirrors/le/League-Toolkit LeagueAkari是一款基于英雄…...

开源字体实用指南:Poppins字体家族的全方位应用策略

开源字体实用指南&#xff1a;Poppins字体家族的全方位应用策略 【免费下载链接】Poppins Poppins, a Devanagari Latin family for Google Fonts. 项目地址: https://gitcode.com/gh_mirrors/po/Poppins 价值定位&#xff1a;如何让开源字体成为项目的视觉资产&#x…...

告别编码等待:LosslessCut的无损视频处理革命

告别编码等待&#xff1a;LosslessCut的无损视频处理革命 【免费下载链接】lossless-cut The swiss army knife of lossless video/audio editing 项目地址: https://gitcode.com/gh_mirrors/lo/lossless-cut 副标题&#xff1a;掌握零质量损失剪辑、多轨道精细控制与批…...

Qwen3-TTS开源大模型效果展示:俄文/葡萄牙文/意大利文等小语种高自然度语音生成

Qwen3-TTS开源大模型效果展示&#xff1a;俄文/葡萄牙文/意大利文等小语种高自然度语音生成 你听过AI用俄语讲普希金的诗吗&#xff1f;或者用意大利语念一段歌剧台词&#xff1f;过去&#xff0c;想让AI生成地道的小语种语音&#xff0c;要么音色机械&#xff0c;要么口音奇怪…...

Flutter项目卡在‘assembleDebug’?Gradle配置优化全攻略

1. 为什么Flutter项目会卡在assembleDebug阶段&#xff1f; 这个问题困扰过无数Flutter开发者&#xff0c;尤其是刚入门的新手。当你满怀期待地运行flutter run命令&#xff0c;结果控制台卡在Running Gradle task assembleDebug...一动不动&#xff0c;那种感觉就像等一辆永远…...

OFA视觉蕴含模型效果展示:抽象艺术作品与评论文本关联性

OFA视觉蕴含模型效果展示&#xff1a;抽象艺术作品与评论文本关联性 1. 引言&#xff1a;当抽象艺术遇见智能理解 想象一下这样的场景&#xff1a;你站在一幅抽象画前&#xff0c;画布上是狂放的笔触和难以名状的色彩组合。旁边有人评论说&#xff1a;"这幅画表达了宇宙…...