Flutter笔记:使用蓝牙(基于Flutter Blue)

举报
jcLee95 发表于 2023/11/30 17:39:39 2023/11/30
【摘要】 Flutter笔记:使用蓝牙(基于Flutter Blue)
Flutter笔记
使用蓝牙


本文基于 Flutte Blue 库介绍在 Flutter 中使用蓝牙。这是一个至今可用,且相当受到欢迎的比较久以前的模块。目前仍然被广泛使用,且大量存在与一些旧的项目中,但是它日后可能将被新的 Flutter Blue Plus 库逐渐替代。



FlutterBlue是一个用于Flutter的蓝牙插件,它可以帮助开发者在Flutter应用中实现蓝牙功能。FlutterBlue的主要功能包括扫描附近的蓝牙设备,连接到蓝牙设备,发现设备的服务,读写设备的特性和描述符等。

FlutterBlue的使用场景非常广泛,例如,你可以使用FlutterBlue开发一个蓝牙设备管理应用,可以扫描和连接到附近的蓝牙设备,读取设备的信息,控制设备的功能等。你也可以使用FlutterBlue在你的应用中添加蓝牙功能,例如,你可以让你的应用通过蓝牙与其他设备通信,或者使用蓝牙传输数据等。



首先,你需要在你的Flutter项目中安装flutter_blue。你可以在你的pubspec.yaml文件中添加以下依赖:

dependencies:
  flutter_blue: ^0.8.0

然后,运行flutter packages get命令来获取包。


flutter_blue只支持Android SDK 19及以上版本。因此,你需要在你的android/app/build.gradle文件中更改minSdkVersion为19。你可以按照以下方式修改:

android {
  defaultConfig {
    minSdkVersion 19
  }
}

为了使用蓝牙功能,你需要在你的Android和iOS项目中添加蓝牙和位置权限。

对于Android,你需要在android/app/src/main/AndroidManifest.xml文件中添加以下权限:

<uses-permission android:name="android.permission.BLUETOOTH" />
<uses-permission android:name="android.permission.BLUETOOTH_ADMIN" />
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"/>

对于iOS,你需要在ios/Runner/Info.plist文件中添加以下权限:

<dict>
    <key>NSBluetoothAlwaysUsageDescription</key>
    <string>Need BLE permission</string>
    <key>NSBluetoothPeripheralUsageDescription</key>
    <string>Need BLE permission</string>
    <key>NSLocationAlwaysAndWhenInUseUsageDescription</key>
    <string>Need Location permission</string>
    <key>NSLocationAlwaysUsageDescription</key>
    <string>Need Location permission</string>
    <key>NSLocationWhenInUseUsageDescription</key>
    <string>Need Location permission</string>
</dict>

这些权限将允许你的应用使用蓝牙功能,并获取设备的位置信息。



在使用flutter_blue进行蓝牙操作之前,首先需要获取FlutterBlue的实例。你可以通过以下方式获取:

FlutterBlue flutterBlue = FlutterBlue.instance;

这行代码将创建一个FlutterBlue的实例,你可以使用这个实例来进行后续的蓝牙操作。


使用flutter_blue进行设备扫描非常简单,你可以使用startScan方法开始扫描,使用stopScan方法停止扫描。以下是一个简单的示例:

// 开始扫描
flutterBlue.startScan(timeout: Duration(seconds: 4));

// 监听扫描结果
var subscription = flutterBlue.scanResults.listen((results) {
    // 处理扫描结果
    for (ScanResult r in results) {
        print('${r.device.name} found! rssi: ${r.rssi}');
    }
});

// 停止扫描
flutterBlue.stopScan();

使用flutter_blue连接到设备也非常简单,你可以使用device.connect方法连接到设备,使用device.disconnect方法断开连接。以下是一个简单的示例:

// 连接到设备
await device.connect();

// 断开设备连接
device.disconnect();

使用flutter_blue发现设备的服务,你可以使用device.discoverServices方法。以下是一个简单的示例:

List<BluetoothService> services = await device.discoverServices();
services.forEach((service) {
    // 处理服务
});

使用flutter_blue读写设备的特性,你可以使用characteristic.read方法读取特性,使用characteristic.write方法写入特性。以下是一个简单的示例:

// 读取所有特性
var characteristics = service.characteristics;
for(BluetoothCharacteristic c in characteristics) {
    List<int> value = await c.read();
    print(value);
}

// 写入特性
await c.write([0x12, 0x34])

使用flutter_blue读写设备的描述符,你可以使用descriptor.read方法读取描述符,使用descriptor.write方法写入描述符。以下是一个简单的示例:

// 读取所有描述符
var descriptors = characteristic.descriptors;
for(BluetoothDescriptor d in descriptors) {
    List<int> value = await d.read();
    print(value);
}

// 写入描述符
await d.write([0x12, 0x34])

在使用FlutterBlue进行蓝牙操作时,你可能需要监听特性值的变化。例如,当设备的某个特性值发生变化时,你可能需要更新你的应用的UI或执行其他操作。FlutterBlue提供了一种简单的方式来设置通知和监听特性值的变化。

以下是如何使用FlutterBlue设置通知和监听特性值的变化的示例:

// 设置通知
await characteristic.setNotifyValue(true);

// 监听特性值的变化
characteristic.value.listen((value) {
    // 当特性值发生变化时,这个回调会被调用
    // 你可以在这里更新你的UI或执行其他操作
    print('New value: $value');
});

在上面的代码中,我们首先使用setNotifyValue(true)方法开启了特性值的通知。这意味着当特性值发生变化时,我们会收到通知。

然后,我们使用characteristic.value.listen方法监听特性值的变化。当特性值发生变化时,我们的监听器会被调用,我们可以在监听器中执行我们需要的操作。

需要注意的是,不是所有的特性都支持通知。在开启通知之前,你应该检查特性是否支持通知。你可以通过检查characteristic.properties.notify属性来判断特性是否支持通知。


MTU,全称为Maximum Transmission Unit,是指数据传输的最大单位。在蓝牙通信中,MTU大小决定了一次可以发送的最大数据量。

在使用FlutterBlue进行蓝牙通信时,你可能需要读取或请求设备的MTU大小。FlutterBlue提供了简单的方法来完成这些操作。

以下是如何使用FlutterBlue读取和请求设备的MTU大小的示例:

// 读取MTU大小
final mtu = await device.mtu.first;
print('MTU size: $mtu');

// 请求更大的MTU大小
await device.requestMtu(512);

在上面的代码中,我们首先使用device.mtu.first来读取设备的MTU大小。然后,我们使用device.requestMtu(512)来请求更大的MTU大小。

需要注意的是,不是所有的设备都支持更改MTU大小。在请求更大的MTU大小之前,你应该检查设备是否支持更改MTU大小。你可以通过检查设备的文档或规格来判断设备是否支持更改MTU大小。

另外,iOS设备不支持请求MTU大小,它会自动尝试协商最大可能的MTU大小(iOS支持的最大MTU大小为185)。



FlutterBlue是flutter_blue库的主要类,它提供了许多用于操作蓝牙的方法。

方法 描述
instance 这是一个静态方法,用于获取FlutterBlue的单例实例。你可以通过FlutterBlue.instance来获取实例。
startScan 这个方法用于开始扫描附近的蓝牙设备。你可以通过startScan方法来启动扫描,扫描结果会通过scanResults流返回。你可以设置timeout参数来指定扫描的超时时间。
stopScan 这个方法用于停止扫描蓝牙设备。当你不再需要扫描设备时,你应该调用stopScan方法来停止扫描,以节省设备的电量。

以下是如何使用FlutterBlue的示例:

// 获取FlutterBlue的实例
FlutterBlue flutterBlue = FlutterBlue.instance;

// 开始扫描蓝牙设备
flutterBlue.startScan(timeout: Duration(seconds: 4));

// 监听扫描结果
var subscription = flutterBlue.scanResults.listen((results) {
    // 处理扫描结果
    for (ScanResult r in results) {
        print('${r.device.name} found! rssi: ${r.rssi}');
    }
});

// 停止扫描蓝牙设备
flutterBlue.stopScan();

在上面的代码中,我们首先获取了FlutterBlue的实例,然后开始扫描蓝牙设备,并监听扫描结果。最后,我们停止了扫描。


BluetoothCharacteristic类代表一个蓝牙特性。以下是BluetoothDevice的主要方法:

方法 描述
read 读取特性的值
write 写入特性的值
setNotifyValue 设置特性的通知值
value 获取特性的值

其中:

  • connect:此方法用于连接到蓝牙设备。它没有参数,返回一个Future,表示连接操作是否成功。
Future<void> connect({
    Duration? timeout,
    bool autoConnect = true,
})
  • disconnect:此方法用于断开与蓝牙设备的连接。它没有参数,返回一个Future,表示断开连接操作是否成功。
Future disconnect()
  • discoverServices:此方法用于发现蓝牙设备提供的服务。它没有参数,返回一个Future<List>,表示发现的服务列表。
Future<List<BluetoothService>> discoverServices()
  • services:此属性用于获取蓝牙设备的服务列表。它是一个Stream<List>,可以监听服务列表的变化。
Stream<List<BluetoothService>> get services
  • state:此属性用于获取蓝牙设备的连接状态。它是一个Stream,可以监听设备状态的变化。
Stream<BluetoothDeviceState> get state
  • mtu:此属性用于获取蓝牙设备的MTU大小。它是一个Stream,可以监听MTU大小的变化。
Stream<int> get mtu
  • requestMtu:此方法用于请求更改蓝牙设备的MTU大小。它接受一个整数参数,表示请求的MTU大小,返回一个Future,表示请求操作是否成功。
Future<void> requestMtu(int desiredMtu)

BluetoothCharacteristic类代表一个蓝牙特性。特性是蓝牙设备提供的一种数据接口,可以用于读取设备的状态,控制设备的操作,或者监听设备的变化。

以下是BluetoothCharacteristic的主要方法:

  • read:这个方法用于读取特性的值。返回的是一个Future,它会在读取完成后返回特性的值。特性的值是一个字节列表。
List<int> value = await characteristic.read();
  • write:这个方法用于写入特性的值。你需要传入一个字节列表作为参数。这个方法也返回一个Future,它会在写入完成后完成。
await characteristic.write([0x12, 0x34]);
  • setNotifyValue:这个方法用于设置特性的通知值。如果你设置了特性的通知值,那么当特性的值发生变化时,你会收到通知。这个方法需要一个布尔值作为参数,true表示开启通知,false表示关闭通知。
await characteristic.setNotifyValue(true);
  • value:这个属性用于获取特性的值。它返回一个Stream,你可以监听这个Stream来获取特性值的更新。
characteristic.value.listen((value) {
    print('New value: $value');
});

BluetoothDescriptor类代表一个蓝牙描述符。描述符提供了关于特性(Characteristic)的额外信息和功能。

方法 描述
read 读取描述符的值
write 写入描述符的值

read 方法

read方法用于读取描述符的值。这是一个异步方法,返回一个Future,当操作完成时,Future的结果是一个包含描述符值的字节列表。

write方法

write方法用于写入描述符的值。这是一个异步方法,接受一个字节列表作为参数,表示要写入的值。返回一个Future,当操作完成时,Future的结果是null。

Future<Null> write(List<int> value)

示例

以下是如何使用read和write方法的示例:

// 获取一个BluetoothDescriptor实例
BluetoothDescriptor descriptor = ...;

// 读取描述符的值
List<int> value = await descriptor.read();
print('Descriptor value: $value');

// 写入描述符的值
await descriptor.write([0x01, 0x02, 0x03]);

在上面的代码中,我们首先获取了一个BluetoothDescriptor实例。然后,我们使用read方法读取了描述符的值,并打印出来。最后,我们使用write方法写入了一个新的值。

【版权声明】本文为华为云社区用户原创内容,未经允许不得转载,如需转载请自行联系原作者进行授权。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。