基于flutter_blue_plus的两部Android手机BLE通信与传输技术问询
flutter_blue_plus实现Android手机间BLE通信问题解答
核心疑问解答
1. 能否向选中的Android手机发送文件、文本或消息?
可以,但需明确BLE的角色分工:
- 一台手机作为中心设备(Central):负责扫描、发起连接、读写数据
- 另一台手机作为外设设备(Peripheral):必须主动广播自定义BLE服务及可写入的特征值(Characteristic)
- 文本/短消息(如"HI THERE")可直接通过写入特征值实现;文件由于BLE带宽限制,需要分片拆分后逐段传输,再在接收端拼接。
2. 发送数据失败,提示未开启写入权限?
从以下几个维度排查:
- 特征值权限检查:确认目标Characteristic的
properties.write或properties.writeWithoutResponse属性为true,只有具备写入属性的特征值才能接收数据。 - 代码写法修正:使用flutter_blue_plus提供的
write()或writeWithoutResponse()方法,确保传入正确的二进制数据(如字符串转codeUnits)。 - Android系统权限:在
AndroidManifest.xml中添加对应权限,并动态申请:<!-- Android 12+ --> <uses-permission android:name="android.permission.BLUETOOTH_SCAN" /> <uses-permission android:name="android.permission.BLUETOOTH_CONNECT" /> <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" /> <!-- 作为外设时需添加 --> <uses-permission android:name="android.permission.BLUETOOTH_ADVERTISE" /> <!-- Android 11及以下 --> <uses-permission android:name="android.permission.BLUETOOTH" /> <uses-permission android:name="android.permission.BLUETOOTH_ADMIN" /> <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" /> - 连接状态验证:确保设备已成功连接并完成服务发现(
discoverServices())后再执行写入操作。
3. 能否程序化建立蓝牙配对与连接?
- 连接:可以通过
device.connect()方法程序化发起连接,无需人工干预。 - 配对:BLE配对属于Android系统级操作,flutter_blue_plus无法完全绕过系统配对弹窗,但可以通过代码触发连接,当系统检测到需要配对时会自动弹出授权框,用户确认后即可完成配对流程;若设备已配对过,后续连接可自动完成。
4. 两部Android手机BLE通信机制
BLE通信基于角色模型实现:
- 外设端(Peripheral):
- 手机需开启BLE外设模式,创建自定义服务(Service)及对应特征值(Characteristic),并对外广播服务UUID。
- 特征值需配置读写权限,用于接收或发送数据。
- 中心端(Central):
- 扫描周围BLE设备,识别到外设的广播后发起连接。
- 连接成功后,调用
discoverServices()获取外设的服务和特征值列表。
- 数据交互:
- 中心端通过写入特征值向外设发送数据,外设通过监听特征值的写入事件接收数据;反之,外设也可主动更新特征值,中心端通过监听特征值的通知事件获取数据。
代码修正(适配flutter_blue_plus最新版本)
你提到的name、id等方法已过时,以下是更新后的示例代码:
import 'package:flutter_blue_plus/flutter_blue_plus.dart'; // 扫描BLE设备 void startScan() { final scanSubscription = FlutterBluePlus.instance.scan().listen((ScanResult result) { // 打印设备名称和ID(最新版用platformName和remoteId) print('发现设备: ${result.device.platformName} | ID: ${result.device.remoteId}'); }); // 5秒后停止扫描 Future.delayed(const Duration(seconds: 5), () { scanSubscription.cancel(); FlutterBluePlus.instance.stopScan(); }); } // 连接设备并发送数据 Future<void> connectAndSendData(BluetoothDevice device) async { try { // 发起连接 await device.connect(); // 发现设备服务 List<BluetoothService> services = await device.discoverServices(); // 遍历服务,找到自定义服务(需与外设端的UUID一致) for (var service in services) { if (service.uuid.toString() == "0000ffe0-0000-1000-8000-00805f9b34fb") { // 遍历特征值,找到可写入的特征 for (var characteristic in service.characteristics) { if (characteristic.properties.write) { // 发送"HI THERE"消息 List<int> message = "HI THERE".codeUnits; await characteristic.write(message); print("消息发送成功"); } } } } } catch (e) { print("连接或发送失败: $e"); } }
具体问题解答
① 每部Android手机的BluetoothService和UUID是否各不相同?
- 标准服务:如电池服务(UUID:
0000180f-0000-1000-8000-00805f9b34fb)、心率服务等,UUID是蓝牙联盟统一规定的,所有支持该服务的设备都使用相同UUID。 - 自定义服务:由开发者自行定义UUID,你可以在两台手机的应用中设置相同的自定义服务UUID,确保双方能识别彼此的服务。
- 手机系统自带的BLE服务UUID是固定标准值,但应用创建的自定义服务UUID可自主指定。
② 如何在两部手机间建立BLE连接?能否申请权限?
连接步骤:
- 外设端配置:在其中一台手机上实现BLE外设模式,创建自定义服务和可读写特征值,并开启广播(flutter_blue_plus主要支持中心端,外设端可借助
flutter_ble_peripheral插件或Android原生代码实现)。 - 中心端操作:在另一台手机上用flutter_blue_plus扫描设备,找到外设的广播后发起连接,完成服务发现后即可读写数据。
权限申请:
- 必须在
AndroidManifest.xml中添加前文提到的权限。 - 对于Android 6.0及以上版本,需要动态申请位置权限(扫描BLE设备需要),可使用
permission_handler插件实现:import 'package:permission_handler/permission_handler.dart'; Future<void> requestPermissions() async { Map<Permission, PermissionStatus> statuses = await [ Permission.bluetoothScan, Permission.bluetoothConnect, Permission.location, ].request(); // 检查权限是否获取成功 if (statuses[Permission.bluetoothScan] != PermissionStatus.granted) { print("蓝牙扫描权限未获取"); } }
内容的提问来源于stack exchange,提问作者iAmNewUSER
相关产品推荐
相关产品推荐

