简体   繁体   中英

How to read data from RFID tag?

I want to read data from NFCv tag, I tried this method but didn't get the data. I search on internet but didn't find any clue to read data, I used another play store application that tell me that there are 128 blocks and each block is of 4 bytes, and total there are 512 bytes

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));

This is the raw string which recieve from NFCV tag

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

The Android NFC stack supports NfcV by default - therefore use class NfcV , which abstracts all of that - instead of dealing with byte[] , which you probably don't understand (else you wouldn't ask).

bytesToHex() may be useful for logging, but to decode byte[] to String that's rather:

new String(bytes, StandardCharsets.UTF_8)

The NfcV Android class does not have have any high level access methods it only has transceive(byte[]) method therefore you are using the right method and have to deal with byte arrays.

Note adding the make/model for the tag or link to it's datasheet would help understand how to correctly read the Tag.

But you have not taken in to account the MaxTransceiveLength this might be smaller than the amount of data you are trying to read in one go.

The datahsheet would also tell you the MaxTransceiveLength

I don't know the max value for this Tag / NfcV but for Cards I used the MaxTransceiveLength is 253 bytes so I guess you might be trying to read too many blocks in one go and the card is returning the maximum it can.

Therefore I use code like below for my NfcA tags with similar commands (FAST Read)
I cannot give an NfcV example as I don't have the datasheet to know the exact command format but for showing how to take in to account the MaxTransceiveLength this is not relevant.
Update added Logging in a more understandable format

// 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);                  
      }

}

This is a solution which I come with, Reading each block successively and adding each within a string, and in the last I have complete value of hexadecimal and also UTF-8 String

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;
                        }
                    }

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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