Ionic 3 BLE模块问题:移除停止广播设备以更新设备列表
解决Ionic 3 BLE设备停止广播后未从deviceList移除的问题
嘿,这个问题我之前也碰到过!BLE扫描本身只会返回正在广播的设备,不会主动通知你哪个设备停止广播了,所以得咱们自己加个超时检测逻辑来处理,给你一步步说怎么改:
1. 追踪设备的最后活跃时间
首先,我们需要给每个设备记录最后一次被扫描到的时间,这样才能判断它是不是已经停播了。可以用一个Map来存每个设备ID对应的最后活跃时间,同时在扫描到设备时更新这个记录,还要避免重复添加设备到deviceList里:
deviceList = []; // 用设备ID作为key,存储最后一次被扫描到的时间戳 deviceLastSeen = new Map<string, number>(); // 定时器实例,后面用来清理 scanCheckInterval: any; scanForDevices(){ console.log("scan for devices"); this.ble.startScan([]).subscribe(device => { this.zone.run(() => { // 先检查设备是否已经在列表里 const existingIndex = this.deviceList.findIndex(d => d.id === device.id); if (existingIndex !== -1) { // 如果存在就更新设备信息(比如信号强度可能变化) this.deviceList[existingIndex] = device; } else { // 不存在就添加新设备 this.deviceList.push(device); } // 更新该设备的最后活跃时间 this.deviceLastSeen.set(device.id, Date.now()); }); this.connect(device); }); // 定时检查超时设备 this.scanCheckInterval = setInterval(() => { this.zone.run(() => { // 设置超时阈值,比如5秒(可根据你的设备广播间隔调整) const timeoutMs = 5000; const currentTime = Date.now(); // 找出所有超过阈值没出现的设备ID const timedOutIds = Array.from(this.deviceLastSeen.entries()) .filter(([id, lastTime]) => currentTime - lastTime > timeoutMs) .map(([id]) => id); // 从deviceList中移除超时设备 this.deviceList = this.deviceList.filter(d => !timedOutIds.includes(d.id)); // 同时清理lastSeen记录 timedOutIds.forEach(id => this.deviceLastSeen.delete(id)); }); }, 1000); // 每秒检查一次,频率可调整 }
2. 清理定时器避免内存泄漏
别忘了在页面离开或者停止扫描的时候,把定时器和扫描都关掉,不然会一直占用资源:
// 比如在页面离开的钩子中清理 ionViewWillLeave() { // 停止BLE扫描 this.ble.stopScan().catch(err => console.log(err)); // 清除检查定时器 if (this.scanCheckInterval) { clearInterval(this.scanCheckInterval); this.scanCheckInterval = null; } // 也可以清空设备列表(可选) this.deviceList = []; this.deviceLastSeen.clear(); }
3. 注意事项
- 超时阈值调整:根据你的设备实际广播间隔来设置
timeoutMs,比如如果设备每2秒广播一次,设5秒就比较稳妥,避免误判设备离线。 - 重复设备过滤:原来的代码每次扫描到都
push,会导致列表里有大量重复设备,现在的逻辑会先检查是否已存在,更新或添加,更合理。
这样改完之后,当设备长按关机停止广播,超过设定的超时时间后,就会自动从deviceList里移除啦~
内容的提问来源于stack exchange,提问作者Jamie Barker
相关产品推荐
相关产品推荐

