Flutter低功耗蓝牙通信插件bluetooth_low_energy的使用
Flutter低功耗蓝牙通信插件bluetooth_low_energy的使用
简介
bluetooth_low_energy
是一个Flutter插件,用于控制低功耗蓝牙(BLE),支持中央设备(Central)和外围设备(Peripheral)角色。以下是该插件的主要功能和使用方法。
CentralManager API 支持情况
API | Android | iOS | macOS | Windows | Linux |
---|---|---|---|---|---|
logLevel | ✅ | ✅ | ✅ | ✅ | ✅ |
state | ✅ | ✅ | ✅ | ✅ | ✅ |
stateChanged | ✅ | ✅ | ✅ | ✅ | ✅ |
authorize | ✅ | ❌ | ❌ | ❌ | ❌ |
showAppSettings | ✅ | ✅ | ❌ | ❌ | ❌ |
discovered | ✅ | ✅ | ✅ | ✅ | ✅ |
connectionStateChanged | ✅ | ✅ | ✅ | ✅ | ✅ |
mtuChanged | ✅ | ❌ | ❌ | ✅ | ❌ |
characteristicNotified | ✅ | ✅ | ✅ | ✅ | ✅ |
startDiscovery | ✅ | ✅ | ✅ | ✅ | ✅ |
stopDiscovery | ✅ | ✅ | ✅ | ✅ | ✅ |
retrieveConnectedPeripherals | ✅ | ✅ | ✅ | ❌ | ✅ |
connect | ✅ | ✅ | ✅ | ✅ | ✅ |
disconnect | ✅ | ✅ | ✅ | ✅ | ✅ |
requestMTU | ✅ | ❌ | ❌ | ❌ | ❌ |
getMaximumWriteLength | ✅ | ✅ | ✅ | ✅ | ✅ |
readRSSI | ✅ | ✅ | ✅ | ❌ | ✅ |
readCharacteristic | ✅ | ✅ | ✅ | ✅ | ✅ |
writeCharacteristic | ✅ | ✅ | ✅ | ✅ | ✅ |
setCharacteristicNotifyState | ✅ | ✅ | ✅ | ✅ | ✅ |
readDescriptor | ✅ | ✅ | ✅ | ✅ | ✅ |
writeDescriptor | ✅ | ✅ | ✅ | ✅ | ✅ |
PeripheralManager API 支持情况
API | Android | iOS | macOS | Windows | Linux |
---|---|---|---|---|---|
logLevel | ✅ | ✅ | ✅ | ✅ | ❌ |
state | ✅ | ✅ | ✅ | ✅ | ❌ |
stateChanged | ✅ | ✅ | ✅ | ✅ | ❌ |
authorize | ✅ | ❌ | ❌ | ❌ | ❌ |
showAppSettings | ✅ | ✅ | ❌ | ❌ | ❌ |
connectionStateChanged | ✅ | ❌ | ❌ | ❌ | ❌ |
mtuChanged | ✅ | ❌ | ❌ | ✅ | ❌ |
characteristicReadRequested | ✅ | ✅ | ✅ | ✅ | ❌ |
characteristicWriteRequested | ✅ | ✅ | ✅ | ✅ | ❌ |
characteristicNotifyStateChanged | ✅ | ✅ | ✅ | ✅ | ❌ |
descriptorReadRequested | ✅ | ❌ | ❌ | ✅ | ❌ |
descriptorWriteRequested | ✅ | ❌ | ❌ | ✅ | ❌ |
addService | ✅ | ✅ | ✅ | ✅ | ❌ |
removeService | ✅ | ✅ | ✅ | ✅ | ❌ |
removeAllServices | ✅ | ✅ | ✅ | ✅ | ❌ |
startAdvertising | ✅ | ✅ | ✅ | ✅ | ❌ |
stopAdvertising | ✅ | ✅ | ✅ | ✅ | ❌ |
getMaximumNotifyLength | ✅ | ✅ | ✅ | ✅ | ❌ |
respondReadRequestWithValue | ✅ | ✅ | ✅ | ✅ | ❌ |
respondReadRequestWithError | ✅ | ✅ | ✅ | ✅ | ❌ |
respondWriteRequest | ✅ | ✅ | ✅ | ✅ | ❌ |
respondWriteRequestWithError | ✅ | ✅ | ✅ | ✅ | ❌ |
notifyCharacteristic | ✅ | ✅ | ✅ | ✅ | ❌ |
开始使用
添加依赖
在 pubspec.yaml
文件中添加 bluetooth_low_energy
依赖:
dependencies:
bluetooth_low_energy: ^<latest-version>
注意: 低功耗蓝牙不适用于模拟器,请使用具有蓝牙功能的物理设备进行开发。
平台特定配置
Android
确保你的 android/app/build.gradle
文件中的 minSdk
设置为21或更高。
iOS 和 macOS
根据苹果文档,你必须在iOS 13及以上版本包含 NSBluetoothAlwaysUsageDescription
,在iOS 13之前包含 NSBluetoothPeripheralUsageDescription
。
对于macOS,开发者需要配置应用沙盒以访问受限资源。
Windows
PeripheralManager#startAdvertising
不支持 name
参数。
Linux
PeripheralManager
API 尚未实现,因为 bluez
不支持此功能。
示例代码
以下是一个完整的示例应用程序,展示了如何使用 bluetooth_low_energy
插件:
import 'dart:async';
import 'dart:developer';
import 'package:flutter/material.dart';
import 'package:logging/logging.dart';
import 'package:bluetooth_low_energy/bluetooth_low_energy.dart';
void main() {
runZonedGuarded(onStartUp, onCrashed);
}
void onStartUp() async {
Logger.root.onRecord.listen(onLogRecord);
hierarchicalLoggingEnabled = true;
// 初始化蓝牙管理器
final centralManager = CentralManager();
await centralManager.startDiscovery();
runApp(const MyApp());
}
void onCrashed(Object error, StackTrace stackTrace) {
Logger.root.shout('App crashed.', error, stackTrace);
}
void onLogRecord(LogRecord record) {
log(
record.message,
time: record.time,
sequenceNumber: record.sequenceNumber,
level: record.level.value,
name: record.loggerName,
zone: record.zone,
error: record.error,
stackTrace: record.stackTrace,
);
}
class MyApp extends StatelessWidget {
const MyApp({super.key});
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'BLE Example',
theme: ThemeData.light().copyWith(
materialTapTargetSize: MaterialTapTargetSize.padded,
),
darkTheme: ThemeData.dark().copyWith(
materialTapTargetSize: MaterialTapTargetSize.padded,
),
home: const BLEHomePage(),
);
}
}
class BLEHomePage extends StatefulWidget {
const BLEHomePage({super.key});
@override
State<BLEHomePage> createState() => _BLEHomePageState();
}
class _BLEHomePageState extends State<BLEHomePage> {
final CentralManager _centralManager = CentralManager();
List<DiscoveredPeripheral> _peripherals = [];
@override
void initState() {
super.initState();
_centralManager.discovered.listen((event) {
setState(() {
_peripherals.add(event);
});
});
_centralManager.startDiscovery();
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text('BLE Devices'),
),
body: ListView.builder(
itemCount: _peripherals.length,
itemBuilder: (context, index) {
final peripheral = _peripherals[index];
return ListTile(
title: Text(peripheral.name ?? 'Unknown Device'),
subtitle: Text(peripheral.identifier),
onTap: () {
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => DeviceDetailPage(peripheral: peripheral),
),
);
},
);
},
),
);
}
}
class DeviceDetailPage extends StatefulWidget {
final DiscoveredPeripheral peripheral;
const DeviceDetailPage({super.key, required this.peripheral});
@override
State<DeviceDetailPage> createState() => _DeviceDetailPageState();
}
class _DeviceDetailPageState extends State<DeviceDetailPage> {
late StreamSubscription<ConnectionState> _connectionStateSubscription;
bool _isConnected = false;
@override
void initState() {
super.initState();
_connectToDevice();
}
Future<void> _connectToDevice() async {
try {
await widget.peripheral.connect();
_connectionStateSubscription = widget.peripheral.connectionStateChanged.listen((state) {
if (mounted) {
setState(() {
_isConnected = state == ConnectionState.connected;
});
}
});
} catch (e) {
log('Failed to connect: $e');
}
}
@override
void dispose() {
_connectionStateSubscription.cancel();
widget.peripheral.disconnect();
super.dispose();
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text(widget.peripheral.name ?? 'Unknown Device'),
),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Text(_isConnected ? 'Connected' : 'Disconnected'),
ElevatedButton(
onPressed: _isConnected ? null : () async {
await widget.peripheral.connect();
setState(() {
_isConnected = true;
});
},
child: const Text('Connect'),
),
ElevatedButton(
onPressed: _isConnected ? () async {
await widget.peripheral.disconnect();
setState(() {
_isConnected = false;
});
} : null,
child: const Text('Disconnect'),
),
],
),
),
);
}
}
这个示例展示了如何初始化蓝牙管理器、发现设备并连接到设备。你可以根据需要扩展此代码以实现更多功能,如读取和写入特征值等。
更多关于Flutter低功耗蓝牙通信插件bluetooth_low_energy的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html
更多关于Flutter低功耗蓝牙通信插件bluetooth_low_energy的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html
当然,下面是一个关于如何在Flutter应用中使用bluetooth_low_energy
插件进行低功耗蓝牙通信的示例代码。这个示例包括扫描设备、连接到设备、读取和写入特征值的基本操作。
首先,确保你的Flutter项目中已经添加了bluetooth_low_energy
插件。你可以在你的pubspec.yaml
文件中添加以下依赖:
dependencies:
flutter:
sdk: flutter
bluetooth_low_energy: ^0.10.0 # 请确保使用最新版本
然后运行flutter pub get
来安装依赖。
接下来是示例代码:
import 'package:flutter/material.dart';
import 'package:bluetooth_low_energy/bluetooth_low_energy.dart';
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
home: BluetoothScreen(),
);
}
}
class BluetoothScreen extends StatefulWidget {
@override
_BluetoothScreenState createState() => _BluetoothScreenState();
}
class _BluetoothScreenState extends State<BluetoothScreen> {
final BleManager bleManager = BleManager();
List<DiscoveredDevice> devices = [];
ConnectedDevice? connectedDevice;
@override
void initState() {
super.initState();
initBluetooth();
}
Future<void> initBluetooth() async {
await bleManager.initialize();
startScanning();
}
Future<void> startScanning() async {
bleManager.startScanning().listen((scanResult) {
setState(() {
devices = devices.filter((device) => device.id != scanResult.device.id).toList();
devices.add(scanResult.device);
});
}).onDone(() {
print("Scanning stopped.");
});
}
Future<void> connectToDevice(DiscoveredDevice device) async {
connectedDevice = await device.connect();
print("Connected to ${connectedDevice!.id}");
await readCharacteristic(connectedDevice!);
}
Future<void> readCharacteristic(ConnectedDevice device) async {
final service = await device.discoverServices();
final characteristic = service.characteristics.firstOrNull;
if (characteristic != null) {
final value = await characteristic.read();
print("Characteristic value: ${value.toHex()}");
}
}
Future<void> writeCharacteristic(ConnectedDevice device, Uint8List data) async {
final service = await device.discoverServices();
final characteristic = service.characteristics.firstOrNull;
if (characteristic != null) {
await characteristic.write(data);
print("Characteristic written: ${data.toHex()}");
}
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('Bluetooth Low Energy Example'),
),
body: Padding(
padding: const EdgeInsets.all(16.0),
child: Column(
children: [
Text('Discovered Devices:'),
Expanded(
child: ListView.builder(
itemCount: devices.length,
itemBuilder: (context, index) {
final device = devices[index];
return ListTile(
title: Text(device.name ?? 'Unknown'),
subtitle: Text(device.id),
onTap: () => connectToDevice(device),
);
},
),
),
if (connectedDevice != null) {
Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text('Connected Device:'),
Text(connectedDevice!.id),
ElevatedButton(
onPressed: () async {
final data = Uint8List.fromList([0x01, 0x02, 0x03]);
await writeCharacteristic(connectedDevice!, data);
},
child: Text('Write Characteristic'),
),
],
)
}
],
),
),
);
}
}
说明
- 初始化蓝牙:在
initState
方法中调用bleManager.initialize()
来初始化蓝牙。 - 扫描设备:调用
bleManager.startScanning()
开始扫描附近的蓝牙设备,并将扫描到的设备添加到devices
列表中。 - 连接设备:点击列表中的设备项时,调用
connectToDevice
方法连接到该设备。 - 读取特征值:连接成功后,调用
readCharacteristic
方法读取第一个特征值(示例中假设只有一个特征值)。 - 写入特征值:提供一个按钮,点击后调用
writeCharacteristic
方法向特征值写入数据。
注意事项
- 确保在
AndroidManifest.xml
和Info.plist
中添加了必要的蓝牙权限。 - 在实际使用中,可能需要处理更多的错误情况和边缘情况,例如设备连接失败、特征值读取/写入失败等。
bluetooth_low_energy
插件的API可能会随着版本更新而变化,请参考最新的官方文档。
希望这个示例代码能帮助你理解如何在Flutter中使用bluetooth_low_energy
插件进行低功耗蓝牙通信。