Flutter蓝牙通信插件all_bluetooth的使用
Flutter蓝牙通信插件all_bluetooth的使用
all_bluetooth
是一个用于在Flutter应用中与蓝牙设备进行通信的插件。本文将详细介绍如何使用该插件,并提供完整的示例代码。
特性
- 连接到蓝牙设备
- 返回已配对设备列表
- 获取蓝牙状态(开/关)作为未来值或流
- 启动蓝牙服务器
- 监听蓝牙连接状态
- 监听蓝牙连接上的数据传输
开始使用
添加依赖
首先,在 pubspec.yaml
文件中添加 all_bluetooth
依赖:
dependencies:
all_bluetooth: ^<latest-version>
配置Android权限
在 AndroidManifest.xml
文件中添加以下权限:
<uses-permission android:name="android.permission.BLUETOOTH" />
<uses-permission android:name="android.permission.BLUETOOTH_ADMIN" />
<uses-permission android:name="android.permission.BLUETOOTH_CONNECT" />
<uses-permission android:name="android.permission.BLUETOOTH_SCAN" />
您可以使用 permission_handler
包来请求这些权限。
创建实例
在您的应用程序中创建 AllBluetooth
实例:
final allBluetooth = AllBluetooth();
导入包
在您的 Dart 文件中导入 all_bluetooth
包:
import "package:all_bluetooth/all_bluetooth.dart";
使用方法
在开始之前,请注意大多数功能仅在有可用的蓝牙连接时才能工作。因此,始终确保您正在监听蓝牙连接状态的 listenForConnection
流。
在调用任何函数之前,您可以使用 isBluetoothOn
方法或 streamBluetoothState
流来检查蓝牙是否打开或关闭。
主要方法和流
- closeConnection: 关闭蓝牙连接并释放所有资源。
- connectToDevice: 使用设备地址连接到另一个蓝牙设备。
- getBondedDevices: 返回已配对设备列表。
- isBluetoothOn: 检查蓝牙是否打开。
- startBluetoothServer: 打开服务器套接字以连接为服务器。
- startDiscovery: 开始发现新设备。
- stopDiscovery: 停止发现设备。
- sendMessage: 发送消息给连接的设备。
- discoverNewDevices: 监听新发现的设备。
- listenForConnection: 监听蓝牙连接状态。
- listenForData: 监听通过蓝牙连接传输的数据。
- streamBluetoothState: 监听设备蓝牙状态。
示例代码
以下是一个完整的示例代码,展示了如何使用 all_bluetooth
插件:
import 'package:all_bluetooth/all_bluetooth.dart';
import 'package:flutter/material.dart';
void main() async {
runApp(const MyApp());
}
final allBluetooth = AllBluetooth();
class MyApp extends StatelessWidget {
const MyApp({super.key});
@override
Widget build(BuildContext context) => MaterialApp(
debugShowCheckedModeBanner: false,
home: StreamBuilder<ConnectionResult>(
stream: allBluetooth.listenForConnection,
builder: (context, snapshot) {
final state = snapshot.data?.state ?? false;
if (state == true) {
final device = snapshot.data!.device;
return ChatScreen(device: device!);
}
return const HomeScreen();
},
),
);
}
class HomeScreen extends StatefulWidget {
const HomeScreen({super.key});
@override
State<HomeScreen> createState() => _HomeScreenState();
}
class _HomeScreenState extends State<HomeScreen> {
bool listeningForClient = false;
final bondedDevices = ValueNotifier<List<BluetoothDevice>>([]);
final scannedDevices = ValueNotifier<List<BluetoothDevice>>([]);
@override
void initState() {
super.initState();
}
@override
Widget build(BuildContext context) {
return StreamBuilder<bool>(
stream: allBluetooth.streamBluetoothState,
builder: (context, snapshot) {
final bluetoothOn = snapshot.data ?? false;
return Scaffold(
floatingActionButton: switch (listeningForClient) {
true => null,
false => FloatingActionButton(
backgroundColor: switch (bluetoothOn) {
true => Theme.of(context).primaryColor,
false => Colors.grey,
},
onPressed: switch (bluetoothOn) {
false => null,
true => () {
allBluetooth.startBluetoothServer();
setState(() {
listeningForClient = true;
});
},
},
child: const Icon(Icons.wifi_tethering),
)
},
appBar: AppBar(
title: const Text("Bluetooth Connect"),
),
body: switch (listeningForClient) {
true => Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
crossAxisAlignment: CrossAxisAlignment.center,
children: [
const Text("Waiting"),
const CircularProgressIndicator(),
FloatingActionButton(
onPressed: () {
setState(() {
listeningForClient = false;
});
allBluetooth.closeConnection();
},
child: const Icon(Icons.stop),
),
],
),
),
false => Column(
children: [
SingleChildScrollView(
scrollDirection: Axis.horizontal,
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Text(
switch (bluetoothOn) {
true => "ON",
false => "off",
},
style: TextStyle(
color: bluetoothOn ? Colors.green : Colors.red,
),
),
ElevatedButton(
onPressed: switch (bluetoothOn) {
false => null,
true => () {
allBluetooth
.getBondedDevices()
.then((newDevices) {
bondedDevices.value = newDevices;
});
},
},
child: const Text("Bonded Devices"),
),
ElevatedButton(
onPressed: switch (bluetoothOn) {
false => null,
true => () {
allBluetooth.startDiscovery();
},
},
child: const Text("Discover"),
),
ElevatedButton(
onPressed: switch (bluetoothOn) {
false => null,
true => () {
allBluetooth.stopDiscovery();
allBluetooth.discoverDevices.listen((event) {
scannedDevices.value = [
...scannedDevices.value,
event
];
});
},
},
child: const Text("Stop discover"),
),
],
),
),
if (!bluetoothOn)
const Center(child: Text("Turn bluetooth on"))
else
Expanded(
child: Column(
children: [
DeviceListWidget(
notifier: bondedDevices,
title: "Paired Devices",
),
DeviceListWidget(
notifier: scannedDevices,
title: "Scanned Devices",
),
],
),
),
],
),
},
);
},
);
}
}
class ChatScreen extends StatefulWidget {
final BluetoothDevice device;
const ChatScreen({super.key, required this.device});
@override
State<ChatScreen> createState() => _ChatScreenState();
}
class _ChatScreenState extends State<ChatScreen> {
final messageListener = ValueNotifier(<String>[]);
final messageController = TextEditingController();
@override
void initState() {
super.initState();
allBluetooth.listenForData.listen((event) {
if (event != null) {
messageListener.value = [
...messageListener.value,
event,
];
}
});
}
@override
void dispose() {
super.dispose();
messageController.dispose();
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text(widget.device.name),
actions: [
ElevatedButton(
onPressed: allBluetooth.closeConnection,
child: const Text("CLOSE"),
),
],
),
body: Padding(
padding: const EdgeInsets.all(8.0),
child: Column(
children: [
Expanded(
child: ValueListenableBuilder(
valueListenable: messageListener,
builder: (context, messages, child) {
return ListView.builder(
itemCount: messages.length,
itemBuilder: (context, index) {
final msg = messages[index];
return Padding(
padding: const EdgeInsets.symmetric(vertical: 5),
child: DecoratedBox(
decoration: BoxDecoration(
color: Theme.of(context).primaryColor,
borderRadius: BorderRadius.circular(10),
),
child: Padding(
padding: const EdgeInsets.all(5),
child: Text(
msg,
style: const TextStyle(color: Colors.white),
),
),
),
);
},
);
}),
),
Row(
children: [
Expanded(
child: TextField(
controller: messageController,
decoration: const InputDecoration(
border: OutlineInputBorder(),
),
),
),
Padding(
padding: const EdgeInsets.all(12),
child: FloatingActionButton(
onPressed: () {
final message = messageController.text;
allBluetooth.sendMessage(message);
messageController.clear();
FocusScope.of(context).unfocus();
},
child: const Icon(Icons.send),
),
),
],
)
],
),
),
);
}
}
class DeviceListWidget extends StatelessWidget {
final String title;
final ValueNotifier<List<BluetoothDevice>> notifier;
const DeviceListWidget({
required this.notifier,
required this.title,
super.key,
});
@override
Widget build(BuildContext context) {
return Expanded(
child: ValueListenableBuilder(
valueListenable: notifier,
builder: (context, value, child) {
return Column(
mainAxisSize: MainAxisSize.min,
children: [
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Text(
title,
style: const TextStyle(
decoration: TextDecoration.underline,
fontWeight: FontWeight.bold,
fontSize: 16,
),
),
Text(value.length.toString()),
],
),
Flexible(
fit: FlexFit.loose,
child: ListView.builder(
physics: const BouncingScrollPhysics(),
itemCount: value.length,
itemBuilder: (ctx, index) {
final device = value[index];
return ListTile(
title: Text(device.name),
subtitle: Text(device.address),
onTap: () async {
allBluetooth.connectToDevice(device.address);
},
);
},
),
),
],
);
}),
);
}
}
以上代码展示了如何使用 all_bluetooth
插件来实现蓝牙设备的发现、连接和通信。希望这个示例能帮助您更好地理解和使用该插件。如果您有任何问题或建议,请随时联系插件作者。
更多关于Flutter蓝牙通信插件all_bluetooth的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html
更多关于Flutter蓝牙通信插件all_bluetooth的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html
当然,以下是一个使用Flutter蓝牙通信插件all_bluetooth
的基本代码示例。这个示例展示了如何初始化插件、扫描蓝牙设备、连接到一个设备以及读写数据。请注意,实际使用中需要根据具体需求进行错误处理和功能扩展。
首先,你需要在你的pubspec.yaml
文件中添加all_bluetooth
依赖:
dependencies:
flutter:
sdk: flutter
all_bluetooth: ^最新版本号
然后运行flutter pub get
来安装依赖。
接下来是示例代码:
import 'package:flutter/material.dart';
import 'package:all_bluetooth/all_bluetooth.dart';
void main() {
runApp(MyApp());
}
class MyApp extends StatefulWidget {
@override
_MyAppState createState() => _MyAppState();
}
class _MyAppState extends State<MyApp> {
late BluetoothService _bluetoothService;
List<BluetoothDevice> _devices = [];
BluetoothDevice? _connectedDevice;
@override
void initState() {
super.initState();
_bluetoothService = BluetoothService.instance;
_bluetoothService.init().then((_) {
// 开始扫描设备
startScanningDevices();
});
}
void startScanningDevices() async {
_devices.clear();
setState(() {});
try {
_bluetoothService.startScanning().listen((List<BluetoothDevice> devices) {
setState(() {
_devices = devices;
});
});
} catch (e) {
print("Error scanning devices: $e");
}
}
void connectToDevice(BluetoothDevice device) async {
try {
_connectedDevice = await _bluetoothService.connectToDevice(device);
print("Connected to ${_connectedDevice?.name}");
// 开始监听设备的数据
startListeningToDeviceData();
} catch (e) {
print("Error connecting to device: $e");
}
}
void startListeningToDeviceData() async {
if (_connectedDevice != null) {
_connectedDevice!.inputStream!.listen((Uint8List data) {
String receivedData = String.fromCharCodes(data);
print("Received data: $receivedData");
});
}
}
void sendDataToDevice(String data) async {
if (_connectedDevice != null) {
Uint8List dataToSend = Uint8List.fromList(data.codeUnits);
_connectedDevice!.outputStream!.write(dataToSend);
print("Sent data: $data");
}
}
@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
appBar: AppBar(
title: Text('Flutter Bluetooth Communication'),
),
body: Padding(
padding: const EdgeInsets.all(16.0),
child: Column(
children: [
Text('Scanned Devices:'),
Expanded(
child: ListView.builder(
itemCount: _devices.length,
itemBuilder: (context, index) {
return ListTile(
title: Text(_devices[index].name ?? 'Unknown'),
onTap: () => connectToDevice(_devices[index]),
);
},
),
),
ElevatedButton(
onPressed: _connectedDevice != null ? () => sendDataToDevice('Hello Device!') : null,
child: Text('Send Data'),
),
],
),
),
),
);
}
}
注意事项:
- 权限:确保在Android和iOS平台上都申请了蓝牙相关的权限。
- 插件初始化:
_bluetoothService.init()
需要在开始使用蓝牙功能之前调用。 - 错误处理:实际应用中应添加更多的错误处理逻辑,例如处理连接失败、设备断开等情况。
- 平台差异:不同平台(Android和iOS)上蓝牙通信的实现可能有所不同,请仔细阅读
all_bluetooth
插件的文档以了解平台特定的差异。
这个示例代码提供了一个基本的框架,你可以在此基础上根据你的具体需求进行扩展和修改。