无法格式化 NdefFormatable NFC 标签

Cannot format NdefFormatable NFC tag

我正在开发一个使用 NFC 的 Android 应用程序。我有一些具有以下技术列表的 NFC 卡:

但我无法使用 NdefFormatable.format(message) 格式化这些标签。相反,我得到一个 IOException。

代码:

try {
    NdefRecord[] records1 = { createRecord("000000") };
    NdefMessage message1 = new NdefMessage(records1);
    formatable.format(message1);
    res = 1;
}

堆栈跟踪给出了这些日志:

W/System.err: java.io.IOException
W/System.err:     at android.nfc.tech.NdefFormatable.format(NdefFormatable.java:131)
W/System.err:     at android.nfc.tech.NdefFormatable.format(NdefFormatable.java:94)
                  at com.example.peng.nfcreadwrite.MainActivity.write(MainActivity.java:170)
W/System.err:     at com.example.peng.nfcreadwrite.MainActivity.access[=11=]0(MainActivity.java:27)
                  at com.example.peng.nfcreadwrite.MainActivity.onClick(MainActivity.java:60)
                  at android.view.View.performClick(View.java:6877)
W/System.err:     at android.widget.TextView.performClick(TextView.java:12651)
                  at android.view.View$PerformClick.run(View.java:26069)
                  at android.os.Handler.handleCallback(Handler.java:789)
                  at android.os.Handler.dispatchMessage(Handler.java:98)
W/System.err:     at android.os.Looper.loop(Looper.java:164)
                  at android.app.ActivityThread.main(ActivityThread.java:6938)
                  at java.lang.reflect.Method.invoke(Native Method)
W/System.err:     at com.android.internal.os.Zygote$MethodAndArgsCaller.run(Zygote.java:327)
                  at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1374)

也许有人可以给我一些东西来研究,因为我对 Android 上的 NFC 还很陌生。

编辑

这是我使用 Mifare Classic Tool 截取的屏幕截图。它显示扇区 4 到 8 "no keys found(or dead sector)":

Android 上 MIFARE Classic 标签的 NDEF 格式化程序要求标签为空且可使用默认传输密钥 (FFFFFFFFFFFF) 或某些标准密钥 (MAD) 访问(读取和写入)扇区 0 的密钥,其他扇区的 NDEF 密钥)。如果标签的某些扇区不可访问,Android 将无法格式化标签以用于 NDEF。

因此,您的标签无法用于您的目的。尽管您可以手动格式化标签以跳过那些锁定的扇区。我不太确定 Android 是否能够使用这些标签。

您可以使用以下代码读写Mifare Classic

 @Override
protected void onNewIntent(Intent intent) {
    super.onNewIntent(intent);
    if(NfcAdapter.ACTION_NDEF_DISCOVERED.equals(intent.getAction()) || NfcAdapter.ACTION_TAG_DISCOVERED.equals(intent.getAction()) || NfcAdapter.ACTION_TECH_DISCOVERED.equals(intent.getAction())) {

        myTag = intent.getParcelableExtra(NfcAdapter.EXTRA_TAG);
        //  Toast.makeText(this, "MyTag :"+myTag, Toast.LENGTH_SHORT).show();

      
        byte[] tagId = getIntent().getByteArrayExtra(NfcAdapter.EXTRA_ID);
        Toast.makeText(this, "this is Tagid:" + tagId, Toast.LENGTH_SHORT).show();
        NfcSn = Hex.bytesToStringLowercase( tagId );
        System.out.println( "Tag Id"+NfcSn);


        MifareClassic mif = MifareClassic.get(myTag);
        //here is how to authenticate 

        try {
            mif.connect();
            if (mif.isConnected()) {
                boolean isAuthenticated = false;
                if (mif.authenticateSectorWithKeyA(1, MifareClassic.KEY_MIFARE_APPLICATION_DIRECTORY)) {
                    isAuthenticated = true;
                } else if (mif.authenticateSectorWithKeyA(1, MifareClassic.KEY_DEFAULT)) {
                    isAuthenticated = true;
                } else if (mif.authenticateSectorWithKeyA(1, MifareClassic.KEY_NFC_FORUM)) {
                    isAuthenticated = true;
                } else {
                    int block_index = mif.sectorToBlock(1);
                    byte[] block = mif.readBlock(block_index);
                    String s_block = Hex.bytesToStringLowercase( block );
                    System.out.println(s_block);
                }

                int block_index = mif.sectorToBlock(1);
                //here is how to read

                byte[] block = mif.readBlock(block_index);

                String s_block = Hex.bytesToStringLowercase( block );
                byte[] stringByte = hexStringToByteArray(s_block);
                String data = new String(stringByte,"UTF-8");

                System.out.println(data);
                System.out.println(s_block);
             
                System.out.println("is auth :"+isAuthenticated);
                //here is how to write
                mif.writeBlock(mif.sectorToBlock(1), new byte[]{'H', 'a', 'f', 'i', 'z', ' ', 'D', 'a', 'n', 'm', 'a', 'n', 'u', ' ', ' ', ' '});
                mif.close();
           }
        }
        catch (IOException e) {
            e.printStackTrace();
        }

    }


   

    setIntent(intent);
  

}

 public static byte[] hexStringToByteArray(String s) {
     int len = s.length();
     byte[] data = new byte[len / 2];
     for (int i = 0; i < len; i += 2) {
         data[i / 2] = (byte) ((Character.digit(s.charAt(i), 16) << 4)
                 + Character.digit(s.charAt(i+1), 16));
     }
     return data;
 }