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);
}
相关推荐
红辣椒...2 分钟前
codex+第三方模型
java·服务器·前端
木子雨廷3 分钟前
Flutter 使用 flutter_flavorizr 多渠道打包
前端·flutter
环境工程笔记6 分钟前
浏览器自动化跑成功了,为什么结果还是不对?
前端
东风破_8 分钟前
一文搞懂 JavaScript 变量声明:var、let、const 到底有什么区别?
前端·javascript
问心无愧051311 分钟前
ctf show web入门261
android·前端·笔记
触底反弹13 分钟前
你真的理解 JavaScript 变量提升(Hoisting)吗?从 V8 引擎编译原理深入剖析
前端·面试
蜡台25 分钟前
Vue2 使用 typescript 教程
前端·vue.js·typescript
光影少年38 分钟前
Redux Toolkit 用法、解决原生Redux 冗余问题
开发语言·前端·javascript·react.js·中间件·前端框架·ecmascript
云水一下1 小时前
JavaScript 从零基础到精通系列:DOM 操作与事件驱动编程
前端·javascript