记录自己开发蓝牙通信功能过程
插件使用:flutter_blue
蓝牙硬件:hc-08
在代码之前需要设置蓝牙权限和位置权限
1:扫描蓝牙设备,返回 deviceid 列表
//可以提前注册扫描监听事件
FlutterBlue flutterBlue = FlutterBlue.instance; List<String> blueId = []; flutterBlue.scanResults.listen((results) {// do something with scan results for (ScanResult r in results) { if(!blueId.contains(r.device.id.id)) { blueId.add(r.device.id.id); //添加到集合,输出到ui setState(() { this._blueDevice.add(r); }); } } });
//开始扫描,(扫描前先停止扫描,防止多次执行扫描动作时报错)
FlutterBlue flutterBlue = FlutterBlue.instance; flutterBlue.stopScan().then((value){ flutterBlue.startScan(timeout: Duration(seconds: 4)); });
2:找到自己需要连接的蓝牙设备
(我这里是hc-08模块,通过连接电脑设置蓝牙名称,扫描时会有名称出现)
3:连接蓝牙设备,这里可以停止扫描蓝牙设备动作
//device 为第二步中选择的蓝牙设备
print('开始连接'); await device.connect(); print('连接成功');
4:扫描设备服务
BluetoothCharacteristic mCharacteristic; device.discoverServices().then((services) { setState(() { this._services = services; }); });
//services是一个列表,每一个service又对应多个 Characteristics
一个设备 device 里面有多个服务 service ,这么多个service干嘛的,我不知道,只知道其中uuid 包含有 FFE0 的就是我们需要使用的读写的服务
5:找到服务,找到对应的 Characteristic,进行读写操作
//接受消息(读取消息) await char.setNotifyValue(true); Utf8Codec decode = new Utf8Codec(); char.value.listen((val) { print('接受到消息:${val}'); List<int> list2 = val.map((e) => e as int).toList(); String msg = String.fromCharCodes(list2); setState(() { this.receiveData.add(msg); }); });
//写消息 (withoutResponse 参数不设置默认false,在android端发送消息正常,但是ios不行,设置为true后,都正常)
char.write(msg, withoutResponse: true);
ps:
1:打包需要设置,否则可能又bug https://www.cnblogs.com/liumang/p/14800305.html
2:android 需要注意,有些设备蓝牙状态读取正常,但是不能进行扫描,需要关掉蓝牙再重新打开
(我在oppo手机上碰到这个问题,一度查问题查到自闭)
3:项目位置 (https://github.com/liumang8691/flutter_blue_map.git)