android - 通过安卓NFC读取ISO15693 RFID标签导致数据输出不正确

标签 android tags nfc rfid iso-15693

我们有一些 ISO15693 标签,我们过去使用 RFID 阅读器读取这些标签。今天,我开始在 Android 上开发一个示例应用程序,以使用 NfcV 和 Android 6 (API 23) 读取相同的标签。

我能够从标签中读取一些数据,但数据中有一些意想不到的字符。这是我使用的代码:

private void readTagData(Tag tag) throws Exception {
    byte[] id = tag.getId();
    String strTag = new String(id, "UTF-8");
    boolean techFound = false;
    for (String tech : tag.getTechList()) {
        if (tech.equals(NfcV.class.getName())) {
            techFound = true;
            NfcV nfcvTag = NfcV.get(tag);
            try {
                nfcvTag.connect();
            } catch (IOException e) {
                Toast.makeText(this, "IO Exception", Toast.LENGTH_LONG).show();
                return;
            }
            try {
                int offset = 0;  
                int blocks = 19;  
                byte[] cmd = new byte[]{
                        (byte)0x60,                  
                        (byte)0x23,                  
                        (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00,  // placeholder for tag UID
                        (byte)(offset & 0x0ff),      
                        (byte)((blocks - 1) & 0x0ff)
                };
                System.arraycopy(id, 0, cmd, 2, 8);
                byte[] response = nfcvTag.transceive(cmd);

                response = Arrays.copyOfRange(response, 0, 96);
                String strData = new String(response, "UTF-8");
                mTextView.setText("TAG:" + strTag + " DATA:" + strData);
            } catch (IOException e) {
                Toast.makeText(this, "An error occurred while reading", Toast.LENGTH_SHORT).show();
                return;
            }

            try {
                nfcvTag.close();
            } catch (IOException e) {
                Toast.makeText(getApplicationContext(), "Unable to close the connection!", Toast.LENGTH_SHORT).show();
                return;
            }
        }
    }
}

输出

标签 ID(UTF-8 解码):{�WP�

数据(UTF-8 解码):����1ead��1234��5678��5000��00B1��2345��6181��5064��1602��2016��1603��2016� ��1602��2018��0011��8899��0002��0920��16����

十六进制表示的数据字节:

0000316561640031 3233340035363738
0035303030003030 42310032333‌43500
363138310035303‌6 3400313630320032
303‌1360031363033 0032303‌136003136
30320032303‌13800 303031310038383‌9
3900303030320030 393‌​2300031360000

现在部分数据是正确的,但我不确定为什么会出现这些“�”字符。标签 ID 也不正确。

另外,我尝试将字节数组“response”和标签 ID 转换为十六进制字符串,然后再转换为 ASCII,结果相同。

最佳答案

您收到的值是您发送的命令的预期响应:

您发送命令 READ MULTIPLE BLOCKS(命令代码 0x23)参数化以读取从偏移量 0 开始的 19 个 block 。您的标签的 block 大小似乎是 4 个字节。

此外,您还指定了一个标志字节 0x60,它转换为标志 Address_flagOption_flagAddress_flag 使命令被寻址(即,您必须指定目标标签的 UID,这是您正确执行的操作)。 Option_flag 使标签除了返回 block 数据本身之外还返回 block 安全状态。因此,您的标签的响应如下所示:

+-------+-------+-------+-------+-------+-------+-------+-------+-------+-------+-------+-...-+--------+-------+-------+-------+-------+
| FLAGS | BSS_0 | BLOCK_DATA_0                  | BSS_1 | BLOCK_DATA_1                  | ... | BSS_18 | BLOCK_DATA_18                 | 
+-------+-------+-------+-------+-------+-------+-------+-------+-------+-------+-------+-...-+--------+-------+-------+-------+-------+

The first byte, the response flags, indicate the overall outcome of the command (e.g. 0x00, as in your case, means success). Due to the Option_flag, each block of data is prepended with a BSS_x byte (the block security status), which seems to be 0x00 for all of the blocks.

Since you don't seem to be interested in the block security status, you might just as well use the command without the Option_flag (flags = 0x20):

byte[] cmd = new byte[]{
        (byte)0x20,                  
        (byte)0x23,                  
        (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00,  // placeholder for tag UID
        (byte)(offset & 0x0ff),      
        (byte)((blocks - 1) & 0x0ff)
};

然后,响应将是:

+-------+-------+-------+-------+-------+-------+-------+-------+-------+-...-+-------+-------+-------+-------+
| FLAGS | BLOCK_DATA_0                  | BLOCK_DATA_1                  | ... | BLOCK_DATA_18                 | 
+-------+-------+-------+-------+-------+-------+-------+-------+-------+-...-+-------+-------+-------+-------+

Consequently, in order to extract the data blocks from the response, you could then use:

response = Arrays.copyOfRange(response, 1, 4 * blocks);

最后,将标签 ID 解码为 UTF-8 对于 ISO/IEC 15693 标签来说根本没有意义。我不确定您期望那里有什么值,但您可能只想将 ID 的字节转换为它们的十六进制表示形式。

关于android - 通过安卓NFC读取ISO15693 RFID标签导致数据输出不正确,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40734601/

相关文章:

android - 以一种聪明的方式根据风格排除 JNI 库

java - 使用 Android 内容的 FileInputStream

java - 如何将实时摄像头图像与图像进行匹配

arrays - 获取一系列产品的 WooCommerce 产品标签

javascript - 等待设备并对网页提供响应

android - 在圆圈中显示带有首字母的联系人姓名

python - 如何在 python 中使用 lxml 去除 xml 标签中的所有子标签,但保留文本合并到 parens?

iphone - 如何获取我正在点击的 UIImageView 的标签?

java - 获取当前 Activity 以处理发现的 NFC 标签

ios - iOS 上的phonegap-nfc 在应用程序下打开“准备扫描”