• uniapp蓝牙传输中文乱码问题


    问题描述: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
                }
  • 相关阅读:
    投稿007期|令人震惊到发指的PyObject对象代码设计之美
    使用OpenCV通过摄像头捕获实时视频并探测人脸
    洛谷 P1259【黑白棋子的移动】
    入门OJ 1281【营救(save)】
    入门OJ 3204【射击】
    POJ 3126【长度为素数的路径个数】
    POJ 1980【Unit Fraction Partition】
    洛谷 P2374【搬运工】
    【常用算法总结——记忆化搜索】
    P3052 [USACO12MAR]【摩天大楼里的奶牛(Cows in a Skyscraper)】
  • 原文地址:https://www.cnblogs.com/lizhao123/p/14923970.html
Copyright © 2020-2023  润新知