第二百二十六回

文章目录

  • 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条件判断语句,它们都是为了遍历多个值.
    看官们,与"通过蓝牙发送数据的细节"相关的内容就介绍到这里,欢迎大家在评论区交流与讨论!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/528268.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

excel导入mysql 截断_解决Excel导入数据库时出现的文本截断问题

问题在把Excel导入到数据库中时&#xff0c;发生文本截断问题&#xff1a;即导入的数据每行只有一部分&#xff0c;原始的Excel数据为&#xff1a;忽略错误导入SQLServer2008过程中&#xff0c;如果源数据和目标数据类型不匹配会导入失败&#xff0c;所以导入数据时会忽略错误&…

map multimapc++_黑马C++视频笔记《STL之map/multimap》

/* map/multimap容器* map/multimap属于关联式容器&#xff0c;底层结构是用二叉树实现。* - map中所有元素都是pair&#xff1b;* - pair中第一个元素为key(键值)&#xff0c;起到索引作用&#xff0c;第二个元素为value(实值)&#xff1b;* - 所有元素都会根据元素的键值自动…

mysql generator备注_MyBatis Generator 自定义生成注释

注释生成器为了生成db里面的注释&#xff0c;必须自定义注释生成器EmptyCommentGenerator&#xff1a;import org.mybatis.generator.api.CommentGenerator;import org.mybatis.generator.api.IntrospectedColumn;import org.mybatis.generator.api.IntrospectedTable;import o…

mysql表添加完整性约束_SQL语句——完整性约束

1.MySQL支持的完整性约束a.主键约束特点&#xff1a;唯一且非空主键可以由一个字段组成&#xff0c;也可以由多个字段组成如果主键由一个字段组成&#xff0c;既可以添加到列级&#xff0c;也可以添加到表级。如果主键由多个字段组成&#xff0c;则只能添加到表级。(1)在字段的…

通信线路工程验收规范 gb51171-2016_老杨一建通信学堂通信线路工程施工技术

引言&#xff1a;本章节以通信线路工程施工建设为主题&#xff0c;涵盖通信光(电)缆施工通用技术、架空、直埋、管道还有综合布线工程施工技术&#xff0c;深入浅出介绍通信线路工程建设中各环节的工作内容和涉及的相关规范。知识归纳卡名 称&#xff1a;1L412050 章 节…

python制作测试报告_使用 python 生成 extent report 测试报告

背景一直使用 HTMLTestRunner 生成 app 自动化的测试报告内容&#xff0c;虽然加了截图的展示&#xff0c;还是感觉报告不够好看。allure 报告内容可以&#xff0c;但是要以 pytest 管理测试 case&#xff0c;且 pytest 会执行所有以 test_命名的 case&#xff0c;测试结果只有…

r语言electricity数据集_R语言实战学习

《R语言实战》中文电子版提取码&#xff1a;lx35已经学习打卡R语言22天了&#xff0c;可以说是初窥真容——基本了解R的数据和函数&#xff1b;作为程序语言&#xff0c;就是要多练习&#xff0c;多领悟&#xff0c;在实战中发现问题并解决问题。所以&#xff0c;就以《R语言实…

mysql查看系统可用字符集_MySQL查看所有可用的字符集

MySQL查看所有可用的字符集Enter password:Welcome to the MySQL monitor. Commands end with ; or \g.Your MySQL connection id is 6190Server version: 5.6.24-log MySQL Community Server (GPL)Copyright (c) 2000, 2015, Oracle and/or its affiliates. All rights reserv…

mysql环形复制的弊端_Docker+阿里云centos7+MySQL主从环形复制踩坑记

老规矩&#xff0c;先列坑slave链接master的时候&#xff0c;一直提示2003错误修改了iptables后&#xff0c;docker 下的容器无法正常使用配置正确后&#xff0c;创建新的db部分机器没有同步Got fatal error 1236 from master when reading data from binary log: unknown erro…

mysql general clomun_关于MySQL索引index杂谈

MySQL建索引命令create index index_name on tablename(clomun_name.....);比如建了CREATE INDEX O_N_P_D ON t_db_netspeed(o,n,p,d)建好索引之后&#xff0c;使用SELECT 命令进行查询SELECT COUNT(*) FROM t_db_netspeed WHERE O1这句话也会用到前面建立的索引 O_N_P_D&…

pythoncount函数怎么用_python中count函数简单的实例讲解

python中count函数的用法count()函数描述&#xff1a;统计字符串里某个字符出现的次数&#xff0c;可以选择字符串索引的起始位置和结束位置。语法&#xff1a;str.count("char", start,end) 或 str.count("char")返回值&#xff1a;整型参数说明&#xff…

twisted mysql_在Twisted下用MySQLadbapi获取自增id

D jango的ORM有一个很便捷的功能&#xff0c;其实也应该说是一个很基本的功能吧。就是在对一个model调用 save() 插入到数据库后&#xff0c;会将创建的D jango的ORM有一个很便捷的功能&#xff0c;其实也应该说是一个很基本的功能吧。就是在对一个model调用 save() 插入到数据…

java客户端_Java常用的Http client客户端

Http Client应用场景&#xff1a;Http协议是最重要的网络协议之一&#xff0c;目前移动端的开发、javaweb前后端分离架构&#xff0c;使越来越多的java应用使用http协议访问资源。Http client 大多数场景使用在多个服务之间相互调用rest api&#xff0c;特别是现在微服务架构的…

java 新浪邮箱_使用javamail发送邮件,sina的邮箱作为发信人不行

我参照网上&#xff0c;写了一个简单的使用javamail发送邮件的程序&#xff0c;使用一般的邮件服务器作为发件人&#xff0c;程序都很正常&#xff1b;但使用smtp.sina.com.cn作为邮件服务器地址的发件人时&#xff0c;程序却验证失败&#xff01;这是什么原因&#xff1f;程序…

java des3加密_JAVA加密算法(3)- 对称加密算法(DES、3DES、AES)

对称加密算法概念加密密钥和解密密钥相同&#xff0c;大部分算法加密揭秘过程互逆。特点&#xff1a;算法公开、(相比非对称加密)计算量小、加密速度快、效率高。弱点&#xff1a;双方都使用同样的密钥&#xff0c;安全性得不到保证。常用对称加密算法DES(Data Encryption Stan…

android jni 调用java对象_Android NDK开发之Jni调用Java对象

本地代码中使用Java对象通过使用合适的JNI函数&#xff0c;你可以创建Java对象&#xff0c;get、set 静态(static)和 实例(instance)的域&#xff0c;调用静态(static)和实例(instance)函数。JNI通过ID识别域和方法&#xff0c;一个域或方法的ID是任何处理域和方法的函数的必须…

docker 容器端口访问不到_docker容器无法访问宿主机端口的解决

最近在工作时遇到一个问题,docker容器无法访问宿主机的redis,telent6379端口不通。 经排查发现,该服务器启用了防火墙,防火墙把6379的端口的访问授权给docker0网卡访问即可。 操作如下: firewall-cmd --permanent --zone=trusted --change-interface=docker0 firewall-cmd…

java public权限_Java public 访问权限

Java public 访问权限接下来&#xff0c;我们准备为大家介绍“public 访问权限”。在前面的学习中&#xff0c;我们已经接触过public这个关键字&#xff0c;就是在入口方法 main的前面&#xff0c;现在我们可以来回顾一下对应的代码&#xff1a;public class MyTest{publicstat…

java timer线程结束_Java线程Timer定时器用法详细总结

定时/计划功能主要使用的就是Timer对象&#xff0c;它在内部还是使用多线程的方式进行处理&#xff0c;所以它和线程技术还是有非常大的关联。Timer类主要作用就是设置计划任务&#xff0c;但封装任务的类却是TimerTask类。TimerTask类是一个抽象类。执行任务的时间晚于当前时间…

java在创建对象时必须_Java中5种创建对象的方式

以下是一些在Java中创建对象的方法&#xff1a;1、 使用new关键字使用new关键字是创建对象的最基本方法。这是在java中创建对象的最常见方法。几乎99%的对象都是这样创建的。通过使用这个方法&#xff0c;我们可以调用我们想要调用的任何构造函数(无参数或参数化构造函数)。//J…