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);
}
相关推荐
桂月二二4 小时前
探索前端开发中的 Web Vitals —— 提升用户体验的关键技术
前端·ux
hunter2062065 小时前
ubuntu向一个pc主机通过web发送数据,pc端通过工具直接查看收到的数据
linux·前端·ubuntu
qzhqbb5 小时前
web服务器 网站部署的架构
服务器·前端·架构
刻刻帝的海角5 小时前
CSS 颜色
前端·css
浪浪山小白兔7 小时前
HTML5 新表单属性详解
前端·html·html5
lee5767 小时前
npm run dev 时直接打开Chrome浏览器
前端·chrome·npm
2401_897579657 小时前
AI赋能Flutter开发:ScriptEcho助你高效构建跨端应用
前端·人工智能·flutter
limit for me7 小时前
react上增加错误边界 当存在错误时 不会显示白屏
前端·react.js·前端框架
浏览器爱好者7 小时前
如何构建一个简单的React应用?
前端·react.js·前端框架
qq_392794488 小时前
前端缓存策略:强缓存与协商缓存深度剖析
前端·缓存