我有很多NfcA新手问题。 docs和网络上的其他地方似乎对此没有什么指导,所以我希望没有人介意我在这里将一些基本问题拼凑起来...
我正在使用nfcA.transceive()将数据写入NTAG213标签,如下所示:
byte[] result = nfcA.transceive(new byte[] {
(byte)0xA2, // WRITE
(byte)(pageNum & 0x0ff),
myData[0], myData[1], myData[2], myData[3]
});
1.
result
数组是值10的单个字节。这意味着什么,我还应该注意其他什么值?我也使用相同的方法从我的NTAG213标签读取数据:
byte[] result = nfcA.transceive(new byte[] {
(byte)0x30, // READ
(byte)(pageNum & 0x0ff)
});
2. 我希望它返回4个字节的用户数据(即,与我的pageNum对应的4个字节),但是它返回了16个字节。为什么会这样?
3. ,在调用
nfcA.isConnected()
之前检查nfcA.connect()
是一种好习惯吗?如果这样,这样做可能会导致明显的性能损失吗? (我问,因为我已经从两个著名的来源中看到了代码示例。)4. 更好地在
nfcA.setTimeout()
之前或之后调用nfcA.connect()
吗?5. 对于我的NTAG213标签,
nfcA.getMaxTransceiveLength()
返回253。这是否真的意味着我可以一次性写入多达251个字节的用户数据(加上其他2个字节),如果这样,建议这样做还是最好写入每个页面(4个字节)具有单独的nfcA.transceive()
调用? 最佳答案
1. WRITE命令的结果数组是单个字节的值10。这意味着什么?我还应注意其他什么值?
值10(十六进制的Ah或二进制表示的1010b)是一个显式ACK,当不返回任何数据的命令成功执行时,将返回一个确认。
可能的值为实际数据,ACK,被动ACK或NACK。这些由NFC论坛数字协议(protocol)规范和NFC论坛2类标签操作规范定义。
NTAG213/215/216产品数据表对可能的NACK值进行了更详细的说明:
除了上述内容之外,某些设备上的NFC堆栈实现还无法将NACK响应正确传播到应用程序。相反,他们要么抛出
TagLostException
要么返回null
。同样,您可能会获得一个指示被动ACK的TagLostException
。因此,通常将检查以下方法的收发方法的结果(除非发送预期会导致被动ACK的命令):
try {
response = nfca.transceive(command);
if (response == null) {
// either communication to the tag was lost or a NACK was received
} else if ((response.length == 1) && ((response[0] & 0x00A) != 0x00A)) {
// NACK response according to Digital Protocol/T2TOP
} else {
// success: response contains ACK or actual data
}
} catch (TagLostException e) {
// either communication to the tag was lost or a NACK was received
}
2.我期望READ方法返回4个字节的用户数据(即,与我的pageNum对应的4个字节),但是它返回了16个字节。为什么会这样?
定义READ命令以从指定的块编号开始返回4个数据块(在NFC论坛2型标签操作规范中)。因此,如果您发送块4的READ命令,您将获得块4、5、6和7的数据。
3.在调用
nfcA.isConnected()
之前检查nfcA.connect()
是一种好习惯吗?如果是的话,这样做可能会导致明显的性能损失吗?如果您直接从NFC系统服务(通过NFC Intent )接收到
Tag
句柄,则将不会连接标签。因此,除非您在调用Tag
之前使用nfca.connect()
句柄,否则我不明白您为什么要在之前调用nfca.isConnected()
。但是,在连接之前调用该方法几乎没有任何性能开销,因为在fammwork API无需调用NFC系统服务的情况下,将由famework API处理在封闭标签技术对象上调用isConnected()
的情况。因此,在if
对象的 bool 成员变量上,这比简单的NfcA
开销要大得多。4.最好在
nfcA.setTimeout()
之前或之后调用nfcA.connect()
?我不确定那个。但是,收发超时通常在断开标签技术时重置。
5.对于我的NTAG213标签,
nfcA.getMaxTransceiveLength()
返回253。这是否真的意味着我可以一次性写入多达251个字节的用户数据(加上其他2个字节),如果这样,建议还是最好编写每个页面(4个字节)具有单独的nfcA.transceive()
调用?不可以,一次只能写一个块。这受NTAG213的WRITE命令的限制,该命令仅支持一个块作为数据输入。
但是,收发缓冲区的大小为253,使您可以使用FAST_READ命令一次读取多个块(最多可以读取62个块,对于NTAG213最多可以读取45个块):
int firstBlockNum = 0;
int lastBlockNum = 42;
byte[] result = nfcA.transceive(new byte[] {
(byte)0x3A, // FAST_READ
(byte)(firstBlockNum & 0x0ff),
(byte)(lastBlockNum & 0x0ff),
});