我已经通过低级通信方法实现了与NTAG216交互的代码(遵循NTAG212 Mifare Ultralight with Authentication和NTAG216的数据表)。
writePage()
方法写入代码,也可以使用readPage()
读取代码。但是,在写入页面时,我将NdefMessage
转换为可以读取和写入的字节数组。但是,在其他应用程序中未检测到此NDEF消息。为了能够检测到我从其他应用程序编写的NDEF消息,我需要做些什么?
答案 0 :(得分:4)
NTAG216是NFC论坛类型2标签。因此,在将数据写入此类NFC标签时,您必须遵循NFC论坛Type 2 Tag Operation specification。
因此,您需要遵循一些规则才能将标记作为NDEF标记(类型2标记)发现:
首先,需要配置功能容器(位于块3中)。
0xE1
。0x10
以指示映射版本1.0。0x6D
以指示NTAG216的内存大小。0x00
以指示对NDEF数据的读/写访问权限,或者设置为0x0F
以指示只读访问权限(请注意这些是应用程序层的权限)。 / LI>
因此,您可以将功能容器编写为:
byte[] response = nfc.transceive(new byte[] {
(byte)0xA2, // WRITE
(byte)3, // block address
(byte)0xE1, (byte)0x10, (byte)0x6D, (byte)0x00
});
NTAG216已附带正确配置的功能容器,因此无需手动执行此操作。另请注意,块3是一次性可编程的,这意味着位只能设置为1,但不能再次清零。因此,如果您已使用不同的值覆盖功能容器,则该标记很可能不再用作NDEF标记。
必须将数据写入从块4开始的数据块。必须将NDEF消息包装到NDEF消息TLV(tag-length-value)结构中。此TLV的标记为0x03
。长度可以是单字节格式(对于长度在0到254字节之间的NDEF消息),也可以是三字节格式(对于长度为255或更多字节的NDEF消息)。此TLV块的数据是实际的NDEF消息(您可以从ndefMessage.toByteArray()
获得)。
例如,对于NDEF消息D1 01 0C 55 01 65 78 61 6D 70 6C 65 2E 63 6F 6D 2F
(具有URL“http://www.example.com/”的URI记录),您将获得以下TLV结构:
03 11 D1010C55016578616D706C652E636F6D2F
如果你有更长的NDEF消息(例如一个有259字节的消息),你将使用三字节长度格式:
03 FF0103 D101FF5501...
此外,您应该使用Terminator TLV(标记0xFE
,没有长度和数据字段)标记标记上数据的结尾:
FE
然后,您可以将此数据写入标记:
byte[] ndefMessage = new byte[] {
(byte)0xD1, (byte)0x01, (byte)0x0C, (byte)0x55, (byte)0x01, (byte)0x65, (byte)0x78, (byte)0x61, (byte)0x6D, (byte)0x70, (byte)0x6C, (byte)0x65, (byte)0x2E, (byte)0x63, (byte)0x6F, (byte)0x6D, (byte)0x2F
};
// wrap into TLV structure
byte[] tlvEncodedData = null;
if (ndefMessage.length < 255) {
tlvEncodedData = new byte[ndefMessage.length + 3];
tlvEncodedData[0] = (byte)0x03; // NDEF TLV tag
tlvEncodedData[1] = (byte)(ndefMessage.length & 0x0FF); // NDEF TLV length (1 byte)
System.arraycopy(ndefMessage, 0, tlvEncodedData, 2, ndefMessage.length);
tlvEncodedData[2 + ndefMessage.length] = (byte)0xFE; // Terminator TLV tag
} else {
tlvEncodedData = new byte[ndefMessage.length + 5];
tlvEncodedData[0] = (byte)0x03; // NDEF TLV tag
tlvEncodedData[1] = (byte)0xFF; // NDEF TLV length (3 byte, marker)
tlvEncodedData[2] = (byte)((ndefMessage.length >>> 8) & 0x0FF); // NDEF TLV length (3 byte, hi)
tlvEncodedData[3] = (byte)(ndefMessage.length & 0x0FF); // NDEF TLV length (3 byte, lo)
System.arraycopy(ndefMessage, 0, tlvEncodedData, 4, ndefMessage.length);
tlvEncodedData[4 + ndefMessage.length] = (byte)0xFE; // Terminator TLV tag
}
// fill up with zeros to block boundary:
tlvEncodedData = Arrays.copyOf(tlvEncodedData, (tlvEncodedData.length / 4 + 1) * 4);
for (int i = 0; i < tlvEncodedData.length; i += 4) {
byte[] command = new byte[] {
(byte)0xA2, // WRITE
(byte)((4 + i / 4) & 0x0FF), // block address
0, 0, 0, 0
};
System.arraycopy(tlvEncodedData, i, command, 2, 4);
byte[] response = nfc.transceive(command);
}
最后,请注意,如果您在NDEF数据区域设置了读取密码,则无法将标记用作NDEF标记,因为NFC论坛类型2标记操作规范要求标记可以自由读取。