dasensen
dasensen
  • 发布:2026-08-21 17:04
  • 更新:2026-08-21 17:05
  • 阅读:12

uni.onBLECharacteristicValueChange 蓝牙监听设备消息如何关闭

分类:uni-app

在测试过程中,已经进入销毁页面生命周期 但是监听器没办法关闭 下次进来的时候 监听器还是处于打开状态,发出的消息会接受到两次

2026-08-21 17:04 负责人:无 分享
已邀请:
Ask小助手

Ask小助手 - Ask社区AI助手

欢迎到专业群( uni-app 官方技术交流群 1 ) 咨询,群中有相关专业的管理员和群友。

这是 uni-app 蓝牙 API 的一个已知限制:uni.onBLECharacteristicValueChange 目前没有对应的 off 方法(调用 uni.offBLECharacteristicValueChange 会提示 is not a function),所以无法像 uni.$off 那样在页面销毁时移除监听。你遇到的"收到两次消息",本质原因是每次进入页面都重复调用了一次 uni.onBLECharacteristicValueChange,导致回调被叠加注册了多次,页面销毁并不会自动移除它。

可以通过以下方式规避:

方案一:保证整个应用只注册一次监听(推荐)

把监听注册逻辑抽出来,用模块级变量做防重复保护,不要在每次连接流程中重复调用:

// ble-listener.js  
let hasRegistered = false  
let pageActive = false  
let dataHandler = null  

export function registerBleListener(handler) {  
  dataHandler = handler  
  if (hasRegistered) return  
  hasRegistered = true  
  uni.onBLECharacteristicValueChange((res) => {  
    if (!pageActive) return // 页面已离开,不处理数据  
    dataHandler && dataHandler(res)  
  })  
}  

export function setBlePageActive(active) {  
  pageActive = active  
}

本助手使用国产模型,生成代码可能不准确。专业的代码生成需要全球顶尖的AI Coding模型。推荐使用uni-agent

页面中使用:

import { registerBleListener, setBlePageActive } from '@/common/ble-listener.js'  

export default {  
  onLoad() {  
    setBlePageActive(true)  
    registerBleListener((res) => {  
      // 处理特征值数据  
      console.log(res.value)  
    })  
  },  
  onUnload() {  
    setBlePageActive(false)  
  }  
}

本助手使用国产模型,生成代码可能不准确。专业的代码生成需要全球顶尖的AI Coding模型。推荐使用uni-agent

方案二:页面销毁时关闭 notify 和连接

onUnload 中关闭特征值通知、断开连接,从源头停止数据推送:

onUnload() {  
  uni.notifyBLECharacteristicValueChange({  
    deviceId: this.deviceId,  
    serviceId: this.serviceId,  
    characteristicId: this.characteristicId,  
    state: false // 关闭 notify  
  })  
  uni.closeBLEConnection({ deviceId: this.deviceId })  
}

本助手使用国产模型,生成代码可能不准确。专业的代码生成需要全球顶尖的AI Coding模型。推荐使用uni-agent

注意事项

  • uni.onBLECharacteristicValueChange 只需调用一次即可持续生效,之后多次调用 uni.notifyBLECharacteristicValueChange 开启 notify 是没关系的,不要误以为每次 notify 前都要重新 on 一次。
  • 如果业务允许,页面销毁时也可以调用 uni.closeBluetoothAdapter 彻底关闭蓝牙模块释放资源。

相关参考:

内容为 AI 生成,仅供参考

要回复问题请先登录注册