Sorry for my bad eng, but I have one issue and I didn't find any solution and my options were not so good.
The issue is next: I need to scan BLE devices and show all scanned in the same view list for a user. The list must be actual (if a device was lost, it must leave from the list, if mobile was found a new device, this device adding in the list). You can imagine a simple Bluetooth (BL) page in Android settings when BL is turn on and there is a list with available BL devices.
In docs this library I found this function: bleManager.startDeviceScan. there is a listener, which has device and error. This listener is working for each device a lot of times. In theory, we can to do something here...
My first idea was filtering all devices from the list in this listener. For recognizing lost devices I added in my list for each device time (in ms), when it was last scanned. I updating time for the current device (parameter of function) in this listener and remove old devices if time now - time last scanned > 5s (for example) It good worked for all situations, except if I have just 1 device. This device was well added in the list and a good updated. But when a device is lost and the list had just that lost device, the listener is not called and we cant remove it from the list and this device is in the stored list but not scanned yet.
My second idea was to parallel process adding in the list and process remove lost devices. I'm using sagas, redux in my project and decided to use the listener just to add devices and scan-time in the list. And special cyclic saga for check all list and remove old. I used delay 1000ms in this cycle and expected that its a better idea and will be working. But as a result, I had a bad situation with the callbacks queue (in js low-level). I saw by console.log that first called listener, it added device in the list. Then called 4-5 cycle actions for clear old devices and no listeners (each iteration of the cycle has delay 1000ms in end)! Then, when the device was deleted because the listener didn't call all the time, the listener working one time and add my device and then cycle with 4-5 iterations and listener and ...
Can you help me resolve this problem? Probably I can improve my ideas or use some other things (API what I don't know or some another algorithm)... Now I have no ideas about what I can to do.
Ok, I found a solution using recursive setTimeout for each device, and if the device was not found any time, it deletes itself from the list.
I hope it'll help someone!
Hello, I try to make like you a list of devices found arround the phone, but I can't find any examples... do you have some advices or exemples with you that can help me? thank you
fun fact: it's been a year to the day since this issue was written!
Hello, I try to make like you a list of devices found arround the phone, but I can't find any examples... do you have some advices or exemples with you that can help me? thank you
fun fact: it's been a year to the day since this issue was written!
Hello! Yeah, I resolved this issue just using recursive setTimeout for each found device. I'll try to explain the logic below:
1) I have some internal array width objects of found devices. Each object has deviceId and timerId and lastScan date-time.
2) in a callback which is calling every time when some device was found:
I'm not sure that explained it clear, just give you my part of code with recursive setTimeout logic:
import moment from 'moment';
import { path, propIs } from 'ramda';
// structure of item:
// deviceId => {
// lastScan: int,
// timerId: timeoutId,
// }
let localDevicesList = {};
export const getActualityDeviceChecker = (deviceTimeout, checkTimeout, removeDevice) =>
function checkActualityOfDevice(deviceId) {
const timeNow = moment().valueOf();
const timeOld = path([deviceId, 'lastScan'], localDevicesList);
if (timeNow - timeOld < deviceTimeout) {
localDevicesList[deviceId].timerId = setTimeout(
checkActualityOfDevice,
checkTimeout,
deviceId,
);
} else {
delete localDevicesList[deviceId];
removeDevice({ deviceId });
}
};
export const isDeviceInList = deviceId => propIs(Object, deviceId, localDevicesList);
export const addDeviceInList = (deviceId, timerId) => {
localDevicesList[deviceId] = {
lastScan: moment().valueOf(),
timerId,
};
};
export const updateDevicesTimeInList = deviceId => {
if (isDeviceInList(deviceId)) {
localDevicesList[deviceId].lastScan = moment().valueOf();
}
};
export const clearDevicesList = () => {
localDevicesList = {};
};
Hi, where does the prop deviceId for the checkActualityOfDevice - function come from? And where do you call the getActualityDeviceChecker - function exaclty?
Most helpful comment
Ok, I found a solution using recursive setTimeout for each device, and if the device was not found any time, it deletes itself from the list.
I hope it'll help someone!