Flutter蓝牙通信插件flutter_ble_central的使用
Flutter蓝牙通信插件flutter_ble_central的使用
flutter_ble_central
一个用于在中心模式下扫描蓝牙低功耗(BLE)数据的Flutter插件。
开始使用
这个项目是一个Flutter插件包的起点,它包含针对Android和/或iOS平台的特定平台实现代码。
要开始使用Flutter,请查看我们的在线文档,其中包含教程、示例、移动开发指南以及完整的API引用。
示例代码
以下是使用flutter_ble_central
插件的基本示例:
import 'dart:async';
import 'package:flutter/material.dart';
import 'package:flutter_ble_central/flutter_ble_central.dart';
void main() {
runApp(const MyApp());
}
class MyApp extends StatefulWidget {
const MyApp({Key? key}) : super(key: key);
[@override](/user/override)
State<MyApp> createState() => _MyAppState();
}
class _MyAppState extends State<MyApp> {
Map<String, ScanResult> devices = {};
bool isScanning = false;
int packetsFound = 0;
int? queue = 0;
[@override](/user/override)
void initState() {
super.initState();
Timer.periodic(const Duration(seconds: 1), (timer) {
setState(() {
debugPrint('Packets found: $packetsFound, in queue $queue');
});
});
FlutterBleCentral().onScanError?.listen((event) {
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(
content: Text(
'错误: ${AndroidError.values[event]}, code: $event',
),
),
);
debugPrint('Error: ${AndroidError.values[event]}, code: $event');
});
FlutterBleCentral().onScanResult.listen((event) {
packetsFound++;
});
}
Future<void> _requestPermissions() async {
final hasPermission = await FlutterBleCentral().hasPermission();
switch (hasPermission) {
case BluetoothCentralState.denied:
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(
backgroundColor: Colors.red,
content: Text(
"我们没有权限,现在请求!",
),
),
);
await _requestPermissions();
break;
default:
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(
backgroundColor: Colors.green,
content: Text(
'状态: $hasPermission!',
),
),
);
break;
}
}
final _messangerKey = GlobalKey<ScaffoldMessengerState>();
[@override](/user/override)
Widget build(BuildContext context) {
return MaterialApp(
scaffoldMessengerKey: _messangerKey,
home: Scaffold(
appBar: AppBar(
title: const Text('Flutter BLE Central 示例'),
actions: <Widget>[
IconButton(
onPressed: () => setState(() {
FlutterBleCentral().stop();
}),
icon: const Icon(Icons.lock_reset),
),
IconButton(
onPressed: _requestPermissions,
icon: const Icon(Icons.security),
),
if (isScanning)
IconButton(
icon: const Icon(Icons.pause_circle_filled),
onPressed: () => setState(() {
isScanning = false;
FlutterBleCentral().stop();
}),
)
else
IconButton(
icon: const Icon(Icons.play_arrow),
onPressed: () async {
final messenger = _messangerKey.currentState!;
final state = await FlutterBleCentral().start();
switch (state) {
case BluetoothCentralState.ready:
case BluetoothCentralState.granted:
setState(() {
isScanning = true;
devices.clear();
});
break;
case BluetoothCentralState.denied:
messenger.showSnackBar(
const SnackBar(
content: Text(
'蓝牙被拒绝,我们可以再次请求!',
),
),
);
break;
case BluetoothCentralState.permanentlyDenied:
messenger.showSnackBar(
const SnackBar(
content: Text(
'蓝牙被永久拒绝,我们不能再请求!',
),
),
);
break;
case BluetoothCentralState.restricted:
// TODO: 处理这种情况。
break;
case BluetoothCentralState.limited:
// TODO: 处理这种情况。
break;
case BluetoothCentralState.turnedOff:
messenger.showSnackBar(
const SnackBar(
content: Text(
'蓝牙已关闭。',
),
),
);
break;
case BluetoothCentralState.unsupported:
messenger.showSnackBar(
const SnackBar(
content: Text(
'设备不支持蓝牙。',
),
),
);
break;
case BluetoothCentralState.unknown:
messenger.showSnackBar(
const SnackBar(
content: Text(
'未知错误..',
),
),
);
break;
}
},
),
],
),
body: Column(
mainAxisSize: MainAxisSize.min,
children: [
ElevatedButton(
onPressed: () async {
if (isScanning) {
FlutterBleCentral().stop();
isScanning = false;
} else {
isScanning = true;
devices.clear();
FlutterBleCentral().start(
scanSettings: ScanSettings(
scanMode: ScanMode.scanModeLowLatency,
),
);
await Future.delayed(
const Duration(
seconds: 30,
),
);
FlutterBleCentral().stop();
isScanning = false;
}
},
child: const Text('30秒测试'),
),
ElevatedButton(
onPressed: () => FlutterBleCentral().openBluetoothSettings(),
child: const Text('蓝牙设置'),
),
ElevatedButton(
onPressed: () => FlutterBleCentral().openAppSettings(),
child: const Text('应用设置'),
),
Text('找到的数据包: $packetsFound, 队列中: $queue'),
ListView.separated(
shrinkWrap: true,
padding: const EdgeInsets.all(8),
itemBuilder: (BuildContext context, int index) {
final scanResult = devices.values.elementAt(index);
return Card(
child: Padding(
padding: const EdgeInsets.all(8.0),
child: Row(
children: <Widget>[
const Icon(Icons.bluetooth),
Expanded(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
Text('${scanResult.scanRecord?.deviceName}'),
Text('${scanResult.device?.address}'),
Text('RSSI: ${scanResult.rssi}'),
],
),
),
],
),
),
);
},
separatorBuilder: (context, index) => const SizedBox(height: 5),
itemCount: devices.length,
),
],
),
),
);
}
}
代码解释
-
导入必要的库
import 'dart:async'; import 'package:flutter/material.dart'; import 'package:flutter_ble_central/flutter_ble_central.dart';
-
初始化应用
void main() { runApp(const MyApp()); }
-
定义主应用状态
class MyApp extends StatefulWidget { const MyApp({Key? key}) : super(key: key); [@override](/user/override) State<MyApp> createState() => _MyAppState(); }
-
处理蓝牙扫描结果
class _MyAppState extends State<MyApp> { Map<String, ScanResult> devices = {}; bool isScanning = false; int packetsFound = 0; int? queue = 0; [@override](/user/override) void initState() { super.initState(); Timer.periodic(const Duration(seconds: 1), (timer) { setState(() { debugPrint('Packets found: $packetsFound, in queue $queue'); }); }); FlutterBleCentral().onScanError?.listen((event) { ScaffoldMessenger.of(context).showSnackBar( SnackBar( content: Text( '错误: ${AndroidError.values[event]}, code: $event', ), ), ); debugPrint('Error: ${AndroidError.values[event]}, code: $event'); }); FlutterBleCentral().onScanResult.listen((event) { packetsFound++; }); }
-
请求权限
Future<void> _requestPermissions() async { final hasPermission = await FlutterBleCentral().hasPermission(); switch (hasPermission) { case BluetoothCentralState.denied: ScaffoldMessenger.of(context).showSnackBar( SnackBar( backgroundColor: Colors.red, content: Text( "我们没有权限,现在请求!", ), ), ); await _requestPermissions(); break; default: ScaffoldMessenger.of(context).showSnackBar( SnackBar( backgroundColor: Colors.green, content: Text( '状态: $hasPermission!', ), ), ); break; } }
-
构建UI
final _messangerKey = GlobalKey<ScaffoldMessengerState>(); [@override](/user/override) Widget build(BuildContext context) { return MaterialApp( scaffoldMessengerKey: _messangerKey, home: Scaffold( appBar: AppBar( title: const Text('Flutter BLE Central 示例'), actions: <Widget>[ IconButton( onPressed: () => setState(() { FlutterBleCentral().stop(); }), icon: const Icon(Icons.lock_reset), ), IconButton( onPressed: _requestPermissions, icon: const Icon(Icons.security), ), if (isScanning) IconButton( icon: const Icon(Icons.pause_circle_filled), onPressed: () => setState(() { isScanning = false; FlutterBleCentral().stop(); }), ) else IconButton( icon: const Icon(Icons.play_arrow), onPressed: () async { final messenger = _messangerKey.currentState!; final state = await FlutterBleCentral().start(); switch (state) { case BluetoothCentralState.ready: case BluetoothCentralState.granted: setState(() { isScanning = true; devices.clear(); }); break; case BluetoothCentralState.denied: messenger.showSnackBar( const SnackBar( content: Text( '蓝牙被拒绝,我们可以再次请求!', ), ), ); break; case BluetoothCentralState.permanentlyDenied: messenger.showSnackBar( const SnackBar( content: Text( '蓝牙被永久拒绝,我们不能再请求!', ), ), ); break; case BluetoothCentralState.restricted: // TODO: 处理这种情况。 break; case BluetoothCentralState.limited: // TODO: 处理这种情况。 break; case BluetoothCentralState.turnedOff: messenger.showSnackBar( const SnackBar( content: Text( '蓝牙已关闭。', ), ), ); break; case BluetoothCentralState.unsupported: messenger.showSnackBar( const SnackBar( content: Text( '设备不支持蓝牙。', ), ), ); break; case BluetoothCentralState.unknown: messenger.showSnackBar( const SnackBar( content: Text( '未知错误..', ), ), ); break; } }, ), ], ), body: Column( mainAxisSize: MainAxisSize.min, children: [ ElevatedButton( onPressed: () async { if (isScanning) { FlutterBleCentral().stop(); isScanning = false; } else { isScanning = true; devices.clear(); FlutterBleCentral().start( scanSettings: ScanSettings( scanMode: ScanMode.scanModeLowLatency, ), ); await Future.delayed( const Duration( seconds: 30, ), ); FlutterBleCentral().stop(); isScanning = false; } }, child: const Text('30秒测试'), ), ElevatedButton( onPressed: () => FlutterBleCentral().openBluetoothSettings(), child: const Text('蓝牙设置'), ), ElevatedButton( onPressed: () => FlutterBleCentral().openAppSettings(), child: const Text('应用设置'), ), Text('找到的数据包: $packetsFound, 队列中: $queue'), ListView.separated( shrinkWrap: true, padding: const EdgeInsets.all(8), itemBuilder: (BuildContext context, int index) { final scanResult = devices.values.elementAt(index); return Card( child: Padding( padding: const EdgeInsets.all(8.0), child: Row( children: <Widget>[ const Icon(Icons.bluetooth), Expanded( child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: <Widget>[ Text('${scanResult.scanRecord?.deviceName}'), Text('${scanResult.device?.address}'), Text('RSSI: ${scanResult.rssi}'), ], ), ), ], ), ), ); }, separatorBuilder: (context, index) => const SizedBox(height: 5), itemCount: devices.length, ), ], ), ), ); }
更多关于Flutter蓝牙通信插件flutter_ble_central的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html
更多关于Flutter蓝牙通信插件flutter_ble_central的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html
当然,以下是一个关于如何使用 flutter_ble_central
插件进行蓝牙通信的示例代码。这个示例展示了如何扫描设备、连接到设备以及读写蓝牙特征值。
首先,确保你已经在 pubspec.yaml
文件中添加了 flutter_ble_central
依赖:
dependencies:
flutter:
sdk: flutter
flutter_ble_central: ^2.0.0 # 请根据需要检查最新版本
然后,运行 flutter pub get
来获取依赖。
接下来是主要的 Dart 代码示例:
import 'package:flutter/material.dart';
import 'package:flutter_ble_central/flutter_ble_central.dart';
void main() {
runApp(MyApp());
}
class MyApp extends StatefulWidget {
@override
_MyAppState createState() => _MyAppState();
}
class _MyAppState extends State<MyApp> {
FlutterBleCentral _flutterBleCentral = FlutterBleCentral();
List<DiscoveredDevice> _devices = [];
ConnectedDevice? _connectedDevice;
Characteristic? _characteristic;
@override
void initState() {
super.initState();
initBle();
}
Future<void> initBle() async {
// 初始化 Bluetooth 适配器
bool isBluetoothAvailable = await _flutterBleCentral.isBluetoothAvailable();
if (!isBluetoothAvailable) {
// 处理蓝牙不可用的情况
return;
}
bool isBluetoothEnabled = await _flutterBleCentral.isBluetoothEnabled();
if (!isBluetoothEnabled) {
// 请求用户开启蓝牙
bool result = await _flutterBleCentral.requestBluetoothEnable();
if (!result) {
// 用户拒绝开启蓝牙
return;
}
}
// 开始扫描设备
_flutterBleCentral.scanForDevices(timeout: Duration(seconds: 5)).listen(
(List<DiscoveredDevice> result) {
setState(() {
_devices = result;
});
},
onError: (dynamic error) {
print('Scan error: $error');
},
onDone: () {
print('Scan done.');
},
);
}
Future<void> connectToDevice(DiscoveredDevice device) async {
_connectedDevice = await _flutterBleCentral.connectToDevice(device.id);
if (_connectedDevice != null) {
// 获取服务
List<BluetoothService> services = await _connectedDevice!.discoverServices();
services.forEach((service) {
// 获取特征值
service.characteristics.forEach((characteristic) {
setState(() {
_characteristic = characteristic;
});
// 可以在这里根据 UUID 筛选需要的特征值
});
});
}
}
Future<void> readCharacteristic() async {
if (_characteristic != null && _connectedDevice != null) {
List<int> value = await _connectedDevice!.readCharacteristic(_characteristic!.uuid);
print('Characteristic value: ${bytesToHex(value)}');
}
}
Future<void> writeCharacteristic(List<int> value) async {
if (_characteristic != null && _connectedDevice != null) {
await _connectedDevice!.writeCharacteristic(_characteristic!.uuid, value);
print('Characteristic written.');
}
}
String bytesToHex(List<int> bytes) {
return bytes.map((byte) => byte.toRadixString(16).padLeft(2, '0')).join();
}
@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
appBar: AppBar(
title: Text('Flutter BLE Example'),
),
body: Column(
children: [
Expanded(
child: ListView.builder(
itemCount: _devices.length,
itemBuilder: (context, index) {
return ListTile(
title: Text(_devices[index].name ?? 'Unknown Device'),
subtitle: Text(_devices[index].id),
onTap: () {
connectToDevice(_devices[index]);
},
);
},
),
),
ElevatedButton(
onPressed: _connectedDevice != null ? () => readCharacteristic() : null,
child: Text('Read Characteristic'),
),
ElevatedButton(
onPressed: _connectedDevice != null ? () => writeCharacteristic([0x01, 0x02, 0x03]) : null,
child: Text('Write Characteristic'),
),
],
),
),
);
}
}
解释
-
依赖初始化:在
pubspec.yaml
中添加flutter_ble_central
依赖,并运行flutter pub get
。 -
Bluetooth 初始化:在
initBle
方法中检查蓝牙是否可用和已启用,并在必要时请求用户开启蓝牙。 -
扫描设备:使用
_flutterBleCentral.scanForDevices
方法开始扫描设备,并将扫描到的设备存储在_devices
列表中。 -
连接设备:在
connectToDevice
方法中,根据设备 ID 连接到设备,并发现服务及其特征值。 -
读写特征值:在
readCharacteristic
和writeCharacteristic
方法中,分别读取和写入特征值。 -
UI:在
build
方法中构建一个简单的 UI,显示扫描到的设备列表,并提供按钮来读取和写入特征值。
这个示例展示了基本的蓝牙通信流程,你可以根据具体需求进一步扩展和修改代码。