| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952 |
- const logEnable = false
- let isAndroid = false
- let ecBluetoothAdapterStateChangeCallback = () => {}
- let ecBluetoothDeviceFoundCallback = () => {}
- let ecBLEConnectionStateChangeCallback = () => {}
- let ecBLECharacteristicValueChangeCallback = () => {}
- let ecDeviceId = ''
- let ecGattServerUUID = ''
- const ecGattServerUUIDOption1 = '0000FFF0-0000-1000-8000-00805F9B34FB'
- const ecGattServerUUIDOption2 = 'FFF0'
- const yiyuanUUIDOption1 = '0000F536-0000-1000-8000-00805F9B34FB';
- const yiyuanUUIDOption2 = 'F536';
- let ecGattCharacteristicWriteUUID = ''
- const ecGattCharacteristicWriteUUIDOption1 = '0000FFF2-0000-1000-8000-00805F9B34FB'
- const ecGattCharacteristicWriteUUIDOption2 = 'FFF2'
- const yiyuancharacterID1 = '0000FF15-0000-1000-8000-00805F9B34FB'
- const yiyuancharacterID2 = 'FF15'
- import i18 from '@/utils/i18.js'
- const log = data => {
- if (logEnable) {
- console.log('[eciot]:' + JSON.stringify(data))
- }
- }
- const onBluetoothAdapterStateChange = cb => {
- ecBluetoothAdapterStateChangeCallback = cb
- }
- const _openBluetoothAdapter = () => {
- return new Promise(function(resolve, reject) {
- uni.openBluetoothAdapter({
- success(res) {
- log(res)
- resolve({
- ok: true,
- errCode: 0,
- errMsg: ''
- })
- },
- fail(res) {
- log(res)
- // {"errMsg":"openBluetoothAdapter:fail not available","code":10001}
- resolve({
- ok: false,
- errCode: res.code,
- errMsg: res.errMsg,
- })
- },
- })
- })
- }
- uni.onBluetoothAdapterStateChange(res => {
- log(res)
- // {"discovering":true,"available":true}
- if (!res.available) {
- ecBluetoothAdapterStateChangeCallback({
- ok: false,
- errCode: 30005,
- errMsg: i18('蓝牙适配器不可用'),
- })
- }
- })
- const openBluetoothAdapter = async () => {
- await _openBluetoothAdapter()
- const systemInfo = uni.getSystemInfoSync()
- log(systemInfo)
- if (systemInfo.platform.toLowerCase() === 'android') {
- isAndroid = true
- }
- const systemSetting = uni.getSystemSetting()
- log(systemSetting)
- const appAuthorizeSetting = uni.getAppAuthorizeSetting()
- log(appAuthorizeSetting)
- if (!systemSetting.bluetoothEnabled) {
- ecBluetoothAdapterStateChangeCallback({
- ok: false,
- errCode: 30001,
- errMsg: i18('请打开系统蓝牙开关'),
- })
- return
- }
- if (isAndroid && !systemSetting.locationEnabled) {
- ecBluetoothAdapterStateChangeCallback({
- ok: false,
- errCode: 30002,
- errMsg: i18('请打开系统定位开关'),
- })
- return
- }
- if (isAndroid && (appAuthorizeSetting.locationAuthorized!=='authorized')) {
- ecBluetoothAdapterStateChangeCallback({
- ok: false,
- errCode: 30003,
- errMsg: i18('请打开应用定位权限,允许应用使用您的位置信息'),
- })
- return
- }
- const openRes = await _openBluetoothAdapter()
- ecBluetoothAdapterStateChangeCallback(openRes)
- }
- uni.onBluetoothDeviceFound(res => {
- // log(res)
- const device = res.devices[0]
- const name = device.name ? device.name : device.localName
- if (!name) {
- return
- }
- let id = device.deviceId
- let rssi = device.RSSI
- ecBluetoothDeviceFoundCallback({
- id,
- name,
- rssi
- })
- })
- const onBluetoothDeviceFound = cb => {
- ecBluetoothDeviceFoundCallback = cb
- }
- const startBluetoothDevicesDiscovery = () => {
- uni.startBluetoothDevicesDiscovery({
- //services: [ecServerId],
- allowDuplicatesKey: true,
- // powerLevel: 'high',
- complete(res) {
- log(res)
- },
- })
- }
- const stopBluetoothDevicesDiscovery = () => {
- uni.stopBluetoothDevicesDiscovery({
- complete(res) {
- log(res)
- },
- })
- }
- const onBLEConnectionStateChange = cb => {
- ecBLEConnectionStateChangeCallback = cb
- }
- const _createBLEConnection = () => {
- return new Promise(function(resolve, reject) {
- uni.createBLEConnection({
- deviceId: ecDeviceId,
- success(res) {
- log(res)
- resolve({
- ok: true,
- errCode: 0,
- errMsg: ''
- })
- },
- fail(res) {
- log(res)
- resolve({
- ok: false,
- errCode: res.code,
- errMsg: res.errMsg,
- })
- },
- })
- })
- }
- const getBLEDeviceServices = () => {
- return new Promise(function(resolve, reject) {
- setTimeout(()=>{
- uni.getBLEDeviceServices({
- deviceId: ecDeviceId,
- success(res) {
- log(res)
- resolve({
- ok: true,
- errCode: 0,
- errMsg: '',
- services: res.services,
- })
- },
- fail(res) {
- log(res)
- resolve({
- ok: false,
- errCode: res.code,
- errMsg: res.errMsg
- })
- },
- })
- },1200)//之前是800ms,要休眠到1200ms
-
- })
- }
- const getBLEDeviceCharacteristics = serviceId => {
- return new Promise(function(resolve, reject) {
- uni.getBLEDeviceCharacteristics({
- deviceId: ecDeviceId,
- serviceId,
- success(res) {
- log(res)
- resolve({
- ok: true,
- errCode: 0,
- errMsg: '',
- characteristics: res.characteristics,
- })
- },
- fail(res) {
- log(res)
- resolve({
- ok: false,
- errCode: res.code,
- errMsg: res.errMsg
- })
- },
- })
- })
- }
- const notifyBLECharacteristicValueChange = (serviceId, characteristicId) => {
- return new Promise(function(resolve, reject) {
- uni.notifyBLECharacteristicValueChange({
- state: true,
- deviceId: ecDeviceId,
- serviceId,
- characteristicId,
- success(res) {
- log(res)
- resolve({
- ok: true,
- errCode: 0,
- errMsg: ''
- })
- },
- fail(res) {
- log(res)
- resolve({
- ok: false,
- errCode: res.code,
- errMsg: res.errMsg
- })
- },
- })
- })
- }
- const setBLEMTU = mtu => {
- return new Promise(function(resolve, reject) {
- setTimeout(()=>{
- uni.setBLEMTU({
- deviceId: ecDeviceId,
- mtu,
- success(res) {
- log(res)
- resolve({
- ok: true,
- errCode: 0,
- errMsg: ''
- })
- },
- fail(res) {
- log(res)
- resolve({
- ok: false,
- errCode: res.code,
- errMsg: res.errMsg
- })
- },
- })
- },500)
- })
- }
- uni.onBLEConnectionStateChange(async res => {
- log(res)
- if (res.connected) {
- console.log("=== 设备连接成功 ===")
- const servicesResult = await getBLEDeviceServices()
- console.log("服务发现结果:", servicesResult)
- if (!servicesResult.ok) {
- ecBLEConnectionStateChangeCallback(servicesResult)
- closeBLEConnection()
- return
- }
- console.log("设备提供的所有服务:", servicesResult.services)
- // 优先查找的服务和特征值UUID(与微信端保持一致)
- const targetServiceUUIDs = [
- '0000FFE0-0000-1000-8000-00805F9B34FB'.toUpperCase(),
- 'FFE0'.toUpperCase(),
- // 保留原来的选项
- '0000FFF0-0000-1000-8000-00805F9B34FB'.toUpperCase(),
- 'FFF0'.toUpperCase(),
- '0000F536-0000-1000-8000-00805F9B34FB'.toUpperCase(),
- 'F536'.toUpperCase()
- ];
- const targetCharacteristicUUIDs = [
- '0000FFE1-0000-1000-8000-00805F9B34FB'.toUpperCase(),
- 'FFE1'.toUpperCase(),
- // 保留原来的选项
- '0000FFF2-0000-1000-8000-00805F9B34FB'.toUpperCase(),
- 'FFF2'.toUpperCase(),
- '0000FF15-0000-1000-8000-00805F9B34FB'.toUpperCase(),
- 'FF15'.toUpperCase()
- ];
- let serviceFound = false;
- let notifyEnabled = false; // 新增:跟踪是否成功启用通知
- let writeCharacteristicFound = false; // 跟踪是否找到写入特征值
- // 首先按优先级查找
- serviceLoop: for (const service of servicesResult.services) {
- const serviceUUID = service.uuid.toUpperCase();
- console.log("正在检查服务:", serviceUUID);
- // 检查是否是目标服务
- if (targetServiceUUIDs.includes(serviceUUID)) {
- console.log("✅ 找到目标服务:", serviceUUID);
- // 获取该服务下的所有特征值
- const characteristicsResult = await getBLEDeviceCharacteristics(service.uuid)
- console.log(`服务 ${service.uuid} 的特征值获取结果:`, characteristicsResult);
- if (!characteristicsResult.ok) {
- console.log(`获取服务 ${service.uuid} 的特征值失败`)
- continue
- }
- console.log(`服务 ${service.uuid} 下的特征值:`, characteristicsResult.characteristics)
- // 分别查找通知特征值和写入特征值
- let notifyCharacteristic = null;
- let writeCharacteristic = null;
- // 遍历所有特征值
- for (const characteristic of characteristicsResult.characteristics) {
- const charUUID = characteristic.uuid.toUpperCase();
- console.log("检查特征值:", charUUID, "属性:", characteristic.properties);
- // 查找通知特征值
- if (characteristic.properties && (characteristic.properties.notify || characteristic.properties.indicate)) {
- notifyCharacteristic = characteristic;
- console.log("✅ 找到通知特征值:", charUUID);
- // 尝试启用通知
- const notifyResult = await notifyBLECharacteristicValueChange(
- service.uuid,
- characteristic.uuid
- )
- if (notifyResult.ok) {
- console.log("✅ 通知已启用:", characteristic.uuid);
- notifyEnabled = true;
- } else {
- console.log("⚠️ 启用通知失败:", characteristic.uuid, notifyResult);
- }
- }
- // 查找写入特征值
- if (targetCharacteristicUUIDs.includes(charUUID) &&
- characteristic.properties &&
- (characteristic.properties.write || characteristic.properties.writeNoResponse)) {
- writeCharacteristic = characteristic;
- console.log("✅ 找到写入特征值:", charUUID);
- }
- }
- // 如果找到了写入特征值,设置全局变量
- if (writeCharacteristic) {
- ecGattServerUUID = service.uuid;
- ecGattCharacteristicWriteUUID = writeCharacteristic.uuid;
- console.log("服务 UUID:", ecGattServerUUID);
- console.log("写入特征值 UUID:", ecGattCharacteristicWriteUUID);
- serviceFound = true;
- writeCharacteristicFound = true;
- break serviceLoop;
- }
- }
- }
- // 如果没找到目标服务/特征值,则使用动态查找
- if (!serviceFound) {
- console.log("未找到预定义的服务/特征值,使用动态查找...")
- serviceLoop2: for (const service of servicesResult.services) {
- console.log("正在检查服务:", service.uuid)
- // 获取该服务下的所有特征值
- const characteristicsResult = await getBLEDeviceCharacteristics(service.uuid)
- console.log(`服务 ${service.uuid} 的特征值获取结果:`, characteristicsResult);
- if (!characteristicsResult.ok) {
- console.log(`获取服务 ${service.uuid} 的特征值失败`)
- continue
- }
- console.log(`服务 ${service.uuid} 下的特征值:`, characteristicsResult.characteristics)
- // 分别查找通知特征值和写入特征值
- let notifyCharacteristic = null;
- // 遍历所有特征值
- for (const characteristic of characteristicsResult.characteristics) {
- console.log("动态查找 - 检查特征值:", characteristic.uuid, "属性:", characteristic.properties);
- // 查找通知特征值
- if (characteristic.properties && (characteristic.properties.notify || characteristic.properties.indicate)) {
- notifyCharacteristic = characteristic;
- console.log("✅ 找到通知特征值:", characteristic.uuid);
- // 尝试启用通知
- const notifyResult = await notifyBLECharacteristicValueChange(
- service.uuid,
- characteristic.uuid
- )
- if (notifyResult.ok) {
- console.log("✅ 通知已启用:", characteristic.uuid);
- notifyEnabled = true;
- } else {
- console.log("⚠️ 启用通知失败:", characteristic.uuid, notifyResult);
- }
- }
- // 查找写入特征值
- if (characteristic.properties &&
- (characteristic.properties.write || characteristic.properties.writeNoResponse)) {
- // 找到支持写入的特征值,设置全局变量
- ecGattServerUUID = service.uuid
- ecGattCharacteristicWriteUUID = characteristic.uuid
- console.log("✅ 找到可写特征值")
- console.log("服务 UUID:", ecGattServerUUID)
- console.log("特征值 UUID:", ecGattCharacteristicWriteUUID)
- serviceFound = true
- writeCharacteristicFound = true;
- break serviceLoop2; // 使用标签跳出外层循环
- }
- }
- }
- }
- // 如果没有找到可写特征值
- if (!writeCharacteristicFound) {
- console.error("❌ 未找到支持写入的特征值")
- console.log("所有服务和特征值信息:", servicesResult.services);
- ecBLEConnectionStateChangeCallback({
- ok: false,
- errCode: 30000,
- errMsg: '未找到支持写入的特征值',
- })
- closeBLEConnection()
- return
- }
- // 检查是否成功启用了通知
- if (!notifyEnabled) {
- console.warn("⚠️ 警告:未成功启用任何特征值的通知功能");
- console.log("⚠️ 设备可能使用轮询方式而非通知方式通信");
- // 继续连接,因为有些设备可能不使用通知机制
- } else {
- console.log("✅ 通知功能已成功启用");
- }
- // 设置MTU(仅安卓)
- if (isAndroid) {
- try {
- await setBLEMTU(247)
- console.log("MTU 设置成功")
- } catch (error) {
- console.log("MTU 设置失败:", error)
- }
- }
- // 连接成功回调
- console.log("=== 准备发送连接成功回调 ===");
- console.log("服务UUID:", ecGattServerUUID);
- console.log("写入特征值UUID:", ecGattCharacteristicWriteUUID);
- ecBLEConnectionStateChangeCallback({
- ok: true,
- errCode: 0,
- errMsg: '',
- })
- } else {
- console.log("=== 设备断开连接 ===");
- ecBLEConnectionStateChangeCallback({
- ok: false,
- errCode: 0,
- errMsg: 'disconnect',
- })
- }
- })
- const createBLEConnection = async id => {
- ecDeviceId = id
- const res = await _createBLEConnection()
- if (!res.ok) {
- ecBLEConnectionStateChangeCallback(res)
- }
- }
- const closeBLEConnection = () => {
- uni.closeBLEConnection({
- deviceId: ecDeviceId,
- complete(res) {
- log(res);
- uni.showToast({
- title: '操作执行成功!',
- icon: 'success',
- duration: 2000
- });
- },
- })
- }
- uni.onBLECharacteristicValueChange(res => {
- log(res)
- let x = new Uint8Array(res.value)
- log(x)
- let str = utf8BytesToStr(x)
- let strHex = ''
- for (let i = 0; i < x.length; i++) {
- strHex = strHex + x[i].toString(16).padStart(2, '0').toUpperCase()
- }
- log(str)
- log(strHex)
- ecBLECharacteristicValueChangeCallback(str, strHex)
- })
-
- const onBLECharacteristicValueChange = cb => {
- ecBLECharacteristicValueChangeCallback = cb
- }
- const _writeBLECharacteristicValue = buffer => {
- return new Promise(function(resolve, reject) {
- uni.writeBLECharacteristicValue({
- deviceId: ecDeviceId,
- serviceId: ecGattServerUUID,
- characteristicId: ecGattCharacteristicWriteUUID,
- value: buffer,
- writeType: 'writeNoResponse',
- success(res) {
- log(res)
- resolve({
- ok: true,
- errCode: 0,
- errMsg: ''
- })
- },
- fail(res) {
- console.log("写入失败");
- console.log(res);
- log(res)
- resolve({
- ok: false,
- errCode: res.code,
- errMsg: res.errMsg
- })
- },
- })
- })
- }
- const writeBLECharacteristicValue = async (str, isHex) => {
-
- if (str.length === 0)
- return {
- ok: false,
- errCode: 30000,
- errMsg: 'data is null'
- }
- let buffer
- if (isHex) {
- buffer = new ArrayBuffer(str.length / 2)
- let x = new Uint8Array(buffer)
- for (let i = 0; i < x.length; i++) {
- x[i] = parseInt(str.substr(2 * i, 2), 16)
- }
- } else {
- // AT指令模式 - 处理ASCII字符串
- // 转换为UTF-8字节数组
- const encoder = new TextEncoder();
- const utf8Bytes = encoder.encode(str);
- buffer = utf8Bytes.buffer;
- // 显示ASCII格式的日志
- console.log("TX: " + str); // 发送数据日志
- const writeData = "RX: " + str;
- saveWriteDataToLocal(writeData, 'rx');
- }
- if (isHex){
- // 显示十六进制格式的日志(类似 RX: + 的格式)
- const hexArray = [...new Uint8Array(buffer)]
- .map(b => b.toString(16).padStart(2, '0').toUpperCase());
- const hexString = hexArray.join(' ');
- console.log("RX: " + hexString); // 发送数据日志,格式如 "RX: 01 03 00 01 00 01"
- // 保存写入数据到本地存储
- const writeData = "RX: " + hexString;
- saveWriteDataToLocal(writeData,'rx');
- }else {
- const writeData = "RX: " + str;
- saveWriteDataToLocal(writeData,'rx');
- }
- return await _writeBLECharacteristicValue(buffer)
- }
- /**
- * 向蓝牙特征值写入数据
- * @param {string} str - 要发送的字符串数据
- * @param {boolean} isHex - 数据格式标志。
- * false: str 包含十六进制字符串 (e.g., "01030001004695F8")
- * true: str 包含 ASCII 字符串 (e.g., "Hello")
- * @returns {Promise<Object>} 写入操作的结果
- */
- const writeBLECharacteristicValueTwo = async (str, isHex) => {
- if (str.length === 0)
- return {
- ok: false,
- errCode: 30000,
- errMsg: 'data is null'
- }
- let buffer;
- // isHex === false 时,发送 ASCII 字符串
- if (!isHex) {
- // AT指令模式 - 处理ASCII字符串
- // 转换为UTF-8字节数组
- const encoder = new TextEncoder();
- const utf8Bytes = encoder.encode(str);
- buffer = utf8Bytes.buffer;
- // 显示ASCII格式的日志
- console.log("TX (ASCII): " + str); // 发送数据日志
- const writeData = "TX (ASCII): " + str;
- saveWriteDataToLocal(writeData, 'tx');
- }
- // isHex === true 时,发送十六进制字符串
- else {
- // 移除所有空格,确保是连续的十六进制字符串
- const hexString = str.replace(/\s/g, '');
- // 检查长度是否为偶数
- if (hexString.length % 2 !== 0) {
- console.error("Invalid hex string length");
- return {
- ok: false,
- errCode: 30001,
- errMsg: 'Invalid hex string length'
- };
- }
- // 检查是否包含非十六进制字符
- if (!/^[0-9A-Fa-f]*$/.test(hexString)) {
- console.error("Invalid hex characters");
- return {
- ok: false,
- errCode: 30002,
- errMsg: 'Invalid hex characters'
- };
- }
- // 创建 ArrayBuffer 并填充数据
- buffer = new ArrayBuffer(hexString.length / 2);
- let x = new Uint8Array(buffer);
- for (let i = 0; i < x.length; i++) {
- x[i] = parseInt(hexString.substr(2 * i, 2), 16);
- }
- // 显示十六进制格式的日志
- const formattedHex = hexString.match(/.{1,2}/g)?.join(' ') || '';
- console.log("TX (HEX): " + formattedHex); // 发送数据日志
- const writeData = "TX (HEX): " + formattedHex;
- saveWriteDataToLocal(writeData, 'tx');
- }
- console.log("Buffer to send:", new Uint8Array(buffer));
- return await _writeBLECharacteristicValue(buffer);
- }
- // 新增:模拟 QString::toLatin1() 的行为
- function stringToLatin1Bytes(str) {
- const bytes = [];
- for (let i = 0; i < str.length; i++) {
- const code = str.charCodeAt(i); // 获取 UTF-16 code unit
- // 检查是否在 Latin-1 范围内 (0-255)
- if (code >= 0 && code <= 255) {
- bytes.push(code); // 直接作为字节值
- } else {
- // C++ QString::toLatin1() 对于超出范围的字符通常会变成 0 或 '?' (0x3F)
- // 这里我们选择 0x3F ('?')
- // 你需要根据 C++ 实际行为调整,可能是 0x00
- bytes.push(0x3F); // 或者 bytes.push(0x00);
- }
- }
- return new Uint8Array(bytes);
- }
- const utf8BytesToStr = utf8Bytes => {
- let unicodeStr = ''
- for (let pos = 0; pos < utf8Bytes.length;) {
- let flag = utf8Bytes[pos]
- let unicode = 0
- if (flag >>> 7 === 0) {
- unicodeStr += String.fromCharCode(utf8Bytes[pos])
- pos += 1
- }
- // else if ((flag & 0xFC) === 0xFC) {
- // unicode = (utf8Bytes[pos] & 0x3) << 30
- // unicode |= (utf8Bytes[pos + 1] & 0x3F) << 24
- // unicode |= (utf8Bytes[pos + 2] & 0x3F) << 18
- // unicode |= (utf8Bytes[pos + 3] & 0x3F) << 12
- // unicode |= (utf8Bytes[pos + 4] & 0x3F) << 6
- // unicode |= (utf8Bytes[pos + 5] & 0x3F)
- // unicodeStr += String.fromCharCode(unicode)
- // pos += 6
- // }
- // else if ((flag & 0xF8) === 0xF8) {
- // unicode = (utf8Bytes[pos] & 0x7) << 24
- // unicode |= (utf8Bytes[pos + 1] & 0x3F) << 18
- // unicode |= (utf8Bytes[pos + 2] & 0x3F) << 12
- // unicode |= (utf8Bytes[pos + 3] & 0x3F) << 6
- // unicode |= (utf8Bytes[pos + 4] & 0x3F)
- // unicodeStr += String.fromCharCode(unicode)
- // pos += 5
- // }
- else if ((flag & 0xf0) === 0xf0) {
- unicode = (utf8Bytes[pos] & 0xf) << 18
- unicode |= (utf8Bytes[pos + 1] & 0x3f) << 12
- unicode |= (utf8Bytes[pos + 2] & 0x3f) << 6
- unicode |= utf8Bytes[pos + 3] & 0x3f
- unicodeStr += String.fromCharCode(unicode)
- pos += 4
- } else if ((flag & 0xe0) === 0xe0) {
- unicode = (utf8Bytes[pos] & 0x1f) << 12
- unicode |= (utf8Bytes[pos + 1] & 0x3f) << 6
- unicode |= utf8Bytes[pos + 2] & 0x3f
- unicodeStr += String.fromCharCode(unicode)
- pos += 3
- } else if ((flag & 0xc0) === 0xc0) {
- //110
- unicode = (utf8Bytes[pos] & 0x3f) << 6
- unicode |= utf8Bytes[pos + 1] & 0x3f
- unicodeStr += String.fromCharCode(unicode)
- pos += 2
- } else {
- unicodeStr += String.fromCharCode(utf8Bytes[pos])
- pos += 1
- }
- }
- return unicodeStr
- }
- const strToUtf8Bytes = str => {
- let bytes = []
- for (let i = 0; i < str.length; ++i) {
- let code = str.charCodeAt(i)
- if (code >= 0x10000 && code <= 0x10ffff) {
- bytes.push((code >> 18) | 0xf0) // 第一个字节
- bytes.push(((code >> 12) & 0x3f) | 0x80)
- bytes.push(((code >> 6) & 0x3f) | 0x80)
- bytes.push((code & 0x3f) | 0x80)
- } else if (code >= 0x800 && code <= 0xffff) {
- bytes.push((code >> 12) | 0xe0)
- bytes.push(((code >> 6) & 0x3f) | 0x80)
- bytes.push((code & 0x3f) | 0x80)
- } else if (code >= 0x80 && code <= 0x7ff) {
- bytes.push((code >> 6) | 0xc0)
- bytes.push((code & 0x3f) | 0x80)
- } else {
- bytes.push(code)
- }
- }
- return bytes
- }
- // 在文件顶部添加全局变量
- let globalWriteLogs = []
- let logListeners = []
- // 保存数据到全局变量的函数(移除本地存储)
- const saveWriteDataToLocal = (data, type) => {
- try {
- const now = new Date();
- const year = now.getFullYear();
- const month = String(now.getMonth() + 1).padStart(2, '0');
- const day = String(now.getDate()).padStart(2, '0');
- const hours = String(now.getHours()).padStart(2, '0');
- const minutes = String(now.getMinutes()).padStart(2, '0');
- const seconds = String(now.getSeconds()).padStart(2, '0');
- // 创建日志条目
- const logEntry = {
- time: `${year}-${month}-${day} ${hours}:${minutes}:${seconds}`,
- data: data,
- type: type
- }
- // 添加到全局变量
- globalWriteLogs.push(logEntry)
- // 限制全局日志数量为最近100条
- if (globalWriteLogs.length > 100) {
- globalWriteLogs = globalWriteLogs.slice(-100)
- }
- // 通知所有监听器
- notifyLogListeners()
- } catch (e) {
-
- }
- }
- // 添加获取全局日志的方法
- const getGlobalWriteLogs = () => {
- return globalWriteLogs
- }
- // 添加清空全局日志的方法
- const clearGlobalWriteLogs = () => {
- globalWriteLogs = []
- notifyLogListeners()
- }
- // 添加监听器管理方法
- const addLogListener = (callback) => {
- logListeners.push(callback)
- }
- const removeLogListener = (callback) => {
- const index = logListeners.indexOf(callback)
- if (index > -1) {
- logListeners.splice(index, 1)
- }
- }
- // 通知监听器
- const notifyLogListeners = () => {
- logListeners.forEach(callback => {
- callback(globalWriteLogs)
- })
- }
- // 根据类型删除日志的函数(仅操作全局变量)
- const removeWriteDataByType = (type) => {
- try {
- const originalLength = globalWriteLogs.length;
- // 过滤掉指定类型的日志
- globalWriteLogs = globalWriteLogs.filter(log => log.type !== type)
- const deletedCount = originalLength - globalWriteLogs.length;
- // 通知所有监听器更新
- notifyLogListeners()
- console.log(`已删除类型为 '${type}' 的日志,共删除 ${deletedCount} 条`);
- return {
- success: true,
- deletedCount: deletedCount
- }
- } catch (e) {
- console.error('删除写入数据失败:', e)
- return {
- success: false,
- error: e
- }
- }
- }
- // 清空所有日志的函数(仅操作全局变量)
- const clearAllWriteData = () => {
- try {
- globalWriteLogs = []
- notifyLogListeners()
- console.log("已清空所有日志");
- return {
- success: true
- }
- } catch (e) {
- console.error('清空所有日志失败:', e)
- return {
- success: false,
- error: e
- }
- }
- }
- // 获取特定类型的日志
- const getWriteDataByType = (type) => {
- try {
- const filteredLogs = globalWriteLogs.filter(log => log.type === type)
- return filteredLogs
- } catch (e) {
- console.error('获取特定类型日志失败:', e)
- return []
- }
- }
- // 获取所有日志(按时间倒序排列)
- const getAllWriteDataSorted = () => {
- try {
- // 创建副本避免修改原数组
- let writeLogs = [...globalWriteLogs]
- // 按时间倒序排列(最新的在前面)
- writeLogs.sort((a, b) => {
- return new Date(b.time) - new Date(a.time);
- });
- return writeLogs
- } catch (e) {
- console.error('获取排序日志失败:', e)
- return []
- }
- }
- // 导出新增的方法
- export default {
- onBluetoothAdapterStateChange,
- openBluetoothAdapter,
- onBluetoothDeviceFound,
- startBluetoothDevicesDiscovery,
- stopBluetoothDevicesDiscovery,
- onBLEConnectionStateChange,
- createBLEConnection,
- closeBLEConnection,
- onBLECharacteristicValueChange,
- writeBLECharacteristicValue,
- saveWriteDataToLocal,
- getGlobalWriteLogs,
- clearGlobalWriteLogs,
- addLogListener,
- removeLogListener,
- removeWriteDataByType, // 新增
- clearAllWriteData, // 新增
- getWriteDataByType, // 新增
- getAllWriteDataSorted, // 新增
- writeBLECharacteristicValueTwo
- }
|