为什么我只能显示 NFC 标签 (nDEF) 的前 4 页

Why am I only able to show the first 4 pages from an NFC Tag (nDEF)

我正在尝试访问驻留在 NFC 标签上的信息。我只能从标签内存的前 4 页检索数据。

有关我尝试从 TAG 读取的数据,请参见下面的屏幕截图。

我目前在 LogCat 中得到的回复是重复的:

I/OUTPUT FROM TAG: 1D045ACB I/OUTPUT FROM TAG: 31580000 I/OUTPUT FROM TAG: 69A20000 I/OUTPUT FROM TAG: E1106F00 I/OUTPUT FROM TAG: 1D045ACB I/OUTPUT FROM TAG: 31580000 I/OUTPUT FROM TAG: 69A20000 I/OUTPUT FROM TAG: E1106F00 I/OUTPUT FROM TAG: 1D045ACB I/OUTPUT FROM TAG: 31580000 I/OUTPUT FROM TAG: 69A20000 I/OUTPUT FROM TAG: E1106F00 I/OUTPUT FROM TAG: 1D045ACB I/OUTPUT FROM TAG: 31580000 I/OUTPUT FROM TAG: 69A20000 I/OUTPUT FROM TAG: E1106F00

public class MainActivity extends AppCompatActivity {
    private TextView text;
    private NfcAdapter mNfcAdapter;
    private IntentFilter[] mFilters;
    private String[][] mtechList;
    PendingIntent pendingIntent;
    static final String DATA = "Data";




    private ArrayList<String> readTag;

    @Override
    protected void onRestoreInstanceState(Bundle savedInstanceState) {
        super.onRestoreInstanceState(savedInstanceState);

    }

    @Override
    public void onSaveInstanceState(Bundle outState) {


        super.onSaveInstanceState(outState);

    }


    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        readTag = new ArrayList<>();
        pendingIntent = PendingIntent.getActivity(this, 0, new Intent(this, getClass()).addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP | Intent.FLAG_ACTIVITY_CLEAR_TOP), 0);
        IntentFilter ndef = new IntentFilter(NfcAdapter.ACTION_TECH_DISCOVERED);
        try {
            ndef.addDataType("*/*");
        } catch (IntentFilter.MalformedMimeTypeException e) {

        }
        mNfcAdapter = NfcAdapter.getDefaultAdapter(this);
        mFilters = new IntentFilter[]{ndef};
        mtechList = new String[][]{
                new String[]{Ndef.class.getName()}

        };

        Intent i = getIntent();
        if (i != null) {
            if (i.getAction() == NfcAdapter.ACTION_TECH_DISCOVERED) {

                readTheIntent(i);
            }
        }
    }





    private void readTheIntent(Intent intent) {
        Tag tag = intent.getParcelableExtra(NfcAdapter.EXTRA_TAG);

        String[] techList = tag.getTechList();

        Boolean containsNfcA = Arrays.toString(techList).contains(NfcA.class.getName());

        if (containsNfcA) {
            ArrayList<Byte> result = readNfcATag(tag);
            readTag.clear();

           readTag.addAll(reformatByteStringArray(result));

        }
        for(String s: readTag){
            Log.i("OUTPUT FROM TAG", s);
        }
    }


    //40:BD:32:95:22:D8


    public static ArrayList<String> reformatByteStringArray(ArrayList<Byte> bytelist){
        int tempIndex = 0;

        ArrayList<String> formatedList = new ArrayList<>();

        if(bytelist != null){
            String page = "";

            for(int index = 0; index < bytelist.size(); index ++){

                byte currentByte = bytelist.get(index);
                String formatedString = String.format("%02X", currentByte);
                page = page + formatedString;
                tempIndex++;
                if(tempIndex == 4){
                    tempIndex = 0;
                    formatedList.add(page);
                    page = "";
                }
            }
        }
        return formatedList;
    }



    public static ArrayList<Byte> readNfcATag(Tag tag) {
        ArrayList<Byte> value = null;
        NfcA nfcATag = NfcA.get(tag);





        try {
            nfcATag.connect();

            if (nfcATag != null) {

                int x = 0;
                value = new ArrayList<>();
                byte[] command = new byte[]{0x30 , (byte) x};
                while (nfcATag.transceive(command) != null) {
                    byte[] payload = nfcATag.transceive(command);



                    int index = 0;
                    for (byte b : payload) {
                        value.add(b);
                        index++;
                    }
                    x += 4;
                    //TODO change this to check whether the first 8 elements in list are the same as equal to byte sequence
                    if(x == 16) break;
                }

            }

        } catch (IOException e) {
            Log.e(ReadNFCTagUtil.class.getSimpleName(), "09 " + e.getMessage());
            e.printStackTrace();
        } finally {
            if (nfcATag != null) {
                try {
                    nfcATag.close();
                } catch (IOException ec) {

                }
            }
        }
        return value;
    }






    @Override
    protected void onNewIntent(Intent intent) {
        super.onNewIntent(intent);
        readTheIntent(intent);
    }

    @Override
    protected void onPause() {
        super.onPause();
        mNfcAdapter.disableForegroundDispatch(this);
    }

    @Override
    protected void onResume() {
        super.onResume();
        mNfcAdapter.enableForegroundDispatch(this, pendingIntent, mFilters, mtechList);
    }




}

您使用的是相同的 command,但没有增加右侧焦点中 x 的值。所以你总是阅读相同的前四页。 尝试以下操作:

if (nfcATag != null) {

            int x = 0;
            value = new ArrayList<>();

            while (x<MAXIMUN_SIZE_OF_NDEF_MESSAGE) {
      //chose better condition to break the while, but not in any way your actuall condition.
                byte[] command = new byte[]{0x30 , (byte) x};
                byte[] payload = nfcATag.transceive(command);



                int index = 0;
                for (byte b : payload) {
                    value.add(b);
                    index++;
                }
                x += 4;
                //TODO change this to check whether the first 8 elements in list are the same as equal to byte sequence
            }

        }

另外你需要重构整个代码,它是不可靠的。