問題描述:app接收到藍牙傳出過來的二進制數據,1.app進行arrbuff轉成16進制字符串
// ArrayBuffer轉16進度字符串示例 function ab2hex(buffer) { const hexArr = Array.prototype.map.call( new Uint8Array(buffer), function(bit) { return ('00' + bit.toString(16)).slice(-2) } ) return hexArr.join('') }
2.將16進制的字符串轉成10進制字符串這里需要特別注意(JS默認是Unicode編碼的 也就是UTF-16)你看下你的設備傳輸過來的是什么編碼
// 16進制轉字符串 async function hexCharCodeToStr(hex) { var arr = hex.split(""), out = "", len = hex.length / 2; for (var i = 0; i < len; i++) { out += String.fromCharCode(parseInt(hex.substr(i * 2, 2), 16)); } // 此時的out為UTF-8 //藍牙使用的是UTF-8編碼 // 解決亂碼問題 (JS默認是Unicode編碼的 也就是UTF-16) return await utf8to16(out) }
3.解決中文亂碼關鍵【這里以我自己舉例,我對接的設備傳輸的編碼是utf-8】我需要把UTF-8編碼轉成UTF-16下面提供兩個方法
function utf8to16(str) { var out, i, len, c; var char2, char3; out = ""; len = str.length; i = 0; while (i < len) { c = str.charCodeAt(i++); switch (c >> 4) { case 0: case 1: case 2: case 3: case 4: case 5: case 6: case 7: // 0xxxxxxx out += str.charAt(i - 1); break; case 12: case 13: // 110x xxxx 10xx xxxx char2 = str.charCodeAt(i++); out += String.fromCharCode(((c & 0x1F) << 6) | (char2 & 0x3F)); break; case 14: // 1110 xxxx 10xx xxxx 10xx xxxx char2 = str.charCodeAt(i++); char3 = str.charCodeAt(i++); out += String.fromCharCode(((c & 0x0F) << 12) | ((char2 & 0x3F) << 6) | ((char3 & 0x3F) << 0)); break; } } return out; } function utf16to8(str) { var out, i, len, c; out = ""; len = str.length; for(i = 0; i < len; i++) { c = str.charCodeAt(i); if ((c >= 0x0001) && (c <= 0x007F)) { out += str.charAt(i); } else if (c > 0x07FF) { out += String.fromCharCode(0xE0 | ((c >> 12) & 0x0F)); out += String.fromCharCode(0x80 | ((c >> 6) & 0x3F)); out += String.fromCharCode(0x80 | ((c >> 0) & 0x3F)); } else { out += String.fromCharCode(0xC0 | ((c >> 6) & 0x1F)); out += String.fromCharCode(0x80 | ((c >> 0) & 0x3F)); } } return out; }
4,APP藍牙發送數據給設備需要注意(因為js默認時utf-16的需要轉成utf-8)在進行發送,否則設備端也解析不了
// 字符串轉16進制 str需要傳入設備需要的utf-8(js字符串默認是Unicode編碼utf16,需轉成設備的utf8)解決中文問題,否則設備處理不了 function strToHexCharCode(str) { if (str === "") return ""; var hexCharCode = []; // hexCharCode.push("0x"); for (var i = 0; i < str.length; i++) { hexCharCode.push((str.charCodeAt(i)).toString(16)); } return hexCharCode.join(""); }
5.調用發送數據給設備
//設置wifi setWifiInfo() { uni.showLoading({ title: 'wifi網絡配置中..', mask: false }); //此時需要注意 wifi名為中文需要把中文的utf-16轉成utf-8 let body = { "ssid":that.$lizhao.scale.utf16to8(that.picker.form.ssid), "password": that.picker.form.password } let length = that.$lizhao.scale.switch_sl(JSON.stringify(body).length, 16) // 十進制轉十六進制 let stri = '0' for (let i = 0; i < (7 - length.length); i++) { stri += '0' } let cmd = '0002' //2轉成兩位的16進制為00 02 let len = stri + length //body的長度為39轉成4位的16進制為00 00 00 26 //十進制數據轉換為16進制 let body_16 = that.$lizhao.scale.strToHexCharCode(JSON.stringify(body)) let hex = that.Bluetooth.agreement.magic + cmd + that.Bluetooth.agreement.id + len + body_16 let arr = that.splitArr(hex) //多個指令串行發送,並行可能會失敗 that.writeCmd(arr, 0) }, //arr為hex分割的數組,i為當前數組下標 async writeCmd(arr, i) { let res = await that.$lizhao.bluetooth.writeBLECharacteristicValue(arr[i]) if (res == 'writeBLECharacteristicValue:ok') { i++ if (i > arr.length) { return } that.writeCmd(arr, i) } else { that.writeCmd(arr, i) } }, //分割指令每20位分割一下,返回數組 splitArr(hex) { let arr = [] for (let a = 0; a < Math.ceil(hex.length / 20); a++) { let str = hex.slice(a * 20, a * 20 + 20) arr.push(str) } return arr }