You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

RFID扫描器读取含数字/大写字母的标签USER区返回乱码求助

问题分析与解决方案

你遇到的核心问题是RFID标签USER区的字节数据并非直接对应标准字符编码的可打印字符,直接将byte[]转换为字符串会因为编码不匹配或数据格式问题导致乱码;小写字母正常只是巧合(其对应的字节刚好在默认编码中是可打印字符)。

可能的原因

  1. 标签数据存储格式问题:多数RFID标签的USER区会以十六进制格式存储原始数据,而非直接存储ASCII字符的字节,直接转字符串会导致编码错位。
  2. 带符号字节干扰:Java的byte是带符号类型(范围-128~127),如果标签中存储的无符号字节值超过127,转换为字符时会被解析为负数对应的乱码。
  3. 额外数据混入:读取的byte[]可能包含标签的长度位、校验位等非内容数据,这些不可打印字符会干扰显示。

解决方案

方案1:将字节数组转为十六进制后再解析为ASCII字符

这是处理RFID数据最常用的方式,先把原始字节转成十六进制字符串,再将每两位十六进制值解析为对应的ASCII字符:

@Override
public void onReadResultReceived(final ReadResult readResult) {
    if (readResult.getStatus() == Status.STATUS_OK) {
        mHandler.post(() -> {
            synchronized (mInventoryResultsLock) {
                if (readResult.getStatus() == Status.STATUS_OK) {
                    byte[] bankData = readResult.getBankData();
                    // 把字节数组转成无符号十六进制字符串
                    StringBuilder hexBuilder = new StringBuilder();
                    for (byte b : bankData) {
                        int unsignedByte = b & 0xFF;
                        hexBuilder.append(String.format("%02X", unsignedByte));
                    }
                    String hexStr = hexBuilder.toString();
                    // 解析十六进制字符串为ASCII字符
                    StringBuilder resultBuilder = new StringBuilder();
                    for (int i = 0; i < hexStr.length(); i += 2) {
                        String hexPair = hexStr.substring(i, i + 2);
                        try {
                            int charCode = Integer.parseInt(hexPair, 16);
                            resultBuilder.append((char) charCode);
                        } catch (NumberFormatException e) {
                            resultBuilder.append('?');
                        }
                    }
                    appendText(resultBuilder.toString());
                }
            }
        });
    }
}

方案2:过滤不可打印字符并按无符号字节转换

如果标签确实存储的是ASCII字符,但混入了不可打印的控制字节,可以先过滤后再转换:

@Override
public void onReadResultReceived(final ReadResult readResult) {
    if (readResult.getStatus() == Status.STATUS_OK) {
        mHandler.post(() -> {
            synchronized (mInventoryResultsLock) {
                if (readResult.getStatus() == Status.STATUS_OK) {
                    byte[] bankData = readResult.getBankData();
                    StringBuilder strBuilder = new StringBuilder();
                    for (byte b : bankData) {
                        char c = (char) (b & 0xFF);
                        // 只保留可打印字符
                        if (Character.isPrintable(c)) {
                            strBuilder.append(c);
                        }
                    }
                    appendText(strBuilder.toString());
                }
            }
        });
    }
}

验证建议

可以先打印出bankData的字节值(用十六进制格式),对比标签USER区的实际存储内容,确认数据格式是否匹配,比如:

for (byte b : bankData) {
    Log.d("RFID_DATA", String.format("%02X", b & 0xFF));
}

这样能直观看到读取的原始数据,进一步定位问题。

内容的提问来源于stack exchange,提问作者lvl 1 slime

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.20 07:44:16