繁体   English   中英

如何从RFID标签读取数据?

[英]How to read data from RFID tag?

我想从 NFCv 标签中读取数据,我尝试了这种方法但没有得到数据。 我在互联网上搜索但没有找到任何读取数据的线索,我使用了另一个播放商店应用程序,告诉我有 128 个块,每个块有 4 个字节,总共有 512 个字节

try {
                        int offset = 0;  // offset of first block to read
                        int blocks = 128;  // number of blocks to read
                        byte[] cmd = new byte[]{
                                (byte)0x60,                  // flags: addressed (= UID field present)
                                (byte)0x23,                  // command: READ MULTIPLE BLOCKS
                                (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00,  // placeholder for tag UID
                                (byte)(offset & 0x0ff),      // first block number
                                (byte)((blocks - 1) & 0x0ff) // number of blocks (-1 as 0x00 means one block)
                        };

                        System.arraycopy(id, 0, cmd, 2, 8);
                        byte[] userdata = nfcvTag.transceive(cmd);

                        userdata = Arrays.copyOfRange(userdata, 0, 32);
                        tagData.setText("DATA:" + bytesToHex(userdata));

这是从 NFCV 标签接收的原始字符串

303330363036422031343530323030383034ffff
ffffffffffffffffffffffff3333303030204120
2046542031353033203030303030393433ffffff
ffffffff32322f30312f323031352d2d31343136
3037ffffffffffffffffffffffffffff752a307c
20dd0aeaffffffffffffffff089cffffffffffff
ffffffffffffffff0000093dffffffffffffffff
ffffffff27130fb60af1ffffffffffffffffffff
8000ffffffffffffffffffffffffffff00fd7d74
ffffffffffffffffffffffff2dcf6030ab0ee1ad
2db36004aadbe17c089f121b20362a7e089d1217
202f2a75ffffffffffffffffffffffffffffffff
ffffffffffffffffffffffffffffffff30303032
3030303600ac9b5300000aca00ac9bb700ac9bc4
00000000fffffffc02dd02de02de02de02dd02dd
02dd02db0000861300000a9c00ac9bff00acb829
00acb82a00acb8330000020dffffffeb03a0039e
039c039d039a039a0397039600008ad300000a51
00002a0800acb83d000000000000000000000000
00009ed500000000000000000000000000007ef9
ffffffffffffffffffffffffffffffffffffffff
ffffffffffffffffffffffffffffffffffffffff
ffffffffffffffff0000391effffffffffffffff
ffffffffffffffffffffffffffffffffffffffff
ffffffffffffffffffffffffffffffffffffffff
ffffffff000136ce2e656e64

Android NFC 堆栈默认支持 NfcV - 因此使用 class NfcV ,它抽象了所有这些 - 而不是处理byte[] ,你可能不明白(否则你不会问)。

bytesToHex()可能对日志记录有用,但要将byte[]解码为String ,那就是:

new String(bytes, StandardCharsets.UTF_8)

NfcV Android class 没有任何高级访问方法,它只有transceive(byte[])方法,因此您使用的是正确的方法并且必须处理字节 ZA3CBC3F9D0CE2F2C1554E1B671D71。

注意添加标签的品牌/型号或链接到它的数据表将有助于理解如何正确读取标签。

但是您没有考虑MaxTransceiveLength ,这可能小于您尝试在 go 中读取的数据量。

数据表还会告诉您 MaxTransceiveLength

我不知道这个标签/NfcV 的最大值,但对于我使用的卡,MaxTransceiveLength 是 253 字节,所以我猜你可能试图在一个 go 中读取太多块,并且卡正在返回它可以返回的最大值。

因此,我对具有类似命令的 NfcA 标签使用如下代码(快速读取)
我无法给出 NfcV 示例,因为我没有数据表来了解确切的命令格式,但为了展示如何考虑 MaxTransceiveLength,这并不相关。
更新以更易于理解的格式添加了日志记录

// Work out how big a fast read we can do (2 bytes for CRC)
int maxTranscieveBytes = mNfcA.getMaxTransceiveLength() - 2;

// Work out how many pages can be fast read
int maxTranscievePages = maxTranscieveBytes / 4;

// Work out how many pages I want to read
int numOfPages = endPage - startPage + 1

while (numOfPages > 0){
// Work out the number of pages to read this time around
      if (numOfPages > maxTranscievePages) {
         readPages = maxTranscievePages;
         // adjust numOfPages left
         numOfPages -= maxTranscievePages;
      } else {
         // Last read
         readPages = numOfPages;
         numOfPages = 0;
      }

      // We can read the right number of pages
      byte[] result = mNfcA.transceive(new byte[] {
             (byte)0x3A,  // FAST_READ
             (byte)(startPage & 0x0ff),
             (byte)((startPage + readPages - 1) & 0x0ff),
      });

      // Adjust startpage for the number of pages read for next time around
      startPage += readPages;

      // Do some result checking

      // Log the data in more understandable format (one block/page per line)
      for(int i = 0; i < (result.length / 4); i++){
          String pageData = new String(result, (i * 4), 4, 
               StandardCharsets.UTF_8 );
          Log.v("NFC", i + "=" + pageData);                  
      }

}

这是我提供的一个解决方案,依次读取每个块并将每个块添加到一个字符串中,最后我有完整的十六进制值和 UTF-8 字符串

if(NfcAdapter.ACTION_TAG_DISCOVERED.equals(action)
                || NfcAdapter.ACTION_TECH_DISCOVERED.equals(action))
        {
            currentTag = intent.getParcelableExtra(NfcAdapter.EXTRA_TAG);
            byte[] id = currentTag.getId();
            StringBuffer buf = new StringBuffer();

            tagId.setText(bytesToHex(id));

            for (String tech : currentTag.getTechList()) {

                if (tech.equals(NfcV.class.getName())) {
                    NfcV nfcvTag = NfcV.get(currentTag);
                    int numberOfBlocks = 0;
                    fullData = new StringBuffer();
                    utf8String = new StringBuffer();
                    blocksData = new ArrayList<String>();
                    while(numberOfBlocks < 128)
                    {
                        try {
                            nfcvTag.connect();
//                        connectTag.setText("Hello NFC!");
                        } catch (IOException e) {
                            Toast.makeText(getApplicationContext(), "Could not open a connection!", Toast.LENGTH_SHORT).show();
                            return;
                        }
                        try {
//
                            byte[] tagUid = currentTag.getId();  // store tag UID for use in addressed commands
//
                            byte[] cmd = new byte[] {
                                    (byte)0x20,  // FLAGS
                                    (byte)0x20,  // READ_SINGLE_BLOCK
                                    0, 0, 0, 0, 0, 0, 0, 0,
                                    (byte)(numberOfBlocks & 0x0ff)
                            };
                            System.arraycopy(tagUid, 0, cmd, 2, 8);  // paste tag UID into command
                            byte[] response = nfcvTag.transceive(cmd);
                            String data =  bytesToHex(response).substring(2);
                            String utf8 = new String(response , "UTF-8");

                            blocksData.add(data.replaceAll(" " , ""));
                            fullData.append(data.replaceAll(" " , ""));
                            utf8String.append(utf8);
                            nfcvTag.close();
                            numberOfBlocks = numberOfBlocks + 1;

                        } catch (IOException e) {
                            Toast.makeText(getApplicationContext(), "An error occurred while reading! :" + e.toString() , Toast.LENGTH_SHORT).show();
                            return;
                        }
                    }

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM