【问题标题】:How to read data from RFID tag?如何从RFID标签读取数据?
【发布时间】:2021-04-01 07:28:05
【问题描述】:

我想从 NFCv 标签中读取数据,我尝试了这种方法但没有得到数据。我在网上搜索但没有找到任何读取数据的线索,我使用了另一个 play store 应用程序,告诉我有 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

【问题讨论】:

    标签: java android-studio nfc rfid


    【解决方案1】:

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

    bytesToHex() 可能对日志记录有用,但将byte[] 解码为String 更确切地说:

    new String(bytes, StandardCharsets.UTF_8)
    

    【讨论】:

    • 我已经发布了答案,请检查一下
    【解决方案2】:

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

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

    但是您没有考虑到MaxTransceiveLength 这可能小于您尝试一次性读取的数据量。

    数据表还会告诉您 MaxTransceiveLength

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

    因此,我对具有类似命令(快速读取)的 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);                  
          }
    
    }
    

    【讨论】:

      【解决方案3】:

      这是我自带的解决方案,依次读取每个块并将每个块添加到字符串中,最后我有完整的十六进制值和 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;
                              }
                          }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2015-12-25
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多