uniapp은 Bluetooth 하드웨어와 하드웨어 데이터 전송을 연결합니다(공용 클래스 캡슐화, 사용하기 쉬움).

사진은 인터넷에서 퍼왔습니다

1. 해당 사업현황 정의

Bluetooth가 장치에 연결되기 전에 먼저 연결 대기, 장치 검색, 연결됨, 연결 실패 등과 같은 다양한 상태를 생각하게 됩니다. 일련의 상태 모니터링이 있으므로 여기서 먼저 비즈니스 논리 판단을 위한 관련 상태를 정의합니다. .

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
	},
	/**
	 * 数据传输完成监听
	 */
	addLockDataListen(callBack) {
    
    
		this.public.bleLockDataCallBack = callBack
	},
	/**
	 * 写入特征值状态
	 */
	addWriteStateListen(callBack) {
    
    
		this.public.bleWriteStateCallBack = callBack
	},
	// 连接状态
	connectStateListen(params) {
    
    
		if (this.public.bleConnectStateCallBack) {
    
    
			this.public.bleConnectStateCallBack(params)
		}
	},
	// 数据传输中
	transferDataListen(params) {
    
    
		if (this.public.bleTransferDataCallBack) {
    
    
			this.public.bleTransferDataCallBack(params)
		}
	},
	// 测量完成
	lockDataListen(params) {
    
    
		if (this.public.bleLockDataCallBack) {
    
    
			this.public.bleLockDataCallBack(params)
		}
	},
	// 写入特征值状态
	writeStateListen(params) {
    
    
		if (this.public.bleWriteStateCallBack) {
    
    
			this.public.bleWriteStateCallBack(params)
		}
	},

	public: {
    
    
		bleConnectStateCallBack: null,
		bleTransferDataCallBack: null,
		bleLockDataCallBack: null,
		bleWriteStateCallBack: 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) => {
    
    
				console.log('位置失败--', 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 => {
    
    
				// device = {
    
    
				// 	RSSI: -50,
				// 	advertisData: ArrayBuffer(19),
				// 	advertisServiceUUIDs: Array(2),
				// 	connectable: true,
				// 	deviceId: "EE59532DF324-4SFSD-34635D-BB893-76SGSDFV",
				// 	localName: "shebeimingcheng",
				// 	name: "shebeimingcheng", 
				// }
				if (device.name !== 'shebeimingcheng') return
				
				let abHex = this.ab2hex(device.advertisData)
				let mac = this.ab2hex(device.advertisData.slice(2, 8), ':').toUpperCase()
				device.macAddr = mac
				// 根据自己的设备修改
				if (abHex.length == 38) {
    
    
					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)
		})
	},
	
	// 发送指令给设备
	sendOrder(byteArray) {
    
    
		let checksum = 0x00
		// byteArray = [FD, 03, 00, 01, 00]
		// 计算异或和
		for(let i = 0; i < byteArray.length - 1; i++) {
    
    
			checksum ^= `0x${
      
      byteArray[i]}`
		}
		this.deviceMode = mode
		let sumStr = checksum.toString(16).toLocaleUpperCase()
		let hex = byteArray.join('') + sumStr // FD03000100C4
		
		let typedArray = new Uint8Array(hex.match(/[\da-f]{2}/gi).map(function(h) {
    
    
			return parseInt(h, 16)
		}))
		
		let order = typedArray.buffer
		
		if(!writeData.device.deviceId){
    
    
			this.stop()
			return
		}
		
		this.writeBLECharacteristicValue(order, writeData.device, writeData.serviceID, writeData.characteristicID)
	},
	// 写入特征值
	writeBLECharacteristicValue(order, device, serviceID, characteristicID) {
    
    
		uni.writeBLECharacteristicValue({
    
    
			deviceId: device.deviceId,
			serviceId: serviceID,
			characteristicId: characteristicID,
			value: order,
			success: (res)=> {
    
    
				console.log("特征值写入成功 --", res)
				bleControl.writeStateListen({
    
    
					code: res.errCode === 0 ? 200 : -1,
				})
			},
			fail: (res)=> {
    
    
				console.log("特征值写入失败 --", res)
				bleControl.writeStateListen({
    
    
					code: -1,
				})
			}
		})
	},

	// 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
		
		const valArr = []
		if (res.length >= 20) {
    
    
			for (let i = 0, len = 10; i < len; i++) {
    
    
				valArr[i] = res.substr(i * 2, 2)
			}
			// console.log(valArr);
		}
	},
}

4. 비즈니스 구성 요소는 Bluetooth를 사용합니다.

Blue.start();

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

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

BleController.addWriteStateListen(res => {
    
    
	console.log('特征值写入状态', res);
})

유용하다고 생각되시면 좋아요, 저를 팔로우 해주셔서 감사합니다
. 가끔 테크니컬 드라이 제품을 공유해 주세요~

Je suppose que tu aimes

Origine blog.csdn.net/weixin_45295253/article/details/128982215
conseillé
Classement