Я использую flutter для работы над приложением Bluetooth с низким энергопотреблением через библиотеку flutterBlue, в которой мы потенциально можем подключаться к нескольким периферийным устройствам одновременно.Я могу подключаться к нескольким периферийным устройствам, если я подключаюсь к ним индивидуально и посылаю команды всем им одновременно.Для управления состоянием мой 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);
}
}
});
});
}
});
}
}
Я пытаюсь закинуть все периферийные уникальные идентификаторы (UID) и затем программно подключить их один за другим.
Это не сработало.Это всегда будет заканчиваться подключением к самому последнему периферийному устройству.Похоже, что экземпляр flutterblue может сканировать только один uid за раз, и если он получает другой запрос, он немедленно отбрасывает последний запрос и переходит на новый.
Я применил эту же логику к соединениюиндивидуальная периферийная логика, в которой я бы сразу подключал одну периферию и вторую, и она соединялась со второй.(В настоящее время я не блокирую пользовательский интерфейс или что-либо еще во время процесса подключения) Мне нужно подождать, пока первое периферийное устройство не будет подключено, прежде чем перейти к следующему.
Приведенный выше код - единственный способ получить мои периферийные устройства, но с этим кодом возникают огромные проблемы.В настоящее время он может подключаться только к 2 устройствам.Он использует задержки вместо обратных вызовов для установления соединения, давая достаточно времени для сканирования и соединения, прежде чем переходить на второе периферийное устройство.
Моим первым инстинктом было преобразовать методы startScan и connect в асинхронные методы, ноэто работает не так хорошо, как я надеюсь.
{ожидание соединения (устройство);} => дает «встроенный Идентификатор« await »нельзя использовать как тип. Я мог бы просто неправильно настроить асинхронные.
Я искал альтернативы и натолкнулся на Completers and IsolatesЯ не уверен, насколько это может быть актуально.
СТОРОНА ПЕРЕДАЧИ:
У меня установлен следующий метод для нажатия кнопки, обернутой в потомка модели с областью действия.надежно загружайте список периферийных устройств с помощью нескольких идентификаторов, а затем подключайтесь к ним один за другим.
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);
}
}