Asynchronous 同步连接到多个BLE设备的颤振

Asynchronous 同步连接到多个BLE设备的颤振,asynchronous,dart,async-await,flutter,bluetooth-lowenergy,Asynchronous,Dart,Async Await,Flutter,Bluetooth Lowenergy,我正在使用Flatter通过FlatterBlue库开发一个蓝牙低能应用程序,在这个应用程序中,我们可能同时连接到多个外围设备。 如果我单独连接到多个外围设备并同时向所有外围设备发送命令,我就能够连接到多个外围设备。 对于状态管理,我的BluetoothHelper是ScopedModel的模型 class BluetoothHelper extends Model { bool isProcessing = false; int val = 0; FlutterBlue fl

我正在使用Flatter通过FlatterBlue库开发一个蓝牙低能应用程序,在这个应用程序中,我们可能同时连接到多个外围设备。 如果我单独连接到多个外围设备并同时向所有外围设备发送命令,我就能够连接到多个外围设备。 对于状态管理,我的BluetoothHelper是ScopedModel的模型

class BluetoothHelper extends Model {

  bool isProcessing = false; 
  int val = 0;

  FlutterBlue flutterBlue = FlutterBlue.instance; //bluetooth library instance

  StreamSubscription scanSubscription;
  Map<DeviceIdentifier, ScanResult> scanResults = new Map();

  /// State
  StreamSubscription stateSubscription;
  BluetoothState state = BluetoothState.unknown;

  /// Device
  List<BluetoothDevice> devicesList = new List(); //todo

  bool get isConnected => (deviceList.size != 0);
  StreamSubscription deviceConnection;
  StreamSubscription deviceStateSubscription;
  List<BluetoothService> services = new List();
  Map<Guid, StreamSubscription> valueChangedSubscriptions = {};
  BluetoothDeviceState deviceState = BluetoothDeviceState.disconnected;

  Future startScan(String uuid) async {
    isProcessing = true;
    if (val == 0) {
      Future.delayed(Duration(milliseconds: 25), () => scanAndConnect(uuid));
      val++;
    } else {
      Future.delayed(Duration(seconds: 4), () => scanAndConnect(uuid));
    }
  }

  scanAndConnect(String uuid){
    scanSubscription =
        flutterBlue.scan(timeout: const Duration(seconds: 120), withServices: [
          //new Guid('FB755D40-8DE5-481E-A369-21C0B3F39664')]
        ]).listen((scanResult) {
          if (scanResult.device.id.toString() == uuid) {
            scanResults[scanResult.device.id] = scanResult;

            print("found! Attempting to connect" + scanResult.device.id.toString());
            device = scanResult.device;

            //connect(device);
            connect(device);
          }
        }, onDone: stopScan);
  }

  Future connect(BluetoothDevice d) {

    deviceConnection = flutterBlue.connect(d).listen(
          null,
        );

    deviceStateSubscription = d.onStateChanged().listen((s) {
      if (s == BluetoothDeviceState.connected) {
        stopScan();
        d.discoverServices().then((s) {
          print("connected to ${device.id.toString()}");
          services = s;
          services.forEach((service) {
            var characteristics = service.characteristics;
            for (BluetoothCharacteristic c in characteristics) {
              if (c.uuid.toString() == '') {//we look for the uuid we want to write to
                String handshakeValue ; //value is initiliazed here in code
                List<int> bytes = utf8.encode(handshakeValue);
                d.writeCharacteristic(c, bytes,
                    type: CharacteristicWriteType.withResponse);
                     devicesList.add(d);
              }
            }
          });
        });
      }
    });

  }
}
类BluetoothHelper扩展模型{
bool isProcessing=false;
int-val=0;
flatterblue flatterblue=flatterblue.instance;//蓝牙库实例
流媒体订阅;
映射扫描结果=新映射();
///陈述
流订阅和流订阅;
BluetoothState=BluetoothState.unknown;
///装置
列表设备列表=新列表();//待办事项
bool get isConnected=>(deviceList.size!=0);
流订阅设备连接;
流订阅设备状态订阅;
列表服务=新列表();
映射值ChangedSubscriptions={};
BluetoothDeviceState deviceState=BluetoothDeviceState.disconnected;
未来startScan(字符串uuid)异步{
isProcessing=true;
如果(val==0){
延迟(持续时间(毫秒:25),()=>scanAndConnect(uuid));
val++;
}否则{
Future.delayed(持续时间(秒:4),()=>scanAndConnect(uuid));
}
}
scanAndConnect(字符串uuid){
扫描订阅=
蓝色。扫描(超时:常量持续时间(秒:120),服务:[
//新Guid('FB755D40-8DE5-481E-A369-21C0B3F39664')]
]).listen((扫描结果){
if(scanResult.device.id.toString()==uuid){
scanResult[scanResult.device.id]=scanResult;
打印(“找到!正在尝试连接”+scanResult.device.id.toString());
device=scanResult.device;
//连接(设备);
连接(设备);
}
},onDone:停止扫描);
}
未来连接(蓝牙设备d){
设备连接=蓝色。连接(d)。听(
无效的
);
deviceStateSubscription=d.onStateChanged().listen((s){
如果(s==BluetoothDeviceState.connected){
停止扫描();
d、 discoverServices()。然后((s){
打印(“连接到${device.id.toString()}”);
服务=s;
services.forEach((服务){
var特性=服务特性;
用于(蓝牙特性中的c特性){
如果(c.uuid.toString()=''”{//我们查找要写入的uuid
字符串握手evalue;//值在代码中初始化
列表字节=utf8.encode(握手值);
d、 writeCharacteristic(c,字节,
类型:CharacteristicWriteType.withResponse);
设备列表。添加(d);
}
}
});
});
}
});
}
}
我试图循环抛出所有外设唯一标识符(UID),然后让它们以编程方式一个接一个地连接

这不是很好。它最终总是连接到最后一个外围设备。看起来blueblue实例一次只能扫描一个uid,如果它收到另一个请求,它会立即删除最后一个请求并移动到新的请求

我将同样的逻辑应用到单个外围逻辑的连接中,我会立即点击一个外围和第二个外围,然后它会连接到第二个外围。(在连接过程中,我当前没有阻塞UI或任何东西) 我需要等到第一个外设连接好后再转到下一个外设

上面的代码是我获取外设的唯一方法,但这段代码存在巨大的问题。它当前只能连接到2个设备。它使用延迟而不是回调来实现连接,在移动到第二个外围设备之前,为扫描和连接提供足够的时间

我的第一反应是将startScan和connect方法转换成异步方法,但这并不像我希望的那样有效

{await connect(device);}=>gives“内置标识符”await不能用作类型。我可能只是错误地设置了异步

我环顾四周寻找替代品,发现了补体和分离物。我不确定这有多重要

用户界面端:

我为封装在作用域模型子体中的按钮的ontap设置了以下方法。这将可靠地加载带有几个UID的外围设备UID列表,然后逐个连接到它们

connectAllPeripherals(BluetoothHelper model, List<String> peripheralUIDs) {
    for(var uuid in peripheralUIDs) { //list of strings containing the uuids for the peripherals I want to connect to
      model.startScan(uuid);
    }
}
连接所有外围设备(BluetoothHelper型号,列出外围设备UID){
对于(外设uids中的var uuid){//包含我要连接到的外设的uuid的字符串列表
型号:startScan(uuid);
}
}

不知道这一点是否仍然是一个问题

假设你的问题还没有得到解决。我认为你的问题是试图在flatter中维护连接(而不是仅仅连接多个设备并让flatter\u Blue/硬件管理连接)

我很高兴能够连接到多个设备;在您设置实例并维护多个设备属性的列表之后

i、 e.我制作了一个可编程设备类,其中包含以下各项:

StreamSubscription deviceConnection;
StreamSubscription deviceStateSubscription;
List<BluetoothService> services = new List();
Map<Guid, StreamSubscription> valueChangedSubscriptions = {};
BluetoothDeviceState deviceState = BluetoothDeviceState.disconnected;
有了上述功能,我可以在几毫秒内轮询多个设备


不知道这是否有帮助-但如果运气好的话,也有人碰到我的问题,他们会解决这个问题并节省一些时间。

不知道这一点是否仍然是个问题

假设你的问题还没有得到解决。我认为你的问题是试图在flatter中维护连接(而不是仅仅连接多个设备并让flatter\u Blue/硬件管理连接)

我很高兴能连接到多个设备
 await