0

我正在开发一个关于 NFC 写作的应用程序。让我们称之为作家......我正在将数据写入 NfcV 标签。

我要写的字符串是String test = "this is\ta real\ttestcase\tyou tag";

要写入数据,我使用 NfcV 的transceive方法。所以这是我的作家方法:

public static String bytesToHex(byte[] bytes) {
    StringBuilder sb = new StringBuilder(bytes.length * 2);
    Formatter formatter = new Formatter(sb);
    for (byte b : bytes) {
        formatter.format("%02X", b);
    }
    formatter.close();
    return sb.toString();
}

public void write(View v) {
    try {
        String[] tagInfoArray = new String[tagData.size()];
        for (int i = 0; i < tagData.size(); i++)
            tagInfoArray[i] = tagData.get(i).getText().toString();

        String tagInfo = join(tagInfoArray, "\t");
        //String test = "this is\ta real\ttestcase\tyou tag";
        writeTag(tag, tagInfo);
    } catch (NullPointerException e) {
        Toast.makeText(this, "How about providing a tag!",
                Toast.LENGTH_LONG).show();
    } finally {
        write.setBackgroundResource(R.layout.bluebutton);
    }
}

public String join(String[] input, String delim) {
    String output = "";
    if (input.length > 0)
        output += input[0];
    if (input.length > 1)
        for (int i = 1; i < input.length; i++)
            output += delim + input[i];
    return output;
}

public void exitButton(View v) {
    this.foreground.disableForeground();
    System.exit(0);
}

public void writeTag(Tag tag, String data) {
    NfcV myTag = NfcV.get(tag);
    try {
        myTag.connect();
        if (myTag.isConnected()) {
            byte[] info = data.getBytes();
            int dataLength = info.length;
            if (data.length()/4 <= 64){ 
                byte[] args = new byte[15];
                args[0] = 0x20;
                args[1] = 0x21;
                byte[] id = tag.getId();
                for (int o=0; o<8; o++)
                    args[o+2] = id[o];
                for (int i = 0; i<64; i++) {
                    args[10] = (byte) i;
                    args[11] = 0x00;
                    args[12] = 0x00;
                    args[13] = 0x00;
                    args[14] = 0x00;
                    byte[] out = myTag.transceive(args);
                    String out2 = bytesToHex(out);
                    System.out.println("1:.. " + printHex(out2));
                }
                for (int i = 0; i<=dataLength/4; i++) {
                    args[10] = (byte) i;
                    args[11] = getByte(info, (i*4)+0);
                    args[12] = getByte(info, (i*4)+1);
                    args[13] = getByte(info, (i*4)+2);
                    args[14] = getByte(info, (i*4)+3);
                    byte[] out = myTag.transceive(args);
                    String out2 = bytesToHex(out);
                    System.out.println("2:.. " + printHex(out2));
                }
            }
        }
    } catch (IOException e) {
        System.out.println(e.getMessage());
    } finally {
        if (myTag != null) {
            try {
                myTag.close();
            } catch (IOException e) {
                System.out.println(e.getMessage());
            }
        }
    }
}

public static byte getByte(byte[] input, int key){
    try {
        return input[key];
    } catch (Exception e){
        return (byte)0x00;
    }
}

public String printByte(byte[] input){
    try {
        return new String(input, "UTF-8");
    } catch (UnsupportedEncodingException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }
    return "";
}

public String printHex(String input){
    return input;
}

因此,当我写东西时,结果并不是我所期望的。它要么根本不写,要么只是写部分,而不是覆盖之前标签上的内容。

这是输出:

11-05 15:32:33.139: I/System.out(1390): 1:.. 00
11-05 15:32:33.249: I/System.out(1390): 1:.. 00
11-05 15:32:33.349: I/System.out(1390): 1:.. 00
11-05 15:32:33.449: I/System.out(1390): 1:.. 00
11-05 15:32:33.549: I/System.out(1390): 1:.. 00
11-05 15:32:33.649: I/System.out(1390): 1:.. 00 
11-05 15:32:33.759: I/System.out(1390): 1:.. 00
11-05 15:32:33.859: I/System.out(1390): 1:.. 00
11-05 15:32:33.959: I/System.out(1390): 1:.. 00
11-05 15:32:34.059: I/System.out(1390): 1:.. 00
11-05 15:32:34.159: I/System.out(1390): 1:.. 00
11-05 15:32:34.259: I/System.out(1390): 1:.. 00
11-05 15:32:34.359: I/System.out(1390): 1:.. 00
11-05 15:32:34.469: I/System.out(1390): 1:.. 00
11-05 15:32:34.569: I/System.out(1390): 1:.. 00
11-05 15:32:34.669: I/System.out(1390): 1:.. 00
11-05 15:32:34.769: I/System.out(1390): 1:.. 00
11-05 15:32:34.869: I/System.out(1390): 1:.. 00
11-05 15:32:34.979: I/System.out(1390): 1:.. 00
11-05 15:32:35.079: I/System.out(1390): 1:.. 00
11-05 15:32:35.179: I/System.out(1390): 1:.. 00
11-05 15:32:35.289: I/System.out(1390): 1:.. 00
11-05 15:32:35.389: I/System.out(1390): 1:.. 00
11-05 15:32:35.489: I/System.out(1390): 1:.. 00
11-05 15:32:35.589: I/System.out(1390): 1:.. 00
11-05 15:32:35.689: I/System.out(1390): 1:.. 00
11-05 15:32:35.789: I/System.out(1390): 1:.. 00
11-05 15:32:35.889: I/System.out(1390): 1:.. 00
11-05 15:32:35.989: I/System.out(1390): Transceive failed
4

2 回答 2

2

总结初始帖子中的各种问题:

  • 读取或写入超出标签大小的块将导致标签停止响应导致的 IOExceptions。
  • NfcV.getMaxTransceiveLength()返回有关在一个命令/一个响应中可以交换的最大字节数的信息。它不提供有关标签大小的信息!。
  • 不幸的是,没有一种万能的方法来检测标签的实际大小。一种可能的方法是尝试检测标签的类型(许多 NfcV 标签将确切的标签类型编码到它们的 ID 中,因此您可以使用Tag.getId()它来获取 ID 并根据标签制造商的数据表对其进行解析)。另一种方法是读取到第一个 IOException 并从该信息中推断标签大小。您可以稍后重新连接标签以继续读取/写入。但是,请记住,任何其他通信中断(例如用户未正确扫描标签)也可能导致 IOExceptions 并因此可能会伪造您估计的标签大小。
  • ISO/IEC 15693 读/写单块命令的块索引参数以块而不是字节为单位。
于 2013-11-13T12:06:43.957 回答
2

不知道英飞凌科技,但对于 NXP ICODE 和 TI 标签 (ISO15693) 存在该Get System Information命令。我将附上带有响应字节的图像。在此示例中,块数为 0x3F + 1。0x03 + 1 是每个块的字节数。所以 3f=63 和 03=3,总内存 = (63+1)*(3+1) = 256bytes

响应获取系统信息命令

我这样使用它(我正在发送一个寻址命令,命令中包含标签 id,但这不是必需的):

        nfcV = NfcV.get(tag);
        byte[] id = tag.getId();

        if (nfcV != null) {

            byte[] infoCmd = new byte[2 + id.length];
            // set "addressed" flag
            infoCmd[0] = 0x20; 
            // ISO 15693 Get System Information command byte
            infoCmd[1] = 0x2B;
            //adding the tag id
            System.arraycopy(id, 0, infoCmd, 2, id.length); 

            int memoryBlocks = null; 
            try {
                nfcV.connect();
                byte[] data = nfcV.transceive(infoCmd);

                memoryBlocks = Integer.parseInt(String.format("%02X", data[data.length-3]), 16);

            }
            catch (IOException e) {
                e.printStackTrace();
            } 
            finally {
                try {
                    nfcV.close();
                } 
                catch (IOException e) {
                    e.printStackTrace();
                }
            }
于 2015-05-29T08:10:34.483 回答