記錄自己開發藍牙通信功能過程
插件使用: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)