Flutter蓝牙通信插件win_ble的使用
Flutter蓝牙通信插件win_ble的使用
WinBle
使用WinBle插件可以在Flutter Windows项目和纯Dart项目(仅限Windows)中启用蓝牙低功耗(Bluetooth Low Energy)。下面将详细介绍如何使用WinBle进行蓝牙通信。
初始化WinBle
在Flutter Windows项目中初始化WinBle时,需要通过await WinServer.path
获取服务器路径。对于纯Dart项目(仅限Windows),需要下载BleServer.exe文件并放置在同一文件夹中,更多细节请参考example_dart
。
// 在Flutter Windows中初始化
await WinBle.initialize(serverPath: await WinServer.path());
// 在纯Dart项目中初始化
await WinBle.initialize(serverPath: "BLEServer.exe文件路径");
使用完后记得释放资源:
WinBle.dispose();
扫描设备
开始扫描附近的蓝牙设备:
WinBle.startScanning();
StreamSubscription? scanStream = WinBle.scanStream.listen((event) {
// 获取设备信息
});
停止扫描:
WinBle.stopScanning();
scanStream?.cancel();
连接与断开连接
连接到指定地址的设备:
await WinBle.connect(address);
StreamSubscription _connectionStream =
WinBle.connectionStreamOf(device.address).listen((event) {
// event为布尔值,true表示已连接,false表示已断开
});
断开连接:
await WinBle.disconnect(address);
获取最大MTU大小
await WinBle.getMaxMtuSize(address);
处理蓝牙无线电状态
获取蓝牙无线电状态:
WinBle.getBluetoothState();
监听无线电状态变化:
WinBle.bleState.listen((BleState state) {
// 获取BleState (On, Off, Unknown, Disabled, Unsupported)
});
// 打开无线电
WinBle.updateBluetoothState(true);
// 关闭无线电
WinBle.updateBluetoothState(false);
配对选项
配对设备:
await WinBle.pair(address);
// 解除配对
await WinBle.unPair(address);
// 检查设备是否可以配对
bool canPair = await WinBle.canPair(address);
// 检查设备是否已配对
bool isPaired = await WinBle.isPaired(address);
其他方法
获取服务:
var services = await WinBle.discoverServices(address);
获取特征值:
List<BleCharacteristic> bleCharacteristics = await WinBle.discoverCharacteristics(address: address, serviceId: serviceID);
读取特征值:
List<int> data = await WinBle.read(address: address, serviceId: serviceID, characteristicId: charID);
写入特征值:
await WinBle.write(address: address, service: serviceID, characteristic: charID, data: data, writeWithResponse: writeWithResponse);
订阅特征值更新:
await WinBle.subscribeToCharacteristic(address: address, serviceId: serviceID, characteristicId: charID);
// 取消订阅
await WinBle.unSubscribeFromCharacteristic(address: address, serviceId: serviceID, characteristicId: charID);
// 监听特征值更新
StreamSubscription _characteristicValueStream = WinBle.characteristicValueStream.listen((event) {
// 接收所有特征值事件
});
注意事项
- 需要Windows版本 >= 10.0.15014。
- 如果Windows发布构建在运行应用时打开命令提示符,请编辑
/windows/runner/main.cpp
文件,这是一个已知的Flutter问题。
示例代码
以下是一个完整的示例代码,展示了如何使用WinBle进行蓝牙设备扫描、连接和交互:
// ignore_for_file: avoid_print
import 'dart:async';
import 'package:flutter/material.dart';
import 'package:win_ble/win_ble.dart';
import 'package:win_ble/win_file.dart';
void main() {
runApp(const MaterialApp(debugShowCheckedModeBanner: false, home: MyApp()));
}
class MyApp extends StatefulWidget {
const MyApp({Key? key}) : super(key: key);
@override
State<MyApp> createState() => _MyAppState();
}
class _MyAppState extends State<MyApp> {
StreamSubscription? scanStream;
StreamSubscription? connectionStream;
StreamSubscription? bleStateStream;
bool isScanning = false;
BleState bleState = BleState.Unknown;
void initialize() async {
await WinBle.initialize(
serverPath: await WinServer.path(),
enableLog: true,
);
print("WinBle Initialized: ${await WinBle.version()}");
}
@override
void initState() {
initialize();
connectionStream = WinBle.connectionStream.listen((event) {
print("Connection Event : " + event.toString());
});
scanStream = WinBle.scanStream.listen((event) {
setState(() {
final index = devices.indexWhere((element) => element.address == event.address);
if (index != -1) {
final name = devices[index].name;
devices[index] = event;
if (event.name.isEmpty || event.name == 'N/A') {
devices[index].name = name;
}
} else {
devices.add(event);
}
});
});
bleStateStream = WinBle.bleState.listen((BleState state) {
setState(() {
bleState = state;
});
});
super.initState();
}
String bleStatus = "";
String bleError = "";
List<BleDevice> devices = [];
startScanning() {
WinBle.startScanning();
setState(() {
isScanning = true;
});
}
stopScanning() {
WinBle.stopScanning();
setState(() {
isScanning = false;
});
}
onDeviceTap(BleDevice device) {
Navigator.push(
context,
MaterialPageRoute(builder: (context) => DeviceInfo(device: device)),
);
}
@override
void dispose() {
scanStream?.cancel();
connectionStream?.cancel();
bleStateStream?.cancel();
super.dispose();
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text("Win BLe"),
centerTitle: true,
actions: [
kButton("Ble Status : ${bleState.toString().split('.').last}", () {}),
],
),
body: SizedBox(
child: Column(
children: [
const SizedBox(height: 10),
Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
crossAxisAlignment: CrossAxisAlignment.center,
children: [
kButton("Start Scan", () {
startScanning();
}),
kButton("Stop Scan", () {
stopScanning();
}),
kButton(
bleState == BleState.On ? "Turn off Bluetooth" : "Turn on Bluetooth", () {
if (bleState == BleState.On) {
WinBle.updateBluetoothState(false);
} else {
WinBle.updateBluetoothState(true);
}
}),
],
),
const Divider(),
Column(
children: [
Text(bleStatus),
Text(bleError),
],
),
Expanded(
child: devices.isEmpty
? noDeviceFoundWidget()
: ListView.builder(
itemCount: devices.length,
itemBuilder: (BuildContext context, int index) {
BleDevice device = devices[index];
return InkWell(
onTap: () {
stopScanning();
onDeviceTap(device);
},
child: Card(
child: ListTile(
title: Text("${device.name.isEmpty ? "N/A" : device.name} ( ${device.address} )"),
subtitle: Text("Rssi : ${device.rssi} | AdvTpe : ${device.advType}"),
),
),
);
},
),
),
],
),
),
);
}
Widget kButton(String txt, VoidCallback onTap) {
return ElevatedButton(
onPressed: onTap,
child: Text(txt, style: const TextStyle(fontSize: 20)),
);
}
Widget noDeviceFoundWidget() {
return Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
isScanning
? const CircularProgressIndicator()
: InkWell(
onTap: () {
startScanning();
},
child: const Icon(Icons.bluetooth, size: 100, color: Colors.grey),
),
const SizedBox(height: 10),
Text(isScanning ? "Scanning Devices ... " : "Click to start scanning")
],
);
}
}
此代码展示了如何使用WinBle插件进行蓝牙设备扫描、连接和交互。希望这些信息对你有所帮助!如果有任何问题或需要进一步的帮助,请随时提问。
更多关于Flutter蓝牙通信插件win_ble的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html
更多关于Flutter蓝牙通信插件win_ble的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html
当然,以下是如何在Flutter项目中使用win_ble
插件进行蓝牙通信的示例代码。win_ble
是一个用于Windows平台的Flutter蓝牙低功耗(BLE)通信插件。请确保你的开发环境已经设置好,并且你的Flutter项目已经正确配置以支持Windows平台。
1. 添加依赖
首先,在你的pubspec.yaml
文件中添加win_ble
依赖:
dependencies:
flutter:
sdk: flutter
win_ble: ^x.y.z # 请替换为最新版本号
然后运行flutter pub get
来安装依赖。
2. 配置插件
确保你的CMakeLists.txt
(如果你使用的是CMake)和windows
文件夹下的其他配置文件已经正确设置以支持蓝牙功能。
3. 使用插件
以下是一个简单的示例,展示如何使用win_ble
插件来扫描蓝牙设备并连接到第一个找到的设备:
import 'package:flutter/material.dart';
import 'package:win_ble/win_ble.dart';
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
home: BleDemo(),
);
}
}
class BleDemo extends StatefulWidget {
@override
_BleDemoState createState() => _BleDemoState();
}
class _BleDemoState extends State<BleDemo> {
late BluetoothManager bluetoothManager;
@override
void initState() {
super.initState();
bluetoothManager = BluetoothManager.instance;
bluetoothManager.initialize();
}
Future<void> scanDevices() async {
setState(() {
// 可以在这里更新UI,比如显示扫描中的提示
});
try {
List<BluetoothDevice> devices = await bluetoothManager.scanForDevices(
allowDuplicates: false,
timeout: Duration(seconds: 10),
);
if (devices.isNotEmpty) {
BluetoothDevice device = devices.first;
connectToDevice(device);
} else {
// 没有找到设备时的处理
print("No devices found");
}
} catch (e) {
print("Scanning failed: $e");
}
setState(() {
// 扫描结束后的UI更新
});
}
Future<void> connectToDevice(BluetoothDevice device) async {
try {
BluetoothRemoteDevice remoteDevice = await device.connect();
// 连接到设备后的处理
print("Connected to: ${remoteDevice.name}");
// 可以在这里继续发现服务、特征值等操作
} catch (e) {
print("Connection failed: $e");
}
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('Flutter Bluetooth Demo'),
),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Text('Press the button to scan for BLE devices.'),
SizedBox(height: 20),
ElevatedButton(
onPressed: scanDevices,
child: Text('Scan for Devices'),
),
],
),
),
);
}
}
注意事项
-
权限:确保你的应用具有访问蓝牙设备的权限。在Windows上,这通常意味着用户需要在系统设置中手动启用蓝牙功能,并且你的应用需要请求相应的权限。
-
异步操作:蓝牙操作通常是异步的,因此你需要在代码中处理这些异步操作,例如使用
async
和await
关键字。 -
错误处理:蓝牙通信可能会因为各种原因失败,例如设备不可达、权限被拒绝等。因此,确保在代码中添加适当的错误处理逻辑。
-
插件版本:随着Flutter和插件的更新,API可能会有所变化。因此,请查阅最新的
win_ble
文档以获取最新的使用方法和API变更。
这个示例代码提供了一个基本的框架,你可以根据需要进行扩展和修改。希望这能帮助你开始在Flutter中使用win_ble
插件进行蓝牙通信。