uniapp蓝牙连接、蓝牙发送消息、蓝牙信号强弱检测

uniAPP实现安卓iOS逃不过与硬件打交道的情况,本文记录一下uniAPP蓝牙连接相关情况

1.初始化蓝牙设备 | | 提醒用户打开蓝牙设备

ini 复制代码
//设置使用变量
let discoveryStarted = false;
let deviceId = '';
let deviceName = '';
let characteristicId = ''; //uuid
let serviceId = '';
let rssiTimer = '';
let rssi = 3; //蓝牙信号强度 1级:近身大于-60,2级:近距离-70~-60, 三级:远距离低于-70
//打开蓝牙适配器
function openBluetoothAdapter(callBack) {
	uni.openBluetoothAdapter({
		success: res => {
			console.log('打开蓝牙适配器 success', res);
			startBluetoothDevicesDiscovery(callBack);
		},
		fail: res => {
			console.log('打开蓝牙适配错误', res);
			if (res.code == 10001) {
				uni.showToast({
					title: '请先打开手机蓝牙',
					icon: 'none'
				});
				uni.onBluetoothAdapterStateChange(res => {
					if (res.available){
                                        startBluetoothDevicesDiscovery(callBack);
					}
				});
			}
		}
	});
}

2.搜索周边设备(此操作比较耗费系统资源,请在搜索并连接到设备后调用 uni.stopBluetoothDevicesDiscovery 方法停止搜索。)

javascript 复制代码
//开启蓝牙搜索
function startBluetoothDevicesDiscovery(callBack) {
	uni.startBluetoothDevicesDiscovery({
		allowDuplicatesKey: true,
		success: res => {
			console.log('开启蓝牙搜索 success', res);
			onBluetoothDeviceFound(callBack);
		},
		fail: res => {
			console.log('开启蓝牙搜索 err', res);
		}
	});
}

3.监听蓝牙设备列表

ini 复制代码
function onBluetoothDeviceFound(callBack) {
	uni.onBluetoothDeviceFound(res => {
		console.log('监听蓝牙设备列表',res.devices)
		res.devices.forEach(device => {
			if (device.name.indexOf(deviceName) == -1) {
				return;
			}
			createBLEConnection(device, callBack);
		});
	});
}

4.建立连接并停止蓝牙搜索

ini 复制代码
function createBLEConnection(device, callBack) {
	deviceId = device.deviceId;
	uni.createBLEConnection({
		deviceId,
		success: res => {
			console.log('建立连接成功', res)
			//获取蓝牙设备服务
			getBLEDeviceServices(deviceId, callBack);
		}
	});
	stopBluetoothDevicesDiscovery();
}
//停止蓝牙搜索
function stopBluetoothDevicesDiscovery() {
	uni.stopBluetoothDevicesDiscovery();
	discoveryStarted = false;
}

5.获取蓝牙设备服务

ini 复制代码
function getBLEDeviceServices(deviceId, callBack) {
    //反复获取,知道获取到为止
    let timer = setInterval(() => {
	uni.getBLEDeviceServices({
            deviceId,
            success: res => {
            if (res.services.length > 0) {
                    clearInterval(timer);
                    for (let i = 0; i < res.services.length; i++) {
                        if (res.services[i].isPrimary) {
				getBLEDeviceCharacteristics(deviceId, res.services[i].uuid, callBack);
				serviceId = res.services[i].uuid;
				return;
                            }
			}
		} else {
                    getBLEDeviceServices(deviceId, callBack);
            }
            }
        });
    }, 1000)
}

6.获取蓝牙特征值

scss 复制代码
function getBLEDeviceCharacteristics(deviceId, serviceId, callBack) {
	uni.getBLEDeviceCharacteristics({
		deviceId,
		serviceId,
		success: res => {
			console.log('getBLEDeviceCharacteristics success', res.characteristics);
			for (let i = 0; i < res.characteristics.length; i++) {
				let item = res.characteristics[i];
				// console.log(item.properties)
				if (item.properties.read) {
					uni.readBLECharacteristicValue({
						deviceId,
						serviceId,
						characteristicId: item.uuid
					});
				}
				if (item.properties.write) {
					characteristicId = item.uuid;
					console.log('读写数据', deviceId, serviceId, characteristicId)
				}
				if (item.properties.notify || item.properties.indicate) {
					uni.notifyBLECharacteristicValueChange({
						deviceId,
						serviceId,
						characteristicId: item.uuid,
						state: true
					});
				}
			}
		},
		fail(res) {
			console.error('getBLEDeviceCharacteristics err', res);
		}
	});
	uni.onBLECharacteristicValueChange(characteristic => {
		//自己的操作
		let value = ab2hex(characteristic.value);
		// console.log('自己的操作', value)
		//监听设备信号强度
		listenRSSI();

		//连接成回调函数
		if (callBack) {
			callBack();
		}
	});
	uni.onBLEConnectionStateChange(res => {
		// 该方法回调中可以用于处理连接意外断开等异常情况
		console.log(`device ${res.deviceId} 设备状态改变, connected: ${res.connected}`);
		if (!res.connected) {
			openBluetoothAdapter(callBack);
		}

	});
	uni.getBluetoothDevices({
		success: res => {
			console.log('获取蓝牙设备成功:', res);
			let devices = res.devices;
		}
	})
}
// ArrayBuffer转16进度字符串示例
function ab2hex(buffer) {
	const hexArr = Array.prototype.map.call(
		new Uint8Array(buffer),
		function(bit) {
			return ('00' + bit.toString(16)).slice(-2)
		}
	)
	return hexArr.join('')
}
// ascii  转  二进制流
function asciiToArrayBuffer(str) {
	if (!str) {
		return new ArrayBuffer(0);
	}
	var buffer = new ArrayBuffer(str.length);
	// let dataView = new DataView(buffer)
	var bufView = new Uint8Array(buffer);
	for (var i = 0, strLen = str.length; i < strLen; i++) {
		bufView[i] = str.charCodeAt(i);
	}
	return buffer;
}

//超出信号强度外报警
function outcallDo() {
	let userInfo = uni.getStorageSync('userInfo');
	if (userInfo.nearremind != '1') {
		if (rssiTimer) {
			clearInterval(rssiTimer)
		}
		uni.showToast({
			icon: 'none',
			title: '超出范围已发起报警'
		})
		writeBLECharacteristicValue();
		let time = 10;
		let timercall = setInterval(() => {
			time--;
			if (time == 0 || time < 0) {
				clearInterval(timercall);
				listenRSSI();
			}
		}, 1000)
	}

}

function listenRSSI() {
	// 监听设备信号强度
	if (rssiTimer) {
		clearInterval(rssiTimer)
	}
	rssiTimer = setInterval(() => {
		uni.getBLEDeviceRSSI({
			deviceId: deviceId,
			success: (res) => {
				console.log('设备信号强度', res)
				uni.showToast({
					icon: 'none',
					title: '信号强度:' + res.RSSI
				})
				let saveRssi = uni.getStorageSync('saveRssi');
				console.log('saveRssi', saveRssi)
				saveRssi ? rssi = saveRssi : '';
				if (rssi == 1) {
					if (res.RSSI < -60) {
						//报警
						outcallDo();
					}
				} else if (rssi == 2) {
					if (res.RSSI < -70) {
						//报警
						outcallDo();
					}
				} else if (rssi == 3) {
					if (res.RSSI < -76) {
						//报警
						outcallDo();
					}
				}
			}
		})
	}, 1000)
}

7.超出信号强度外报警

scss 复制代码
function outcallDo() {
	let userInfo = uni.getStorageSync('userInfo');
	if (userInfo.nearremind != '1') {
		if (rssiTimer) {
			clearInterval(rssiTimer)
		}
		uni.showToast({
			icon: 'none',
			title: '超出范围已发起报警'
		})
		writeBLECharacteristicValue();
		let time = 10;
		let timercall = setInterval(() => {
			time--;
			if (time == 0 || time < 0) {
				clearInterval(timercall);
				listenRSSI();
			}
		}, 1000)
	}

}

function listenRSSI() {
	// 监听设备信号强度
	if (rssiTimer) {
		clearInterval(rssiTimer)
	}
	rssiTimer = setInterval(() => {
		uni.getBLEDeviceRSSI({
			deviceId: deviceId,
			success: (res) => {
				console.log('设备信号强度', res)
				uni.showToast({
					icon: 'none',
					title: '信号强度:' + res.RSSI
				})
				let saveRssi = uni.getStorageSync('saveRssi');
				console.log('saveRssi', saveRssi)
				saveRssi ? rssi = saveRssi : '';
				if (rssi == 1) {
					if (res.RSSI < -60) {
						//报警
						outcallDo();
					}
				} else if (rssi == 2) {
					if (res.RSSI < -70) {
						//报警
						outcallDo();
					}
				} else if (rssi == 3) {
					if (res.RSSI < -76) {
						//报警
						outcallDo();
					}
				}
			}
		})
	}, 1000)
}

8.暴露公共方法

javascript 复制代码
//发送指令 蓝牙呼叫
export function writeBLECharacteristicValue(callBack) {
	console.log('deviceId:' + deviceId)
	console.log('serviceId:' + serviceId)
	console.log('characteristicId:' + characteristicId)
	// 向蓝牙设备发送一个0x00的16进制数据
	const buffer = asciiToArrayBuffer(JSON.stringify({
		'fn': '3'
	}));
	uni.writeBLECharacteristicValue({
		deviceId: deviceId, // 这里的 deviceId 需要在 getBluetoothDevices 或 onBluetoothDeviceFound 接口中获取
		serviceId: serviceId, // 这里的 serviceId 需要在 getBLEDeviceServices 接口中获取
		characteristicId: characteristicId, // 这里的 characteristicId 需要在 getBLEDeviceCharacteristics 接口中获取
		value: buffer, // 这里的value是ArrayBuffer类型
		success(res) {
			uni.showToast({
				icon: 'none',
				title: '已发起呼叫'
			});
			if (callBack) {
				callBack(0);
			}

		},
		fail(res) {
			console.log('writeBLECharacteristicValue fail', res);
			//连接成回调函数
			if (callBack) {
				callBack(1);
			}
		}
	});
}

/* 
	@eptName 设备名称
	@callBack() 回调函数
 */
export function blueToothLink(eptName, callBack) {
	deviceName = eptName;
	openBluetoothAdapter(callBack);
}
相关推荐
世俗ˊ14 分钟前
CSS入门笔记
前端·css·笔记
子非鱼92114 分钟前
【前端】ES6:Set与Map
前端·javascript·es6
6230_19 分钟前
git使用“保姆级”教程1——简介及配置项设置
前端·git·学习·html·web3·学习方法·改行学it
想退休的搬砖人28 分钟前
vue选项式写法项目案例(购物车)
前端·javascript·vue.js
加勒比海涛42 分钟前
HTML 揭秘:HTML 编码快速入门
前端·html
啥子花道44 分钟前
Vue3.4 中 v-model 双向数据绑定新玩法详解
前端·javascript·vue.js
麒麟而非淇淋1 小时前
AJAX 入门 day3
前端·javascript·ajax
茶茶只知道学习1 小时前
通过鼠标移动来调整两个盒子的宽度(响应式)
前端·javascript·css
清汤饺子1 小时前
实践指南之网页转PDF
前端·javascript·react.js
蒟蒻的贤1 小时前
Web APIs 第二天
开发语言·前端·javascript