第二百二十六回
我们在上一章回中介绍了"连接蓝牙设备的细节"相关的内容,本章回中将介绍通过蓝牙发送数据的细节.闲话休提,让我们一起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,本章回中将介绍如何使用这些接口去读写数据。
- 获取服务,通过包中的discoverServices()方法来获取服务;
- 通过服务的characteristics属性获取characteristics;
- 使用characteristics中的read()和write()方法来读写数据;
- 使用characteristics中的onValueReceived属性监听读写结果,
- 该属性是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条件判断语句,它们都是为了遍历多个值.
看官们,与"通过蓝牙发送数据的细节"相关的内容就介绍到这里,欢迎大家在评论区交流与讨论!
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。 如若内容造成侵权/违法违规/事实不符,请联系我的编程经验分享网邮箱:veading@qq.com进行投诉反馈,一经查实,立即删除!