根据文档,在发生读/写之前,我需要先发送REQA,然后发送SELECT,以防冲突。但是我找不到任何完整的示例代码,执行此操作的代码序列。每个人都从authenticate
中的onTagDiscovered
开始,然后开始读取/写入。
所以我的问题是,1. Android是否在后台自行执行自己的REQA / SEL?2.如果我愿意,如何独自执行REQA和SEL?
我基于代码here提出了一个示例代码
try {
byte[] reqa = new byte[1];
reqa[0] = 0x26;
Log.e(TAG, "Sending REQA: " + bytesToHex(reqa));
mifareTag.transceive(reqa);
Log.e(TAG, bytesToHex(mifareTag.transceive(reqa)));
byte[] sel = new byte[9];
sel[0] = (byte) 0x93;
sel[1] = (byte) 0x70;
System.arraycopy(uid, uid.length - 4, sel, 2, 4);
sel[6] = (byte) (sel[2] ^ sel[3] ^ sel[4] ^ sel[5]);
java.util.zip.CRC32 x = new java.util.zip.CRC32();
x.update(sel);
long crc32 = x.getValue();
sel[7] = (byte) crc32;
sel[8] = (byte) (crc32 >> 8);
Log.e(TAG, "CRC: " + Long.toHexString(crc32));
Log.e(TAG, "Sending SEL: " + bytesToHex(sel));
Log.e(TAG, bytesToHex(mifareTag.transceive(sel)));
if (mifareTag.transceive(cmd) != null) {
Log.e(TAG, "NfcA Tag transcieve:auth success");
return true;
}
} catch (Exception ex) {
Log.e(TAG, "NfcA Tag transcieve:auth failed with exception !", ex);
return false;
}
但是问题是,通过这段代码,我收到的是奇怪的数据。
10-22 11:04:13.465 30687-30734/com.mfreader E/RfidReader: Sending REQA: 26
10-22 11:04:13.492 30687-30734/com.mfreader E/RfidReader: B2007D9BD20804000215671E0D8B811D
10-22 11:04:13.492 30687-30734/com.mfreader E/RfidReader: CRC: a247ff86
10-22 11:04:13.493 30687-30734/com.mfreader E/RfidReader: Sending SEL: 93701A2E7D9BD286FF
10-22 11:04:13.519 30687-30734/com.mfreader E/RfidReader: B2007D9BD20804000215671E0D8B811D
10-22 11:04:13.602 30687-30734/com.mfreader E/RfidReader: NfcA Tag transcieve:auth failed with exception !
java.io.IOException: Transceive failed
at android.nfc.TransceiveResult.getResponseOrThrow(TransceiveResult.java:52)
at android.nfc.tech.BasicTagTechnology.transceive(BasicTagTechnology.java:151)
at android.nfc.tech.NfcA.transceive(NfcA.java:145)
返回的值是Sect#0Block#0
,但前2个字节用UID的B200
代替1A2E
。并且后续的Auth失败,否则只会间歇性失败(这是我要解决的问题!)!
不确定我在做什么错,有帮助吗?
- Android是否在幕后自行执行自己的REQA / SEL?
是
- 如果愿意,我如何自己执行REQA和SEL?
/**
* Send raw NFC-A commands to the tag and receive the response.
*
* <p>Applications must not append the EoD (CRC) to the payload,
* it will be automatically calculated.
* <p>Applications must only send commands that are complete bytes,
* for example a SENS_REQ is not possible (these are used to
* manage tag polling and initialization).
*
* <p>Use {@link #getMaxTransceiveLength} to retrieve the maximum number of bytes
* that can be sent with {@link #transceive}.
*
* <p>This is an I/O operation and will block until complete. It must
* not be called from the main application thread. A blocked call will be canceled with
* {@link IOException} if {@link #close} is called from another thread.
*
* <p class="note">Requires the {@link android.Manifest.permission#NFC} permission.
*
* @param data bytes to send
* @return bytes received in response
* @throws TagLostException if the tag leaves the field
* @throws IOException if there is an I/O failure, or this operation is canceled
*/
public byte[] transceive(byte[] data) throws IOException {
return transceive(data, true);
}
您可以通过方法mifareTag.connect()
选择标签,在从android文档使用android方法进行身份验证后,您可以进行读写。https://developer.android.com/reference/android/nfc/tech/MifareClassic您在文档中找到错误“ B2”的含义是什么?