我有一些新手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.结果数组是值为10的单个字节.这意味着什么以及我应该注意哪些其他值?
我也使用相同的方法从我的NTAG213标签读取数据:
byte[] result = nfcA.transceive(new byte[] {
(byte)0x30, // READ
(byte)(pageNum & 0x0ff)
});
2.我希望这能返回4个字节的用户数据(即对应于我的pageNum的4个字节),但它返回16个字节.为什么会这样?
3.在调用nfcA.connect()之前检查nfcA.isConnected()是否是一种好习惯,如果是这样,那么这样做是否会造成严重的性能损失? (我问,因为我看过两个声誉良好的代码示例.)
4.在nfcA.connect()之前或之后调用nfcA.setTimeout()会更好吗?
5.对于我的NTAG213标签,nfcA.getMaxTransceiveLength()返回253.这是否真的意味着我可以一次写入最多251个字节的用户数据(加上另外2个字节),如果是这样,那是可取的还是更好使用单独的nfcA.transceive()调用来编写每个页面(4个字节)?
解决方法:
1. WRITE命令的结果数组是一个值为10的单字节.这是什么意思,我应该注意哪些其他值?
值10(十六进制中的Ah或二进制表示中的1010b)是显式ACK,当不返回数据的命令成功时返回确认.
可能的值是实际数据,ACK,被动ACK或NACK.这些由NFC论坛数字协议规范和NFC论坛类型2标签操作规范定义.
>如果预期命令在成功时返回实际数据,则返回数据而不是显式ACK值.
> ACK定义为4位短帧(有关详细信息,请参阅NFC论坛数字协议规范和ISO / IEC 14443-3),值为1010b(Ah).
>被动ACK被定义为在特定超时内根本不发送响应的标签.
> NACK定义为4位短帧,其值为0x0xb(其中x为0或1).
NTAG213 / 215/216产品数据表对可能的NACK值更加具体:
> 0000b(0h)表示无效的命令参数.
> 0001b(1h)表示奇偶校验或CRC错误.
> 0100b(4h)表示认证计数器溢出无效.
> 0101b(5h)表示EEPROM写入错误.
除了上述之外,某些设备上的NFC堆栈实现不会将NACK响应正确地传播到app.相反,它们要么抛出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.connect()之前检查nfcA.isConnected()是否是一种好习惯,如果是这样,那么这样做是否会造成严重的性能损失?
如果您直接从NFC系统服务(通过NFC意图)收到标签处理,则不会连接标签.因此,除非您在调用nfca.connect()之前使用Tag句柄,否则我不明白为什么您之前要调用nfca.isConnected().但是,在连接之前调用该方法几乎没有任何性能开销,因为在封闭标签上调用isConnected()技术对象将由famework API处理,而无需调用NFC系统服务.因此,与NfcA对象的布尔成员变量相比,它的开销要小得多.
4.在nfcA.connect()之前或之后调用nfcA.setTimeout()会更好吗?
我不确定那一个.但是,通常在断开标签技术时重置收发超时.
5.对于我的NTAG213标签,nfcA.getMaxTransceiveLength()返回253.这是否真的意味着我可以一次写入最多251个字节的用户数据(加上另外2个字节),如果是这样,那是可取的还是更好使用单独的nfcA.transceive()调用来编写每个页面(4个字节)?
不,你一次只能写一个块.这受到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),
});