quick_blue
quick_blue copied to clipboard
[Windows] Unhandled Exception: PlatformException(IllegalArgument, Unknown devicesId: .... , null, null)
QuickBlue irregularly throws an exception when calling
await QuickBlue.setNotifiable(
device.address,
myUartServiceUUID,
myUartCharacteristicsUUID,
BleInputProperty.notification);
This exception does not always occur thats why I assume it's a timing error.
Here's the full code:
// scan for device
String deviceId;
QuickBlue.scanResultStream.listen((result) {
deviceId = result.deviceId;
// return if device found
});
QuickBlue.startScan();
// wait some time for scanning
await Future.delayed(const Duration(seconds: 1));
QuickBlue.stopScan();
// set value handler
QuickBlue.setValueHandler((String deviceId, String characteristicId, Uint8List value) {
// do something with the recevied values
});
// connect and set notifiable
QuickBlue.connect(deviceId);
// give quick_blue some time to handle async function
await Future.delayed(const Duration(seconds: 2));
await QuickBlue.setNotifiable(
deviceId,
myUartServiceUUID,
myUartCharacteristicsUUID,
BleInputProperty.notification);
// give quick_blue some time to handle async function
await Future.delayed(const Duration(seconds: 2));
What I did trying to fix it:
- added delays (see ahead)
- checked for the correct
deviceId
. ThedeviceId
comes from the scan result and stable works forQuickBlue.connect(deviceId);
Is this related to: #93, or #90?
Does anyone have an idea how I can fix/avoid the exception?
Thanks!
You can use prerelease plugin version 0.5.0-dev.2 In this version, the author completed the receiving serviceId and characteristicIds from device for Windows.
QuickBlue.setConnectionHandler(_handleConnectionChange);
QuickBlue.setServiceHandler(_handleServiceDiscovery);
void _handleConnectionChange(String deviceId, BlueConnectionState state) {
if (state == BlueConnectionState.connected) {
QuickBlue.discoverServices(deviceId);
}
}
//The main point: This handler is called multiple times during the connection process
void _handleServiceDiscovery(String deviceId, String serviceId, List<String>? characteristicIds) {
if (deviceId.isNotEmpty && serviceId.isNotEmpty && characteristicIds != null && characteristicIds.length > 1) {
//Update: Here you are already dealing with different services and you can choose which you need, no need any Future and delays :-)
}
}
}
@alevlako Thanks for the fast response!
You can use prerelease plugin version 0.5.0-dev.2
Have tried this. Unfortunately this does not fix the error...
@rebeccasc Hi, did you find any solution or workaround?
@rebeccasc Hi, did you find any solution or workaround?
I fixed it with some workaround. Maybe it's not the smartest way to solve it but it works for me.
First I wrap the code block with an flutter runZonedGuarded so the error can be caught. It turned out that the thrown error cannot be caught by a simple try-catch
statement. Because the error will be thrown irregularly I simply try to run the code 5 times. Practice shows that it usually works with the second call. The code looks like this:
var connectionRetry = 5;
while (connectionRetry > 0 && !(await connectPlatformWindows())) {
// connection failed, try again
connectionRetry--;
}
Future<bool> connectPlatformWindows() async {
var success = true;
await runZonedGuarded(() async {
// run the code ahead ...
QuickBlue.setValueHandler((String deviceId, String characteristicId, Uint8List value) {
// do something with the recevied values
});
QuickBlue.connect(deviceId);
// give quick_blue some time to handle async function
await Future.delayed(const Duration(seconds: 2));
await QuickBlue.setNotifiable(
deviceId,
myUartServiceUUID,
myUartCharacteristicsUUID,
BleInputProperty.notification);
// give quick_blue some time to handle async function
await Future.delayed(const Duration(milliseconds: 250));
}, (e, stack) {
success = false;
});
return success;
}
Hope it helps.
@rebeccasc Hi, did you find any solution or workaround?
I fixed it with some workaround. Maybe it's not the smartest way to solve it but it works for me.
First I wrap the code block with an flutter runZonedGuarded so the error can be caught. It turned out that the thrown error cannot be caught by a simple
try-catch
statement. Because the error will be thrown irregularly I simply try to run the code 5 times. Practice shows that it usually works with the second call. The code looks like this:var connectionRetry = 5; while (connectionRetry > 0 && !(await connectPlatformWindows())) { // connection failed, try again connectionRetry--; } Future<bool> connectPlatformWindows() async { var success = true; await runZonedGuarded(() async { // run the code ahead ... QuickBlue.setValueHandler((String deviceId, String characteristicId, Uint8List value) { // do something with the recevied values }); QuickBlue.connect(deviceId); // give quick_blue some time to handle async function await Future.delayed(const Duration(seconds: 2)); await QuickBlue.setNotifiable( deviceId, myUartServiceUUID, myUartCharacteristicsUUID, BleInputProperty.notification); // give quick_blue some time to handle async function await Future.delayed(const Duration(milliseconds: 250)); }, (e, stack) { success = false; }); return success; }
Hope it helps.
Thanks for reply, It looks really interesting workaround. I'have tried it , but infortunately, in my case i'm getting native windows fatal crash on first call of connect method (even runZonedGuarded not catching exception). I really don't know why this package has so chaotic behavior for windows platform implementation. I've also tried to make connection via win32 package with winsock2, but there are also has its own issues. Now I'm just stuck.
... in my case i'm getting native windows fatal crash on first call of connect method (even runZonedGuarded not catching exception). I really don't know why this package has so chaotic behavior for windows platform implementation. I've also tried to make connection via win32 package with winsock2, but there are also has its own issues. Now I'm just stuck.
The plugin behaves like this when there is no bluetooth receiver (dongle) connected to the PC. This is a known issue and it has the fix.