export default { featrueValueCallback: null, //蓝牙特征变化回调 BleChangeCallback: null, //蓝牙状态变化回调 //引导用户打开蓝牙 showBluetoothGuide: function(showTip) { let platform = process.env.UNI_PLATFORM; var openBlueSetting = function() { // 判断平台类型 if (platform === 'mp-weixin') { uni.openSetting(); } else if (platform === 'app-plus' || platform === 'app') { //---------------------------------------------------------------- const osName = plus.os.name; if (osName === 'iOS') { // iOS 平台打开蓝牙设置 plus.runtime.openURL('App-Prefs:root=Bluetooth', function() { console.log('成功打开蓝牙设置'); }, function(err) { console.error('打开蓝牙设置失败:' + err.message); uni.showModal({ title: '提示', content: '无法自动打开蓝牙设置,请手动前往设置 > 蓝牙 进行操作。', showCancel: false }); }); } else if (osName === 'Android') { // Android 平台打开蓝牙设置 try { const Intent = plus.android.importClass('android.content.Intent'); const Settings = plus.android.importClass('android.provider.Settings'); const main = plus.android.runtimeMainActivity(); const intent = new Intent(Settings.ACTION_BLUETOOTH_SETTINGS); main.startActivity(intent); } catch (e) { console.error('打开蓝牙设置失败:' + e.message); // 尝试使用通用设置页面作为备选方案 plus.runtime.openURL('settings://', function() { console.log('打开系统设置成功,请手动找到蓝牙选项'); }, function() { uni.showModal({ title: '提示', content: '无法自动打开蓝牙设置,请手动前往设置页面开启蓝牙。', showCancel: false }); }); } } else { uni.showModal({ title: '提示', content: '当前系统不支持自动打开蓝牙设置,请手动操作。', showCancel: false }); } //-------------------------------------------------------------------- } else if (platform === 'mp-alipay') { uni.openSetting(); } } if (showTip !== undefined) { openBlueSetting(); return; } if (platform === 'mp-weixin' || platform === 'app-plus' || platform === 'mp-alipay' || platform === 'app') { uni.showModal({ title: '蓝牙未开启', content: '请在系统设置中打开蓝牙以使用此功能', success: (res) => { if (res.confirm) { openBlueSetting(); } } }); } else { console.log("当前平台不支持打开系统设置" + platform); } }, //获取蓝牙适配器状态 CheckBlue: function(callback) { uni.getBluetoothAdapterState({ success(res1) { //console.log("当前蓝牙适配器状态:" + JSON.stringify(res1)) if (callback) { callback(res1); } }, fail(ex1) { console.log("检查蓝牙状态异常:" + JSON.stringify(ex1)); if (callback) { if (ex1.code == 10000) { console.log("未初始化蓝牙适配器"); } let res1 = { available: false, discovering: false } callback(res1); } }, complete() { } }); }, //初始化蓝牙模块 OpenBlue: function(isCheckState, callback, availCallback) { var these = this; var init = function() { uni.openBluetoothAdapter({ success: (res) => { console.log("蓝牙初始化成功:" + JSON.stringify(res)); if (callback) { callback(); } uni.onBluetoothAdapterStateChange(function(state) { //console.log('蓝牙状态发生变化:' + JSON.stringify(state)); if (this.BleChangeCallback) { this.BleChangeCallback() } }) }, fail: function(ex2) { console.log("蓝牙初始化失败:" + JSON.stringify(ex2)) if (ex2.code == '10001') { console.log("手机蓝牙未打开或设备不支持蓝牙"); if (availCallback) { availCallback(); } else { these.showBluetoothGuide(); } } } }); } if (isCheckState) { this.CheckBlue(function(res1) { if (res1.available) { if (callback) { callback(); } return; } init(); }) } else { init(); } }, //关闭蓝牙模块,停止搜索、断开所有连接 CloseBlue: function(callback) { this.StopSearch(); this.disconnectDevice(); uni.closeBluetoothAdapter({ success: () => { console.log("蓝牙模块已关闭"); if (callback) { callback(); } } }); }, //开始搜索新设备 StartSearch: function(callback) { var these = this; //发现新设备 var onDeviceFound = function() { uni.onBluetoothDeviceFound(function(res) { console.log("发现新设备:" + JSON.stringify(res)); if (callback) { callback(res); } }) } //开始搜索 var Search = function() { uni.startBluetoothDevicesDiscovery({ services: ["0xFFE0"], allowDuplicatesKey: false, success: (res) => { console.log('开始搜索蓝牙设备成功'); onDeviceFound(); }, fail: (err) => { console.log(`搜索蓝牙设备失败: ${err.errMsg}`); } }); } //先检查蓝牙状态是可用 this.CheckBlue(function(res1) { if (res1.available) { if (!res1.discovering) { Search(); } else { console.log("当前蓝牙正在搜索设备") } } else { these.OpenBlue(false, Search, () => { these.showBluetoothGuide(); }); } }); }, //停止搜索 StopSearch: function() { uni.stopBluetoothDevicesDiscovery({ success: (res) => { //console.log("停止搜索蓝牙设备成功") }, fail() { console.log("无法停止蓝牙搜索") } }); }, //获取已连接的设备 getLinkBlue: function(callback) { uni.getConnectedBluetoothDevices({ success: (res) => { if (callback) { callback(res); } }, fail: function(ex) { console.log("获取已连接设备异常",ex); if (callback) { callback({ devices: [] }); } } }) }, //连接某个设备 LinkBlue: function(deviceId, callback, error) { //console.log("deviceId="+deviceId) this.StopSearch(); var these = this; let key = "linkedDevices"; var store = uni.getStorageInfoSync(); var f = store.keys.find(function(v) { return v == key; }); var linkedDevices = []; if (f) { var str = uni.getStorageSync(key); if (str) { linkedDevices = JSON.parse(str); } else { linkedDevices = []; } } //连接成功的回调 var lindedCallback = function(id,flag) { let c = linkedDevices.find(function(v) { return v.deviceId == deviceId; }); if (c && !flag) { console.log("连接成功开始监听特征变化,deviceid="+deviceId+',serviceId='+c.notifyServiceid+',characteristicId='+c.notifyCharactId) //监听设备的特征变化 setTimeout(()=>{ uni.notifyBLECharacteristicValueChange({ deviceId: deviceId, serviceId: c.notifyServiceid, characteristicId: c.notifyCharactId, state: true, success: function(res) { console.log("开始监听成功。。。。",res) //订阅特征值 uni.onBLECharacteristicValueChange(function(data) { // data.characteristicId // data.deviceId // data.serviceId // data.value console.log("监听到特征值:" + JSON.stringify(data)); if (these.featrueValueCallback) { these.featrueValueCallback(data); } }); } }); },1000); } if (callback) { callback(deviceId,flag); } } var linkState = function(res) { //console.log("获取已连接的设备回调" + JSON.stringify(res)) let flag = res.devices.find(function(v) { if (v.deviceId == deviceId) { return true; } return false; }); if (flag) { //console.log("设备状态已连接"); lindedCallback(deviceId,true); return; } else { console.log("设备未连接:"+deviceId); linkDevice(deviceId); } } var linkDevice = function() { console.log("正在连接" + deviceId); uni.createBLEConnection({ deviceId: deviceId, timeout: 30000, success: function(info) { console.log("连接成功"); var call = () => { if (linkedDevices) { console.log("11111" + JSON.stringify(linkedDevices)); f = linkedDevices.find(function(v) { return v.deviceId == deviceId; }); } else { console.log("22222") f = null; } if (!f) { console.log("缓存中没有找到该设备") these.getLinkBlue(function(res) { if (res.devices && res.devices.length) { let f = res.devices.find(function(v) { return v.deviceId == deviceId; }); linkedDevices.push(f); uni.setStorageSync(key, JSON.stringify( linkedDevices)); getService(deviceId); } }); } else { console.log("缓存中已连接过"); if (!f.services) { getService(deviceId); } else { lindedCallback(deviceId,false); } } } let os = uni.getSystemInfoSync().osName; if (os == 'android') { uni.setBLEMTU({ deviceId: deviceId, mtu: 512, success: () => { //console.log("mtu设置成功"); }, fail: function() { console.log("mtu设置失败") }, complete: function() { call(); } }); } else { call(); } }, fail: function(ex) { if (ex) { console.log("蓝牙连接失败" + JSON.stringify(ex)); if(error){ error(ex); } } } }); } //获取服务 var getService = function(id) { var repeatCnt = 0; var startgetService = function() { uni.getBLEDeviceServices({ deviceId: id, success: function(res) { if (res.services && res.services.length > 0) { console.log("获取到服务:" + JSON.stringify(res)); linkedDevices.find(function(v) { if (v.deviceId == id) { v.services = res.services; } }); uni.setStorageSync(key, JSON.stringify(linkedDevices)); var promises = []; for (var i = 0; i < res.services.length; i++) { let service = res.services[i]; promises.push(getFeatrus(id, service.uuid)); } Promise.all(promises) .then(results => { console.log('所有操作成功完成', results); lindedCallback(id,false); }) .catch(error => { console.error('至少一个操作失败', error); }); } else { repeatCnt++; if (repeatCnt > 5) { lindedCallback(id,false); return; } setTimeout(function() { startgetService(id); }, 500); } } }) } setTimeout(function() { startgetService(id); }, 1000); } //获取特性 var getFeatrus = function(id, serviceId) { var promise = new Promise((resolve, reject) => { uni.getBLEDeviceCharacteristics({ deviceId: id, serviceId: serviceId, success: (res) => { console.log("获取到特征:" + JSON.stringify(res)); //写特征 let writeChar = res.characteristics.find(char => char.uuid.indexOf("FFE1") > -1 ); //通知特征 let notiChar = res.characteristics.find(char => char.uuid.indexOf("FFE2") > -1 ); linkedDevices.find(function(v) { if (v.deviceId == id) { if (!v.Characteristics) { v.Characteristics = []; } v.Characteristics = v.Characteristics.concat(res .characteristics); if (writeChar) { v.writeServiceId = serviceId; v.wirteCharactId = writeChar.uuid; } if (notiChar) { v.notifyServiceid = serviceId; v.notifyCharactId = notiChar.uuid; } } }); uni.setStorageSync(key, JSON.stringify(linkedDevices)); resolve(res); }, fail: (ex) => { console.log("获取特征出现异常:" + JSON.stringify(ex)); resolve(ex); } }); }); return promise; } //监测蓝牙状态变化 uni.onBLEConnectionStateChange(function(res) { if (!res.connected) { console.log("蓝牙断开连接" + res.deviceId + ""); // lindDevice(res.deviceId); } }); //console.log("正在获取蓝牙适配器状态") this.CheckBlue((res) => { //console.log("蓝牙状态:" + JSON.stringify(res)); if (res.available) { this.getLinkBlue(linkState); } else { console.log("蓝牙适配器不可用,正在初始化"); this.OpenBlue(false, () => { this.getLinkBlue(linkState); }, () => { console.log("请引导用户打开蓝牙"); these.showBluetoothGuide(); }) } }); }, //断开连接 disconnectDevice: function(deviceId) { var disconnect = function(id) { uni.closeBLEConnection({ deviceId: id, success: (res) => { console.log("蓝牙连接已断开"); } }); } if (deviceId) { disconnect(deviceId); return; } //断开所有已连接的设备 this.getLinkBlue(function(res) { if (res.devices && res.devices.length > 0) { for (var i = 0; i < res.devices.length; i++) { let item = res.devices[i]; disconnect(item.deviceId); } } else { console.log("无连接设备"); } }); }, //发送二进制数据 sendData: function(deviceid, buffer) { console.log("准备向设备发送数据,deviceid=" + deviceid); return new Promise((resolve, reject) => { if (!deviceid) { reject(`deviceid为空,请输入要发送的设备`); return; } console.log("准备发送数据包"); let key = "linkedDevices"; var store = uni.getStorageInfoSync(); var f = store.keys.find(function(v) { return v == key; }); console.log("倒计时:5"); var linkedDevices = []; if (f) { var str = uni.getStorageSync(key); if (str) { linkedDevices = JSON.parse(str); } } console.log("倒计时:4"); if (linkedDevices && linkedDevices.length && linkedDevices.length > 0) { console.log("倒计时:3"); f = linkedDevices.find(function(v) { return v.deviceId == deviceid; }); console.log("f=" + JSON.stringify(f)); // console.log("deviceid=" + deviceid); console.log("倒计时:2"); if (f) { console.log("倒计时:1"); these.sendDataNew(f.deviceId,f.writeServiceId,f.wirteCharactId,buffer).then(succ).catch(err); } else { reject(`已连接设备中无法找到此设备`); // console.log("警报:已连接设备中无法找到此设备") } } else { console.log("检测到未与设备建立连接"); reject(`检测到未与设备建立连接`); } }); }, sendDataNew: function(deviceid, serviceId, characteristicId, buffer) { //console.log("准备向设备发送数据,deviceid=" + deviceid+',serviceId='+serviceId+',characteristicId='+characteristicId); return new Promise((resolve, reject) => { let promise = new Promise((succ, err) => { uni.writeBLECharacteristicValue({ deviceId: deviceid, serviceId: serviceId, characteristicId: characteristicId, value: buffer, success: () => { //console.log("发送数据成功"); succ(); }, fail: (ex) => { console.log("发送数据失败" + JSON.stringify(ex)); err(ex); } }); }); if (uni.getSystemInfoSync().osName.toLowerCase() == 'ios') { //专业给IOS填坑,uni.writeBLECharacteristicValue在IOS上不进入任何回调 function timeout(ms) { return new Promise((_, err) => { setTimeout(() => { err({ code: -1, errMsg: '超时了' }) }, ms); }); } Promise.race([promise, timeout(50)]).then(resolve).catch((ex) => { console.log("ex=", ex); if (ex.code == -1) { resolve(); } else { reject(ex); } }).finally(() => { console.log("完成了") }); } else { promise.then(resolve).catch(reject); } }); } }