uniapp 低功耗蓝牙onBLECharacteristicValueChange多次传参的解决方法(曲线救国

前置问题:每当连接完蓝牙并且会启用notify监听。在这时一但断开蓝牙并且重新连接,notify功能会被二次启用,第一次启用的notify会在后台运行,无法被关闭。除非将整个app给“杀死”。在上述情况下,我们给蓝牙发送一条下行指令,notify会接收到两条相同的上行指令。如果我们的业务逻辑是每次接收到一条上行指令,然后要去做对应的业务操作。在这种情况下,我们会做出几次相同的业务操作。这就会导致一些莫名其妙的bug。

解决方法:把蓝牙封装成单独的js模块,利用单例模式来创建蓝牙类。利用isNotify参数来判断是否开启过notify功能。因为断开重连后的蓝牙不重新开启notify功能,notify功能是无法使用的。所以我们添加一个notifyCount来记录notify功能重启过几次,这样我们就可以清楚每次发送一条下行数据后,会有几条重复的上行数据被接收。

封装的ble_class.js蓝牙模块代码:

class blue_class {  
    static instance = null; // 静态属性,用于存储单例  
    // 私有构造函数,防止外部通过 new 关键字创建实例  
    constructor() {  
        // 初始化蓝牙相关的状态或变量  
        this.bluetoothStatus = null; // 蓝牙状态  
		this.isNotify=false;//用于防止重复启动notify功能
		this.notifyCount=0;	//用于判断启动了几次notify功能
    }  
    // 静态方法,用于获取蓝牙管理器的实例  
    static getInstance() {  
        if (!blue_class.instance) {  
            // 如果没有实例,则创建一个新的实例  
            blue_class.instance = new BLE_Class(); // 注意这里使用了 private constructor  
        }  
        return blue_class.instance;  
    }  
  
    // 初始化蓝牙适配器  
    // 注意:这个方法应该是公开的,但不应该在构造函数中调用  
    initBluetoothAdapter() {  
        // 这里使用uni.openBluetoothAdapter等API来初始化蓝牙适配器  
        uni.openBluetoothAdapter({  
            success: (res) => {  
                console.log('蓝牙适配器初始化成功', res);  
                this.bluetoothStatus = 'open'; // 更新蓝牙状态  
            },  
            fail: (err) => {  
                console.error('蓝牙适配器初始化失败', err);  
                this.bluetoothStatus = 'error'; // 更新蓝牙状态  
            }  
        });  
    }  
	
	// ArrayBuffer转16进度字符串示例
	ab2hex(buffer) {
		const hexArr = Array.prototype.map.call(
			new Uint8Array(buffer),
			function(bit) {
				return ('00' + bit.toString(16)).slice(-2)
			}
		)
		return hexArr.join('')
	}
	
	//监听设备发送数据
	onBLECharacteristicValueChange(){
		uni.onBLECharacteristicValueChange((sjRes) => {
			var resData=this.ab2hex(sjRes.value);
			uni.$emit('xx',resData);
		})
	}
	// 启用 notify 功能
	startNotice(uuid) {
		// 预防重复启动
		if(this.isNotify)
		{
			console.log('已经启用过 notify 功能');
		}
		else
		{
			uni.notifyBLECharacteristicValueChange({
				state: true, // 启用 notify 功能
				deviceId: uuid.deviceUUID,
				serviceId: uuid.serviceUUID,
				characteristicId: uuid.notifyUUID,
				success:(res)=> {
					// store.state.notyfiyFlagList.push(uuid);
					console.log('成功启用 notify 功能',uuid);
					this.isNotify=true;
					// 启动一次notify,就加1
					this.notifyCount=this.notifyCount+1;
					this.onBLECharacteristicValueChange();
				},
				fail:(res)=> {
					console.log('启用 notify 功能失败',res)
				}
			});
		}
	}
}  
export default blue_class;

示例蓝牙连接页面模块:

<script setup>
import blue_class from '../xxx/xxx/xx.js';
const a=blue_class .getInstance();
// 蓝牙连接请参考官方文档
function connectBle(){
	uni.createBLEConnection({
		deviceId:connectId,
		success(res) {
			// 获取蓝牙服务
			getBLEDeviceServices(connectId);
		},
		fail(err) {
			
		}
	})
}
// 初始化蓝牙服务
function openBluetoothAdapter(){
	a.initBluetoothAdapter();
}
// 启用监听
function startNotify(){
    a.startNotice(uuid);
	// 用于记录这是第几次重复监听
	let count=0;
	uni.$on('xx',function(data){
		console.log('上行数据', data.toUpperCase());
		count++;
		if(count==a.notifyCount)
		{
			// 使用最后一次监听的数据,然后清零计数器
			count=0;
			//业务逻辑....
		}
	})
}
onUnload(()=>{
    //关闭监听 
	uni.$off("xx");
})
</script>

  • 3
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值