插件介绍
fluttertpc_flutter_blue_plus 是一个功能强大的蓝牙低功耗(BLE)插件,专为 Flutter 应用设计,支持在鸿蒙(HarmonyOS)平台上进行 BLE 设备的扫描、连接和通信。该插件基于 flutter_blue_plus 进行了鸿蒙平台的适配,提供了完整的 BLE 中央角色功能支持。
主要功能特性
- ✅ 支持检查设备是否支持蓝牙
- ✅ 支持启用蓝牙适配器
- ✅ 支持扫描 BLE 设备
- ✅ 支持与 BLE 设备建立连接
- ✅ 支持发现设备的服务和特征
- ✅ 支持读写特征值
- ✅ 支持设置特征通知
- ✅ 支持读取设备 RSSI 值
- ✅ 支持设置 MTU 值
- ✅ 支持蓝牙适配器状态监听
- ✅ 支持连接状态变化监听
如何使用插件
1. 包的引入
由于这是一个自定义修改版本的插件,需要通过 Git 形式引入依赖。在项目的 pubspec.yaml 文件中添加以下配置:
dependencies:
flutter:
sdk: flutter
flutter_blue_plus:
git:
url: "https://gitcode.com/openharmony-sig/fluttertpc_flutter_blue_plus.git"
path: "."
flutter_blue_plus_ohos:
git:
url: "https://gitcode.com/openharmony-sig/fluttertpc_flutter_blue_plus.git"
path: "ohos"
添加依赖后,执行以下命令获取包:
flutter pub get
2. 权限配置
在鸿蒙平台上使用蓝牙功能需要配置相应的权限。打开 entry/src/main/module.json5 文件,添加以下权限配置:
{
"module": {
"requestPermissions": [
{
"name": "ohos.permission.ACCESS_BLUETOOTH",
"reason": "需要蓝牙权限来扫描和连接BLE设备",
"usedScene": {
"abilities": ["EntryAbility"],
"when": "inuse"
}
},
{
"name": "ohos.permission.PERSISTENT_BLUETOOTH_PEERS_MAC"
}
]
}
}
同时,在 entry/src/main/resources/base/element/string.json 文件中添加权限说明:
{
"string": [
{
"name": "bluetooth_reason",
"value": "需要蓝牙权限来扫描和连接BLE设备"
}
]
}
3. API 的调用
3.1 初始化与蓝牙状态检查
import 'package:flutter_blue_plus/flutter_blue_plus.dart';
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
// 检查设备是否支持蓝牙
bool isSupported = await FlutterBluePlus.isSupported;
if (!isSupported) {
print("此设备不支持蓝牙");
return;
}
// 设置日志级别
FlutterBluePlus.setLogLevel(LogLevel.verbose, color: false);
// 监听蓝牙适配器状态变化
StreamSubscription<BluetoothAdapterState> adapterStateSubscription =
FlutterBluePlus.adapterState.listen((state) {
print("蓝牙状态: $state");
if (state == BluetoothAdapterState.on) {
// 蓝牙已开启,可以开始扫描设备
} else {
// 蓝牙未开启,需要提示用户
}
});
// 开启蓝牙(仅Android和HarmonyOS平台支持)
if (defaultTargetPlatform == TargetPlatform.android ||
defaultTargetPlatform == TargetPlatform.ohos) {
await FlutterBluePlus.turnOn(timeout: 60);
}
3.2 扫描 BLE 设备
// 监听扫描结果
StreamSubscription<List<ScanResult>> scanResultsSubscription =
FlutterBluePlus.scanResults.listen((results) {
for (ScanResult result in results) {
print('发现设备: ${result.device.platformName}, RSSI: ${result.rssi}');
print('设备ID: ${result.device.remoteId}');
print('广播名称: ${result.advertisementData.advName}');
print('服务UUID: ${result.advertisementData.serviceUuids}');
}
});
// 开始扫描
await FlutterBluePlus.startScan(
withServices: [], // 可以指定要扫描的服务UUID
withNames: [], // 可以指定要扫描的设备名称
timeout: Duration(seconds: 30), // 扫描超时时间
);
// 等待扫描停止
await FlutterBluePlus.isScanning.where((val) => val == false).first;
// 清理订阅
scanResultsSubscription.cancel();
3.3 连接 BLE 设备
// 获取扫描结果中的设备
ScanResult scanResult = results.first;
BluetoothDevice device = scanResult.device;
// 监听连接状态变化
StreamSubscription<BluetoothConnectionState> connectionStateSubscription =
device.connectionState.listen((state) {
print('连接状态: $state');
if (state == BluetoothConnectionState.connected) {
// 连接成功,可以发现服务
discoverServices(device);
} else if (state == BluetoothConnectionState.disconnected) {
// 连接断开
print('设备已断开连接');
}
});
// 建立连接
await device.connect(
timeout: Duration(seconds: 35),
autoConnect: false,
);
3.4 发现设备服务
Future<void> discoverServices(BluetoothDevice device) async {
// 发现服务
List<BluetoothService> services = await device.discoverServices();
for (BluetoothService service in services) {
print('服务UUID: ${service.uuid}');
// 遍历服务的特征
for (BluetoothCharacteristic characteristic in service.characteristics) {
print(' 特征UUID: ${characteristic.uuid}');
print(' 特征属性: ${characteristic.properties}');
// 读取特征值(如果有读权限)
if (characteristic.properties.read) {
List<int> value = await characteristic.read();
print(' 特征值: $value');
}
// 订阅特征通知(如果有通知权限)
if (characteristic.properties.notify) {
await characteristic.setNotifyValue(true);
characteristic.onValueReceived.listen((value) {
print(' 接收到通知值: $value');
});
}
// 写入特征值(如果有写权限)
if (characteristic.properties.write) {
List<int> valueToWrite = [1, 2, 3, 4, 5];
await characteristic.write(valueToWrite, withoutResponse: false);
}
// 遍历特征的描述符
for (BluetoothDescriptor descriptor in characteristic.descriptors) {
print(' 描述符UUID: ${descriptor.uuid}');
// 读取描述符值
List<int> descriptorValue = await descriptor.read();
print(' 描述符值: $descriptorValue');
}
}
}
}
3.5 读取 RSSI 值
// 读取设备RSSI值
int rssi = await device.readRssi();
print('设备RSSI: $rssi');
3.6 设置 MTU 值
// 请求设置MTU值
int newMtu = await device.requestMtu(desiredMtu: 512);
print('新的MTU值: $newMtu');
// 监听MTU值变化
device.mtu.listen((mtu) {
print('MTU值已更新: $mtu');
});
3.7 断开连接
// 断开连接
await device.disconnect(timeout: 35);
// 清理订阅
connectionStateSubscription.cancel();
adapterStateSubscription.cancel();
代码示例
下面是一个完整的示例,展示了如何在鸿蒙应用中使用 fluttertpc_flutter_blue_plus 插件:
import 'package:flutter/material.dart';
import 'package:flutter_blue_plus/flutter_blue_plus.dart';
import 'dart:typed_data';
void main() {
runApp(const BluetoothApp());
}
class BluetoothApp extends StatelessWidget {
const BluetoothApp({Key? key}) : super(key: key);
Widget build(BuildContext context) {
return MaterialApp(
title: 'BLE 示例应用',
theme: ThemeData(primarySwatch: Colors.blue),
home: const BluetoothHomePage(),
);
}
}
class BluetoothHomePage extends StatefulWidget {
const BluetoothHomePage({Key? key}) : super(key: key);
State<BluetoothHomePage> createState() => _BluetoothHomePageState();
}
class _BluetoothHomePageState extends State<BluetoothHomePage> {
BluetoothAdapterState _adapterState = BluetoothAdapterState.unknown;
List<ScanResult> _scanResults = [];
bool _isScanning = false;
BluetoothDevice? _connectedDevice;
List<BluetoothService> _services = [];
late StreamSubscription<BluetoothAdapterState> _adapterStateSubscription;
late StreamSubscription<List<ScanResult>> _scanResultsSubscription;
StreamSubscription<BluetoothConnectionState>? _connectionStateSubscription;
void initState() {
super.initState();
_initBluetooth();
}
Future<void> _initBluetooth() async {
// 检查设备是否支持蓝牙
bool isSupported = await FlutterBluePlus.isSupported;
if (!isSupported) {
_showAlert('此设备不支持蓝牙');
return;
}
// 设置日志级别
FlutterBluePlus.setLogLevel(LogLevel.verbose, color: false);
// 监听蓝牙适配器状态
_adapterStateSubscription = FlutterBluePlus.adapterState.listen((state) {
setState(() {
_adapterState = state;
});
});
// 开启蓝牙
await FlutterBluePlus.turnOn(timeout: 60);
}
Future<void> _startScan() async {
setState(() {
_scanResults.clear();
_isScanning = true;
});
// 监听扫描结果
_scanResultsSubscription = FlutterBluePlus.scanResults.listen((results) {
setState(() {
_scanResults = results;
});
});
// 开始扫描
await FlutterBluePlus.startScan(timeout: Duration(seconds: 15));
// 等待扫描停止
await FlutterBluePlus.isScanning.where((val) => val == false).first;
setState(() {
_isScanning = false;
});
// 清理订阅
_scanResultsSubscription.cancel();
}
Future<void> _connectToDevice(BluetoothDevice device) async {
try {
setState(() {
_connectedDevice = device;
});
// 监听连接状态
_connectionStateSubscription = device.connectionState.listen((state) {
if (state == BluetoothConnectionState.connected) {
// 连接成功,发现服务
_discoverServices(device);
} else if (state == BluetoothConnectionState.disconnected) {
setState(() {
_connectedDevice = null;
_services.clear();
});
}
});
// 建立连接
await device.connect(timeout: Duration(seconds: 35));
} catch (e) {
_showAlert('连接失败: $e');
setState(() {
_connectedDevice = null;
});
}
}
Future<void> _discoverServices(BluetoothDevice device) async {
List<BluetoothService> services = await device.discoverServices();
setState(() {
_services = services;
});
}
Future<void> _disconnectFromDevice() async {
if (_connectedDevice != null) {
await _connectedDevice!.disconnect();
_connectionStateSubscription?.cancel();
setState(() {
_connectedDevice = null;
_services.clear();
});
}
}
void _showAlert(String message) {
showDialog(
context: context,
builder: (context) => AlertDialog(
title: const Text('提示'),
content: Text(message),
actions: [
TextButton(
onPressed: () => Navigator.pop(context),
child: const Text('确定'),
),
],
),
);
}
void dispose() {
_adapterStateSubscription.cancel();
_connectionStateSubscription?.cancel();
super.dispose();
}
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: const Text('BLE 示例应用')),
body: SingleChildScrollView(
padding: const EdgeInsets.all(16.0),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
// 蓝牙状态
Card(
child: Padding(
padding: const EdgeInsets.all(16.0),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
const Text('蓝牙状态', style: TextStyle(fontSize: 18, fontWeight: FontWeight.bold)),
const SizedBox(height: 8),
Text('当前状态: $_adapterState'),
const SizedBox(height: 16),
ElevatedButton(
onPressed: _adapterState == BluetoothAdapterState.on ? _startScan : null,
child: Text(_isScanning ? '正在扫描...' : '开始扫描'),
),
],
),
),
),
const SizedBox(height: 16),
// 扫描结果
Card(
child: Padding(
padding: const EdgeInsets.all(16.0),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
const Text('扫描结果', style: TextStyle(fontSize: 18, fontWeight: FontWeight.bold)),
const SizedBox(height: 8),
_scanResults.isEmpty
? const Text('暂无设备')
: SizedBox(
height: 200,
child: ListView.builder(
itemCount: _scanResults.length,
itemBuilder: (context, index) {
ScanResult result = _scanResults[index];
return ListTile(
title: Text(result.device.platformName.isNotEmpty
? result.device.platformName
: '未知设备'),
subtitle: Text('RSSI: ${result.rssi} dBm'),
trailing: ElevatedButton(
onPressed: () => _connectToDevice(result.device),
child: const Text('连接'),
),
);
},
),
),
],
),
),
),
const SizedBox(height: 16),
// 连接设备信息
if (_connectedDevice != null)
Card(
child: Padding(
padding: const EdgeInsets.all(16.0),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
const Text('已连接设备', style: TextStyle(fontSize: 18, fontWeight: FontWeight.bold)),
const SizedBox(height: 8),
Text('设备名称: ${_connectedDevice!.platformName}'),
Text('设备ID: ${_connectedDevice!.remoteId}'),
const SizedBox(height: 16),
ElevatedButton(
onPressed: _disconnectFromDevice,
child: const Text('断开连接'),
),
],
),
),
),
const SizedBox(height: 16),
// 服务列表
if (_services.isNotEmpty)
Card(
child: Padding(
padding: const EdgeInsets.all(16.0),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
const Text('服务列表', style: TextStyle(fontSize: 18, fontWeight: FontWeight.bold)),
const SizedBox(height: 8),
for (BluetoothService service in _services)
Padding(
padding: const EdgeInsets.only(bottom: 16.0),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text('服务UUID: ${service.uuid}'),
const SizedBox(height: 8),
for (BluetoothCharacteristic characteristic in service.characteristics)
Padding(
padding: const EdgeInsets.only(left: 16.0, bottom: 8.0),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text('特征UUID: ${characteristic.uuid}'),
Text('属性: ${characteristic.properties}'),
],
),
),
],
),
),
],
),
),
),
],
),
),
);
}
}
注意事项
-
在鸿蒙平台上使用蓝牙功能需要正确配置权限,否则会导致蓝牙功能无法正常工作。
-
蓝牙扫描可能会消耗较多电量,建议在不需要时及时停止扫描。
-
与 BLE 设备的通信应该在连接建立后进行,通信完成后及时断开连接。
-
对于频繁的特征值读写操作,建议使用通知方式获取数据,而不是轮询读取。
-
MTU 值的设置需要考虑设备的支持情况,过大的 MTU 值可能会导致通信不稳定。
总结
fluttertpc_flutter_blue_plus 插件为鸿蒙平台提供了完整的 BLE 中央角色功能支持,包括设备扫描、连接建立、服务发现、特征读写等核心功能。通过简单的 API 调用,开发者可以轻松地在 Flutter 应用中集成 BLE 通信功能,实现与各种 BLE 设备的交互。
该插件的主要优势在于:
-
跨平台兼容性:除了鸿蒙平台外,还支持 Android、iOS、macOS 等多种平台,便于开发者编写跨平台应用。
-
完整的功能支持:覆盖了 BLE 中央角色的大多数常见功能需求,满足各种应用场景。
-
简单易用的 API:提供了简洁明了的 API 接口,减少了开发者的学习成本。
-
稳定的性能:基于成熟的 flutter_blue_plus 进行开发,具有稳定的性能和良好的兼容性。
通过本指南,开发者可以快速上手并在鸿蒙应用中使用 fluttertpc_flutter_blue_plus 插件,实现高效的 BLE 通信功能。
891

被折叠的 条评论
为什么被折叠?



