You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.25 07:43:55