Calling requestDevice twice produces error on Android when using Evothings adapter
mikaelkindborg opened this issue · 5 comments
Found a bug on Android when calling requestDevice a second time (did disconnect in between calls), get this error "requestDevice error: Android function startLeScan failed".
I now understand why this error happens. It is because stopScan
is never called. (This was an issue on iOS also, but did not cause an error.) Need some advice on how to proceed.
The Evothings adapter never calls the callback completeFn
in startScan
:
adapter.startScan = function(
serviceUUIDs, // String[] serviceUUIDs advertised service UUIDs to restrict results by
foundFn, // Function(Object deviceInfo) function called with each discovered deviceInfo
completeFn, // Function() function called when scanning completed
errorFn // Function(String errorMsg) function called if error occurs
)
{
init(function() {
evothings.ble.startScan(
function(deviceInfo) {
if (foundFn) { foundFn(createBleatDeviceObject(deviceInfo)); }
},
function(error) {
if (errorFn) { errorFn(error); }
});
});
};
https://github.com/thegecko/bleat/blob/master/dist/adapter.evothings.js#L67
This means that the variable scanner
in api.web-bluetooth.js
won't be set:
https://github.com/thegecko/bleat/blob/master/dist/api.web-bluetooth.js#L202
And adapter.stopScan()
is never called in cancelRequest
:
https://github.com/thegecko/bleat/blob/master/dist/api.web-bluetooth.js#L209
I don't quite understand when completeFn
is supposed to be called. Should it be called as soon as scanning begins (when startScan
is called)?
This might be a problem also for other adapters if scanning is started and completeFn
for some reason is never called. Then stopScan
will not be called.
Should I solve this by calling completeFn
or should the code in api.web-bluetooth.js
handle this situation?
Making this change to startScan
in the adapter solves the bug:
adapter.startScan = function(
serviceUUIDs, // String[] serviceUUIDs advertised service UUIDs to restrict results by
foundFn, // Function(Object deviceInfo) function called with each discovered deviceInfo
completeFn, // Function() function called when scanning completed
errorFn // Function(String errorMsg) function called if error occurs
)
{
init(function() {
evothings.ble.startScan(
function(deviceInfo) {
if (foundFn) { foundFn(createBleatDeviceObject(deviceInfo)); }
},
function(error) {
if (errorFn) { errorFn(error); }
});
if (completeFn) { completeFn(); }
});
};
Your suggested change is the right fix. Both APIs expect the callback function to be executed once scanning starts.
I would also suggest the evothings adapter explicitly stops any scanning before starting if that's what it requires. This is an adapter implementation issue, the old ChromeOS adapter used to always call stop() before starting a scan, too.
In this case, it's your call whether you just add the callback function or both a callback and explicit stop().
@thegecko Thanks a lot for the help. Added call to completeFn
and also now stopping scan before scanning starts.
Tested working on Android and iOS.