uniapp连接蓝牙硬件及硬件数据传输(公用类封装,简单易用)

文章定义了蓝牙连接的各种状态,如等待连接、搜索设备、已连接等,并封装了蓝牙控制器监听函数,包括连接状态监听和数据传输监听。此外,还提供了蓝牙扫描、连接、断开的函数实现,以及异常处理。代码适用于uniapp平台,便于在小程序中进行蓝牙设备的操作和管理。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

图片来自网络

1、定义相关业务状态

蓝牙连接设备前,首先会想到一些各种的状态,比如等待连接、搜索设备中、已连接、连接失败等等一系列的状态监听,所以这里先定义好相关状态,以便业务逻辑判断。

export const BLUE_STATE = {
	/**
	 * 蓝牙不可用
	 */
	UNAVAILABLE: {
		label: '请检查手机蓝牙是否开启',
		code: -1
	},
	/**
	 * 等待连接蓝牙
	 */
	READY: {
		label: '等待连接蓝牙',
		code: 10000
	},
	/**
	 * 等待连接蓝牙(重启蓝牙适配器)
	 */
	READYAGAIN: {
		label: '等待连接蓝牙',
		code: 10001
	},
	/**
	 * 正在搜索设备...
	 */
	SCANING: {
		label: '正在搜索设备...',
		code: 12000
	},
	/**
	 * 正在传输数据...
	 */
	TRANSMITDATA: {
		label: '正在传输数据...',
		code: 13000
	},
	/**
	 * 数据传输完成
	 */
	LOCKDATA: {
		label: '数据已锁定',
		code: 11000
	},
	/**
	 * 已连接蓝牙
	 */
	CONNECTSUCCESS: {
		label: '已连接蓝牙',
		code: 200
	},
	/**
	 * 写入特征已准备就绪
	 */
	WRITEREADY: {
		label: '写入特征已准备就绪',
		code: 201
	},
	/**
	 * 蓝牙连接已断开
	 */
	DISCONNECT: {
		label: '蓝牙连接已断开',
		code: 500
	},
	/**
	 * 连接失败, 请重试!
	 */
	CONNECTFAILED: {
		label: '连接失败, 请重试!',
		code: -2
	},
	/**
	 * 微信无位置权限
	 */
	NOLOCATIONPERMISSION: {
		label: '您关闭了微信位置权限,请前往手机设置页打开权限后重试',
		code: 10007
	},
	/**
	 * 当前系统版本过低,请升级后重试!
	 */
	VERSIONLOW: {
		label: '当前系统版本过低,请升级后重试!',
		code: 10009
	},
	/**
	 * 系统异常,请稍后重试!
	 */
	SYSTEMERROR: {
		label: '系统异常,请稍后重试!',
		code: 10008
	}
}

2、封装蓝牙控制器监听函数

可自行拓展监听器

export const BleController = {
	/**
	 * 蓝牙连接状态
	 */
	addConnectStateListen(callBack) {
		this.public.bleConnectStateCallBack = callBack
	},
	/**
	 * 传输数据监听
	 */
	addTransferDataListen(callBack) {
		this.public.bleProgressDataCallBack = callBack
	},
	// 连接状态
	connectStateListen(params) {
		if (this.public.bleConnectStateCallBack) {
			this.public.bleConnectStateCallBack(params)
		}
	},
	// 数据传输中
	transferDataListen(params) {
		if (this.public.bleTransferDataCallBack) {
			this.public.bleTransferDataCallBack(params)
		}
	},

	public: {
		bleConnectStateCallBack: null,
		bleTransferDataCallBack: null,
	}
}

图片来自网络

3、封装蓝牙扫描&连接函数

整个流程比较长,具体API使用可查看uniapp官方文档

let bleControl = null
let bleConnectDeviceID = null
let currentDevice = {}
let writeData = {
	device: {}, 
	serviceID: '',
	characteristicID: ''
}
export const Blue = {
	/**
	 * 蓝牙连接状态:200-> 已连接;-1 ->未连接
	 */
	connectState: -1,
	
	// 开始蓝牙设备扫描
	start() {
		bleControl = BleProtocol
		this._lastLockData = ""
		if(bleConnectDeviceID) { // 设备已连接
			this.connectState = 200
			bleControl.connectStateListen(BLUE_STATE.CONNECTSUCCESS);
			return
		};
		bleControl.connectStateListen(BLUE_STATE.READY)
		// 打开蓝牙适配器
		uni.openBluetoothAdapter({
			success: (res) => {
				this.startBluetoothDevicesDiscovery()
			},
			fail: (res) => {
				console.error('打开蓝牙适配器失败:', res);
				if (res.errCode === 10001) {
					bleControl.connectStateListen(BLUE_STATE.UNAVAILABLE)
				}
				// Android 系统特有,系统版本低于 4.3 不支持 BLE
				if(res.errCode === 10009) {
					bleControl.connectStateListen(BLUE_STATE.VERSIONLOW)
				}
				if(res.errCode === 10008) {
					bleControl.connectStateListen(BLUE_STATE.SYSTEMERROR)
				}
			},
			complete: () => {
				// 监听蓝牙适配器状态
				uni.onBluetoothAdapterStateChange(res => {
					console.log('蓝牙适配器状态:', res);
					if (res.available) {
						this._isDiscovering = res.discovering
						bleControl.connectStateListen(BLUE_STATE.READYAGAIN)
						this.startBluetoothDevicesDiscovery()
					}else {
						// 蓝牙模块未开启
						bleControl.connectStateListen(BLUE_STATE.UNAVAILABLE)
					}
				})
			}
		})
	},

	// 关闭蓝牙连接,关闭状态监听,初始化状态
	stop() {
		if (bleConnectDeviceID) {
			uni.closeBLEConnection({
				deviceId: bleConnectDeviceID
			})
		}
		writeData = {}
		bleConnectDeviceID = null
		this.connectState = -1
		this._isDiscovering = false
		uni.closeBluetoothAdapter()
		uni.offBluetoothAdapterStateChange()
		uni.offBLEConnectionStateChange()
		uni.stopBluetoothDevicesDiscovery()
	},
	// 停止蓝牙扫描
	stopBluetoothDevicesDiscovery() {
		uni.stopBluetoothDevicesDiscovery()
	},
	// 开始蓝牙扫描
	startBluetoothDevicesDiscovery() {
		if (this._isDiscovering) return
		this._isDiscovering = true
		
		uni.startBluetoothDevicesDiscovery({
			allowDuplicatesKey: true,
			success: (res) => {
				bleControl.connectStateListen(BLUE_STATE.SCANING)
				this.onBluetoothDeviceFound()
			},
			fail: (res) => {
				if(res.errCode === -1 && (res.errno === 1509008 || res.errno === 1509009)) {
					this.stop()
					bleControl.connectStateListen(BLUE_STATE.NOLOCATIONPERMISSION)
				}
			}
		})
	},
	// 搜索附近设备
	onBluetoothDeviceFound() {
		uni.onBluetoothDeviceFound(res => {
			res.devices.forEach(device => {
				let abHex = this.ab2hex(device.advertisData)
				
				// 自动连接设备,根据自己的设备修改
				if (abHex.length === 10) {
					this.stopBluetoothDevicesDiscovery()
					this.createBLEConnection(device)
				}
			})
		})
	},
	// 创建蓝牙连接
	createBLEConnection(device) {
		if (bleConnectDeviceID == null) {
			bleConnectDeviceID = device.deviceId
			uni.createBLEConnection({
				deviceId: device.deviceId,
				success: res=> {
					currentDevice = device
					this.connectState = 200
					// 蓝牙连接成功,上报设备信息
					bleControl.connectStateListen({
						...BLUE_STATE.CONNECTSUCCESS,
						deviceInfo: {...device}
					})
					this.getBLEDeviceServices(device)
					this.onBLEConnectionStateChange()
				},
				fail: (err)=> {
					bleControl.connectStateListen(BLUE_STATE.CONNECTFAILED)
				},
			})
		}
	},
	// 监听连接状态
	onBLEConnectionStateChange() {
		uni.onBLEConnectionStateChange(res => {
			console.log('蓝牙连接状态: ', res);
			if (!res.connected) {
				bleControl.connectStateListen(BLUE_STATE.DISCONNECT)
				this.stop()
			}
		});
	},
	// 获取设备服务
	getBLEDeviceServices(device) {
		uni.getBLEDeviceServices({
			deviceId: device.deviceId,
			success: res=> {
				for (let i = 0; i < res.services.length; i++) {
					let uuid = res.services[i].uuid
					if (uuid.indexOf("FFF0") == 0) {
						this.getBLEDeviceCharacteristics(device, uuid)
					}
				}
			},
		})
	},
	// 获取设备特征值
	getBLEDeviceCharacteristics(device, serviceID) {
		uni.getBLEDeviceCharacteristics({
			deviceId: device.deviceId,
			serviceId: serviceID,
			success: res=> {
				for (let i = 0; i < res.characteristics.length; i++) {
					let item = res.characteristics[i]
					// 该特征值是否支持 write 操作
					if (item.properties.write) { 
						if (item.uuid.indexOf("FFF1") == 0) {
							writeData = {
								device: device, 
								serviceID: serviceID,
								characteristicID: item.uuid
							}
							bleControl.connectStateListen(BLUE_STATE.WRITEREADY);
						}
					}
					// 该特征值是否支持 notify或indicate 操作
					if (item.properties.notify || item.properties.indicate) { 
						if (item.uuid.indexOf("FFF4") == 0) {
							this.notifyBLECharacteristicValueChange(device, serviceID, item.uuid);
						}
					}
				}
			}
		})
	},
	// 监听特征值变化(设备数据变化)
	notifyBLECharacteristicValueChange(device, serviceID, characteristicID) {
		uni.notifyBLECharacteristicValueChange({
			deviceId: device.deviceId,
			serviceId: serviceID,
			characteristicId: characteristicID,
			state: true,
			success: res=> {
				this.onBLECharacteristicValueChange()
			},
		})
	},


	onBLECharacteristicValueChange() {
		uni.onBLECharacteristicValueChange(res=> {
			let value = this.ab2hex(res.value)
			this.resolvingData(value)
		})
	},

	// ArrayBuffer转16进制字符串
	ab2hex(buffer, split='') {
		var hexArr = Array.prototype.map.call(new Uint8Array(buffer), function(bit) {
			return ('00' + bit.toString(16)).slice(-2)
		})
		return hexArr.join(split)
	},
	
	// TODO 根据自己实际业务解析数据
	resolvingData(res) {
		if (this._lastLockData == res) return
		this._lastLockData = res
	},
}

4、业务组件使用蓝牙

Blue.start();

BleController.addConnectStateListen(state => {
	console.log('蓝牙连接状态', state.code);
});

BleController.addTransferDataListen(info => {
	console.log('数据传输中', info);
});

小程序蓝牙设备扫描,蓝牙连接【uniapp模板】

如果觉得有用随手点个赞吧,谢谢
关注我,不定时分享技术干货~

uniapp中,可以通过以下步骤来实现蓝牙传输数据: 1. 初始化蓝牙模块:使用uni.openBluetoothAdapter API来初始化蓝牙模块。这个API必须在其他蓝牙相关API之前调用,否则会返回错误。\[2\] 2. 搜索蓝牙设备:使用uni.startBluetoothDevicesDiscovery API来搜索附近的蓝牙设备。 3. 获取设备列表:使用uni.getBluetoothDevices API来获取搜索到的蓝牙设备列表。 4. 连接设备:使用uni.createBLEConnection API来连接指定的蓝牙设备。 5. 获取设备服务列表:使用uni.getBLEDeviceServices API来获取已连接设备的服务列表。 6. 获取蓝牙特征:使用uni.getBLEDeviceCharacteristics API来获取指定服务的特征列表。 7. 接收设备数据:使用uni.onBLECharacteristicValueChange API来监听蓝牙设备发送的数据。 8. 向设备发送数据:使用uni.writeBLECharacteristicValue API来向蓝牙设备发送数据。\[3\] 通过以上步骤,你可以在uniapp中实现蓝牙设备的连接、数据接收和数据发送功能。 #### 引用[.reference_title] - *1* [uniapp 调用蓝牙接收数据、发送指令后接收返回结果](https://blog.csdn.net/weixin_45581505/article/details/123565761)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^insertT0,239^v3^insert_chatgpt"}} ] [.reference_item] - *2* *3* [『uni-app、小程序』蓝牙连接、读写数据全过程](https://blog.csdn.net/weixin_39415598/article/details/124553790)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^insertT0,239^v3^insert_chatgpt"}} ] [.reference_item] [ .reference_list ]
评论 11
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

z.week

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值