Flutter Web蓝牙通信插件flutter_web_bluetooth的使用
Flutter Web蓝牙通信插件flutter_web_bluetooth的使用
Introduction
flutter_web_bluetooth
是一个Dart插件,用于支持Web Bluetooth API。它不仅限于Flutter项目,还可以与AngularDart等其他Dart项目兼容,并且能够很好地融入Dart原生项目中,以实现跨平台应用的Web端支持。
该库在非浏览器环境中(例如命令行工具或移动设备)也能编译,但其功能仅限于浏览器环境。有关概念验证的示例代码,请访问jeroen1602.github.io/flutter_web_bluetooth/。
Limited Support
Web蓝牙API仍处于草案阶段,因此并非所有浏览器都完全支持它。请查阅canIUse.com了解各浏览器的支持情况。某些浏览器版本可能不提供API的所有特性。
Requirements
- 浏览器和设备支持:确保你使用的浏览器和设备支持Web蓝牙API。对于Linux上的Chrome,可能需要启用特定标志位。
- 安全上下文:必须通过HTTPS或本地主机访问,以确保API可用性。
Usage
检查浏览器是否支持Web蓝牙API
// 检查当前用户代理是否支持蓝牙API
final supported = FlutterWebBluetooth.instance.isBluetoothApiSupported;
检查蓝牙适配器是否可用
// 获取表示蓝牙适配器是否可用的流
final available = FlutterWebBluetooth.instance.isAvailable;
请求连接设备
在请求设备之前,你需要指定想要连接的服务。如果不指定具体服务,则无法发现这些服务!
// 定义要通信的服务UUID列表
final requestOptions = RequestOptionsBuilder.acceptAllDevices(optionalServices: [
BluetoothDefaultServiceUUIDS.deviceInformation.uuid // 示例服务UUID
]);
try {
final device = await FlutterWebBluetooth.instance.requestDevice(requestOptions);
} on UserCancelledDialogError {
// 用户取消了对话框
} on DeviceNotFoundError {
// 根据定义的选项,没有找到范围内的设备
}
发现服务并读取特征值
一旦获取到设备实例,你可以遍历它的服务,并查找感兴趣的特征值。
await device.connect();
final services = await device.discoverServices();
final service = services.firstWhere((service) => service.uuid == BluetoothDefaultServiceUUIDS.deviceInformation.uuid);
// 现在获取特征值
final characteristic = await service.getCharacteristic(BluetoothDefaultCharacteristicUUIDS.manufacturerNameString.uuid);
final value = characteristic.readValue(); // 返回的是ByteData对象
device.disconnect();
访问已配对设备
如果启用了“实验性Web平台特性”标志,可以通过监听设备流来获取用户已配对并授权的设备集合。
// 获取所有已配对设备的流
FlutterWebBluetooth.instance.devices.listen((devices) {
// 处理已配对设备
});
自定义日志记录器
你可以覆盖库默认的日志记录器,以便自定义日志输出位置。
import 'package:flutter_web_bluetooth/web_bluetooth_logger.dart';
setWebBluetoothLogger(Logger("my logger"));
示例Demo
下面是一个简单的Flutter Web应用程序示例,展示了如何使用flutter_web_bluetooth
插件:
import "dart:async";
import "package:flutter/material.dart";
import "package:flutter_web_bluetooth/flutter_web_bluetooth.dart";
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
home: StreamBuilder<bool>(
stream: FlutterWebBluetooth.instance.isAvailable,
initialData: false,
builder: (context, snapshot) {
final available = snapshot.data ?? false;
return Scaffold(
appBar: AppBar(title: Text('Flutter Web Bluetooth Example')),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Text(
'Bluetooth is ${available ? 'available' : 'not available'}',
),
ElevatedButton(
onPressed: () async {
if (available) {
try {
final device = await FlutterWebBluetooth.instance.requestDevice(
RequestOptionsBuilder.acceptAllDevices(optionalServices: ['0000180a-0000-1000-8000-00805f9b34fb']), // 设备信息服务UUID
);
print('Connected to device: ${device.name}');
} catch (e) {
print('Failed to connect: $e');
}
}
},
child: Text('Connect to a Bluetooth Device'),
),
],
),
),
);
},
),
);
}
}
此示例创建了一个简单的UI,用于检查蓝牙是否可用,并提供了一个按钮来尝试连接到附近的蓝牙设备。当点击按钮时,它会弹出一个选择设备的对话框,用户可以选择要连接的设备。如果成功连接,将在控制台打印出设备名称。
更多关于Flutter Web蓝牙通信插件flutter_web_bluetooth的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html
更多关于Flutter Web蓝牙通信插件flutter_web_bluetooth的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html
当然,以下是一个使用Flutter Web蓝牙通信插件flutter_web_bluetooth
的示例代码。这个示例展示了如何扫描附近的蓝牙设备,连接到某个设备,并读取其服务、特征和值。
首先,确保你已经在pubspec.yaml
文件中添加了flutter_web_bluetooth
依赖:
dependencies:
flutter:
sdk: flutter
flutter_web_bluetooth: ^x.y.z # 请使用最新版本号
然后,运行flutter pub get
来安装依赖。
接下来,编写Flutter代码:
import 'package:flutter/material.dart';
import 'package:flutter_web_bluetooth/flutter_web_bluetooth.dart';
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
home: BluetoothApp(),
);
}
}
class BluetoothApp extends StatefulWidget {
@override
_BluetoothAppState createState() => _BluetoothAppState();
}
class _BluetoothAppState extends State<BluetoothApp> {
List<BluetoothDevice> devices = [];
BluetoothRemoteGATTServer? server;
BluetoothRemoteGATTService? service;
BluetoothRemoteGATTCharacteristic? characteristic;
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('Flutter Web Bluetooth Example'),
),
body: Padding(
padding: const EdgeInsets.all(16.0),
child: Column(
children: [
ElevatedButton(
onPressed: scanDevices,
child: Text('Scan Devices'),
),
SizedBox(height: 20),
if (devices.isNotEmpty)
ListView.builder(
itemCount: devices.length,
itemBuilder: (context, index) {
return ListTile(
title: Text(devices[index].name ?? 'Unknown Device'),
subtitle: Text(devices[index].id),
trailing: ElevatedButton(
onPressed: () => connectToDevice(devices[index]),
child: Text('Connect'),
),
);
},
),
SizedBox(height: 20),
if (server != null)
Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text('Connected to: ${server!.device.name ?? 'Unknown Device'}'),
ElevatedButton(
onPressed: listServices,
child: Text('List Services'),
),
if (service != null)
Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text('Selected Service: ${service!.uuid}'),
ElevatedButton(
onPressed: listCharacteristics,
child: Text('List Characteristics'),
),
if (characteristic != null)
Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text('Selected Characteristic: ${characteristic!.uuid}'),
ElevatedButton(
onPressed: readCharacteristicValue,
child: Text('Read Value'),
),
],
),
],
),
],
),
],
),
),
);
}
Future<void> scanDevices() async {
setState(() {
devices = [];
});
try {
var requestDeviceOptions = BluetoothRequestDeviceOptions(
filters: [
BluetoothDeviceFilter(
namePrefix: '', // 设置为空字符串以扫描所有设备
),
],
optionalServices: [],
);
var devices = await navigator.bluetooth.requestDevice(requestDeviceOptions);
setState(() {
this.devices = devices;
});
} catch (e) {
print('Error scanning devices: $e');
}
}
Future<void> connectToDevice(BluetoothDevice device) async {
try {
server = await device.gatt.connect();
print('Connected to ${device.name}');
} catch (e) {
print('Error connecting to device: $e');
}
}
Future<void> listServices() async {
if (server == null) return;
try {
var services = await server!.primaryServices();
print('Services: ${services.map((s) => s.uuid).join(', ')}');
// 假设选择第一个服务进行后续操作
setState(() {
service = services.firstOrNull;
});
} catch (e) {
print('Error listing services: $e');
}
}
Future<void> listCharacteristics() async {
if (service == null) return;
try {
var characteristics = await service!.characteristics();
print('Characteristics: ${characteristics.map((c) => c.uuid).join(', ')}');
// 假设选择第一个特征进行后续操作
setState(() {
characteristic = characteristics.firstOrNull;
});
} catch (e) {
print('Error listing characteristics: $e');
}
}
Future<void> readCharacteristicValue() async {
if (characteristic == null) return;
try {
var value = await characteristic!.readValue();
print('Characteristic value: ${new TextDecoder().decode(value)}');
} catch (e) {
print('Error reading characteristic value: $e');
}
}
}
注意事项:
- 代码中使用了
navigator.bluetooth
,这是flutter_web_bluetooth
插件提供的API。 - 在Web平台上,蓝牙权限和可用性可能受到浏览器的限制,因此请确保在支持Web蓝牙的浏览器(如Chrome)上运行此代码。
- 由于隐私和安全原因,浏览器可能需要用户明确授予访问蓝牙设备的权限。
- 代码中的错误处理仅用于演示,在实际应用中你可能需要更详细的错误处理和用户反馈。
这个示例展示了如何使用flutter_web_bluetooth
插件进行蓝牙通信的基本流程,包括扫描设备、连接设备、读取服务和特征值。根据具体需求,你可以进一步扩展这些功能。