class Bluetooth { constructor(options = {}) { this.isOpenBle = false; this.deviceId = ""; this.serviceId = ""; this.writeId = ""; this.notifyId = ""; this.num = 0; this.serviceList = []; if (options.autoOpen !== false) { this.openBluetoothAdapter({ silent: true }).catch(() => {}); } } showToast(title) { uni.showToast({ title: title, icon: 'none', 'duration': 2000 }); } openBluetoothAdapter(options = {}) { const silent = options.silent === true; return new Promise((resolve, reject) => { uni.openBluetoothAdapter({ success: res => { this.isOpenBle = true; // this.showToast("初始化蓝牙模块成功"); resolve(res); }, fail: err => { if (!silent) { this.showToast('蓝牙状态读取失败,请检查是否打开蓝牙'); } reject(err); }, }); }); } startBluetoothDevicesDiscovery() { if (!this.isOpenBle) { this.showToast(`初始化蓝牙模块失败`) return; } let self = this; uni.showLoading({ title: '蓝牙搜索中' }) return new Promise((resolve, reject) => { setTimeout(() => { uni.startBluetoothDevicesDiscovery({ success: res => { resolve(res) }, fail: err => { self.showToast(`搜索设备失败` + JSON.stringify(err)); reject(err); } }) }, 300); }); } stopBluetoothDevicesDiscovery() { let self = this; return new Promise((resolve, reject) => { uni.stopBluetoothDevicesDiscovery({ success: e => { uni.hideLoading(); }, fail: err => { uni.hideLoading(); self.showToast(`停止搜索蓝牙设备失败` + JSON.stringify(err)); } }) }); } saveDevice(deviceId, deviceName = '') { if (!deviceId) return; uni.setStorageSync('bluetoothDeviceId', deviceId); if (deviceName) { uni.setStorageSync('bluetoothDeviceName', deviceName); } } removeSavedDevice() { uni.removeStorageSync('bluetoothDeviceId'); uni.removeStorageSync('bluetoothDeviceName'); uni.removeStorageSync('serviceId'); uni.removeStorageSync('notifyId'); uni.removeStorageSync('writeId'); } resetConnectionInfo() { this.serviceId = ""; this.writeId = ""; this.notifyId = ""; this.num = 0; this.serviceList = []; } async connectDevice(deviceId, options = {}) { if (!deviceId) { return Promise.reject('设备ID不能为空'); } await this.openBluetoothAdapter(options); this.deviceId = deviceId; this.resetConnectionInfo(); await this.createBLEConnection(deviceId, options); this.serviceList = await this.getBLEDeviceServices(options); await this.getBLEDeviceCharacteristics(options); this.saveDevice(deviceId, options.deviceName); return { deviceId: this.deviceId, serviceId: this.serviceId, notifyId: this.notifyId, writeId: this.writeId }; } connectSavedDevice(options = {}) { const deviceId = uni.getStorageSync('bluetoothDeviceId'); if (!deviceId) { return Promise.resolve(null); } return this.connectDevice(deviceId, { ...options, deviceName: options.deviceName || uni.getStorageSync('bluetoothDeviceName') }); } createBLEConnection(deviceId, options = {}) { //设备deviceId let self = this; const silent = options.silent === true; if (!silent) { uni.showLoading({ mask: true, title: '设备连接中,请稍候...' }) } return new Promise((resolve, reject) => { uni.createBLEConnection({ deviceId, timeout: 5000, success: (res) => { resolve(res) }, fail: err => { if (err.errMsg == "createBLEConnection:fail already connect") { resolve(err) return true; } if (err.errCode == 10012) { if (!silent) { self.showToast(`蓝牙连接超时`); } } else if (!silent) { self.showToast(`蓝牙连接失败` + JSON.stringify(err)); } reject(err); }, complete() { if (!silent) { uni.hideLoading(); } } }) }); } //获取蓝牙设备所有服务(service) getBLEDeviceServices(options = {}) { let _serviceList = []; let deviceId = this.deviceId; let self = this; const silent = options.silent === true; return new Promise((resolve, reject) => { setTimeout(() => { uni.getBLEDeviceServices({ deviceId, success: res => { for (let service of res.services) { if (service.isPrimary) { _serviceList.push(service); } } if (!silent) { uni.hideLoading(); } resolve(_serviceList) }, fail: err => { if (!silent) { uni.hideLoading(); self.showToast(`获取设备Services` + JSON.stringify(err)); } reject(err); }, }) }, 500); }); } //获取蓝牙设备某个服务中所有特征值(characteristic) getBLEDeviceCharacteristics(options = {}) { let self = this; let deviceId = self.deviceId; let service = self.serviceList; const silent = options.silent === true; if (!service || !service[self.num]) { return Promise.reject('找不到该读写的服务'); } var uuid = service[self.num].uuid; return new Promise((resolve, reject) => { uni.getBLEDeviceCharacteristics({ deviceId: deviceId, serviceId: uuid, success: res => { for (let _obj of res.characteristics) { //获取notify if (_obj.properties.notify) { self.notifyId = _obj.uuid; uni.setStorageSync('notifyId', self.notifyId); } //获取writeId if (_obj.properties.write) { self.writeId = _obj.uuid; uni.setStorageSync('writeId', self.writeId); } } if (!self.writeId || !self.notifyId) { self.num++ if (self.num == service.length) { reject('找不到该读写的特征值'); return false; } else { self.getBLEDeviceCharacteristics(options).then(resolve).catch(reject); return; } } else { self.serviceId = uuid; uni.setStorageSync('serviceId', self.serviceId); } let result = { 'notifyId': self.notifyId, 'writeId': self.writeId }; // self.showToast(`获取服务中所有特征值OK,${JSON.stringify(result)}`); resolve(result) }, fail: err => { if (!silent) { self.showToast(`getBLEDeviceCharacteristics` + JSON.stringify(err)); } reject(err); } }) }); } //断开联链接 closeBLEConnection(deviceId = this.deviceId) { if (!deviceId) return; uni.closeBLEConnection({ deviceId, success(res) { } }) } notifyBLECharacteristicValue() { let deviceId = this.deviceId; let serviceId = this.serviceId; let characteristicId = this.notifyId; uni.notifyBLECharacteristicValueChange({ state: true, // 启用 notify 功能 deviceId, serviceId, characteristicId, success(res) { uni.onBLECharacteristicValueChange(function(res) { }); } }); } writeBLECharacteristicValue(buffer) { let deviceId = this.deviceId; let serviceId = this.serviceId; let characteristicId = this.writeId; return new Promise((resolve, reject) => { uni.writeBLECharacteristicValue({ deviceId, serviceId, characteristicId, value: buffer, success(res) { resolve(res); }, fail(err) { reject(err); } }); }); } closeBluetoothAdapter() { uni.closeBluetoothAdapter({ success: res => { } }); } //若APP在之前已有搜索过某个蓝牙设备,并成功建立连接,可直接传入之前搜索获取的 deviceId 直接尝试连接该设备,无需进行搜索操作。 reconnect() { return this.connectSavedDevice(); } } export default Bluetooth;