Flutter蓝牙通信插件ble_ex的使用

Flutter蓝牙通信插件ble_ex的使用

简介

ble_ex 是一个基于 flutter_reactive_ble 实现的 BLE 中心设备的 Flutter 库,增加了更多中心设备与从设备的通信方式支持。

  • Android 版本的实现:可以通过配合 Flutter 版本的 ble_ex 轻松实现 BLE 外围设备相关功能。
  • iOS 版本的实现:尚未开始开发。

安装

插件的安装
pub.dev 安装
dependencies:
  ble_ex: ^1.0.1

执行以下命令:

flutter pub add ble_ex
从 GitHub 安装

pubspec.yaml 文件的 dependencies 字段中增加如下依赖:

dependencies:
  ble_ex:
    git:
      url: https://github.com/featherJ/ble_ex.git
      ref: ^1.0.1

然后执行命令:

flutter pub get
项目的配置

由于该插件的实现依赖于 flutter_reactive_ble,所以关于 Android 和 iOS 项目的配置需要参考 flutter_reactive_ble 的文档进行。

功能简介

ble_ex 库提供了以下功能:

  • 连接时的重试功能,自动重试3次以增大连接成功的概率。
  • 主设备可以通过一个方法直接申请最大的 mtu 值。
  • 实现了带有数据请求方法,中心设备可以像外围设备的指定特征提交一段数据并请求一段数据。
  • 实现了从中心设备到外围设备指定特征的长数据的发送,可以忽视 mtu 的限制。
  • 实现了中心设备读取外围设备指定特征的长数据,同上可以忽视 mtu 的限制。
  • 实现了监听并接收外围设备的指定特征的长数据的方法,同上可以忽视 mtu 的限制。
  • 实现了带有长数据请求方法,类似于 HTTP 中的 POST 方法,同上可以忽视 mtu 的限制。
  • 可以先对设备指定特征进行监听,再请求连接。
  • 搜索外围设备广播过程中,可以根据 manufacturer 值进行设备的过滤。

使用

初始化
WidgetsFlutterBinding.ensureInitialized();

BleEx.logLevel = BleLogLevel.lib;
var bleex = BleEx();
扫描外围设备

搜索设备提供了两种方式:

监听周围所有设备的变化
var task = bleex.createScanningTask();
task.addDeviceUpdateListener(deviceUpdateHandler);
task.scanDevices({List<DevicesFilter>? filters});

void deviceUpdateHandler(DiscoveredDevice device) {
  // 设备更新处理
}

// 停止扫描设备
task.stopScan();
// 释放资源
task.dispose();
直接搜索并获取某个指定的设备
var device = await bleex.searchForDevice(List<DevicesFilter> filters);
// device 就是查找到的指定的外围设备
设备的连接与状态
BlePeripheral peripheral = bleex.<T extends BlePeripheral>(DiscoveredDevice device, T instance);
peripheral.addConnectedListener(connectedHandler);
peripheral.addDisconnectedListener(disconnectedHandler);
peripheral.addConnectErrorListener(connectErrorHandler);

// 主动建立连接
peripheral.connect();

// 主动断开连接
// await peripheral.disconnect();

void connectedHandler(BlePeripheral target) {
  // 设备已连接
}

void disconnectedHandler(BlePeripheral target) {
  // 设备断开
}

void connectErrorHandler(BlePeripheral target, Object error) {
  // 设备连接错误
}
特征的读与写
读取特征
try {
    Uint8List response = await peripheral.read(Uuid service, Uuid characteristic);
    // 有应答写完成
} catch (e) {
    // 有应答写错误
}
有应答写入特征
try {
    await peripheral.writeWithResponse(Uuid service, Uuid characteristic, Uint8List data);
    // 有应答写完成
} catch (e) {
    // 有应答写错误
}
无应答写入特征
try {
    await peripheral.writeWithoutResponse(Uuid service, Uuid characteristic, Uint8List data);
    // 无应答写完成
} catch (e) {
    // 无应答写错误
}
监听指定特征的通知
peripheral.addNotifyListener(Uuid characteristic, notifyHandler);
void notifyHandler(BlePeripheral target, Uuid service, Uuid characteristic, Uint8List data) {
    // 接收到了某个特征的通知
}
短数据请求(受到mtu限制)
try {
    var response = await peripheral.request(Uuid service, Uuid characteristic, Uint8List data);
    // response 为接收到的数据
} catch (e) {
    // 请求失败
}
协商请求最大的mtu
int suggestedMtu = await peripheral.requestSuggestedMtu();
请求优先级,仅在android上生效

应在 requestSuggestedMtu 调用结束之后再调用,因为 requestSuggestedMtu 在某些设备上可能会触发断连并自动重连的过程。

await peripheral.requestConnectionPriority(ConnectionPriority priority);
长数据的写(不受mtu限制)
try {
    await peripheral.writeLarge(Uuid service, Uuid characteristic, Uint8List bytes);
    // 长数据写入完成
} catch (e) {
    // 长数据写入错误
}
监听/移除监听指定特征的长数据(不受mtu限制)
peripheral.addLargeIndicateListener(Uuid service, Uuid characteristic, NotifyListener listener);
peripheral.removeLargeIndicateListener(Uuid service, Uuid characteristic, NotifyListener listener);

void largeIndicateHandler(BlePeripheral target, Uuid service, Uuid characteristic, Uint8List data) {
    // 接收到了某个特征的长数据
}
长数据请求(不受mtu限制)
try {
    var response = await peripheral.requestLarge(Uuid service, Uuid characteristic, Uint8List data);
    // response 为接收到的数据
} catch (e) {
    // 请求失败
}

示例代码

import 'package:ble_ex/ble_ex.dart';
import 'package:ble_ex_example/samples/cases/base_case.dart';
import 'package:ble_ex_example/samples/cases/ble_communication_case.dart';
import 'package:ble_ex_example/samples/cases/ble_mulit_write_case.dart';
import 'package:ble_ex_example/samples/cases/bleex_communication_case.dart';
import 'package:ble_ex_example/samples/cases/bleex_reqeust_case.dart';
import 'package:ble_ex_example/samples/cases/bleex_reqeust_high_frequency_case.dart';
import 'package:ble_ex_example/samples/cases/connect_by_dist_case.dart';
import 'package:ble_ex_example/samples/cases/reconnect_case.dart';
import 'package:ble_ex_example/samples/cases/scan_case.dart';
import 'package:ble_ex_example/samples/cases/verify_central_case.dart';
import 'package:flutter/material.dart';

const String tag = "Main";

void main() async {
  WidgetsFlutterBinding.ensureInitialized();

  BleEx.logLevel = BleLogLevel.lib;
  bleLog(tag, "Running");
  var bleex = BleEx();
  runSampleCase(bleex);
}

void runSampleCase(BleEx bleex) {
  bleLog(tag, "Creating sample case");
  CaseBase sampleCase = CaseBase();

  sampleCase.init(bleex);
  bleLog(tag, "Sample case created");
  sampleCase.start();
}

更多关于Flutter蓝牙通信插件ble_ex的使用的实战教程也可以访问 https://www.itying.com/category-92-b0.html

1 回复

更多关于Flutter蓝牙通信插件ble_ex的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html


ble_ex 是一个用于 Flutter 的蓝牙低功耗 (BLE) 插件,允许开发者轻松地实现与 BLE 设备的通信。它提供了扫描设备、连接、发现服务、读写特征值等功能。以下是使用 ble_ex 插件进行蓝牙通信的基本步骤。

1. 添加依赖

首先,在 pubspec.yaml 文件中添加 ble_ex 插件的依赖:

dependencies:
  flutter:
    sdk: flutter
  ble_ex: ^0.0.1  # 请使用最新版本

然后运行 flutter pub get 来安装依赖。

2. 初始化插件

在你的 Dart 文件中,导入 ble_ex 插件并初始化它:

import 'package:ble_ex/ble_ex.dart';

final bleEx = BleEx();

3. 检查蓝牙状态

在开始扫描设备之前,建议先检查设备的蓝牙状态:

Future<void> checkBluetoothStatus() async {
  final status = await bleEx.bluetoothState;
  if (status == BleState.on) {
    print("Bluetooth is on");
  } else {
    print("Bluetooth is off");
  }
}

4. 扫描设备

使用 startScan 方法开始扫描附近的 BLE 设备:

void startScanning() {
  bleEx.startScan(
    withServices: [], // 可以指定要扫描的服务UUID
    scanMode: ScanMode.lowLatency,
    callback: (scanResult) {
      print('Found device: ${scanResult.device.name}');
      print('Device ID: ${scanResult.device.id}');
    },
  );
}

停止扫描:

void stopScanning() {
  bleEx.stopScan();
}

5. 连接设备

扫描到设备后,可以使用设备的 id 进行连接:

void connectToDevice(String deviceId) async {
  try {
    await bleEx.connectToDevice(deviceId);
    print('Connected to device');
  } catch (e) {
    print('Failed to connect: $e');
  }
}

6. 发现服务

连接成功后,可以发现设备的服务:

void discoverServices(String deviceId) async {
  final services = await bleEx.discoverServices(deviceId);
  for (var service in services) {
    print('Service UUID: ${service.uuid}');
    for (var characteristic in service.characteristics) {
      print('Characteristic UUID: ${characteristic.uuid}');
    }
  }
}

7. 读写特征值

你可以读取或写入特征值:

void readCharacteristic(String deviceId, String characteristicId) async {
  final value = await bleEx.readCharacteristic(deviceId, characteristicId);
  print('Characteristic value: $value');
}

void writeCharacteristic(String deviceId, String characteristicId, List<int> value) async {
  await bleEx.writeCharacteristic(deviceId, characteristicId, value);
  print('Characteristic value written');
}

8. 断开连接

操作完成后,断开与设备的连接:

void disconnectDevice(String deviceId) async {
  await bleEx.disconnectFromDevice(deviceId);
  print('Disconnected from device');
}

9. 处理权限

在 Android 上,使用 BLE 需要一些权限。确保在 AndroidManifest.xml 中添加以下权限:

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

在 iOS 上,需要在 Info.plist 中添加以下键值对:

<key>NSBluetoothAlwaysUsageDescription</key>
<string>We need access to Bluetooth to connect to your device.</string>
<key>NSBluetoothPeripheralUsageDescription</key>
<string>We need access to Bluetooth to connect to your device.</string>
回到顶部