Android nfcA.connect()、nfcA.transceive()、nfcA.setTimeout() 和 nfcA.getMaxTransceiveLength()
Android nfcA.connect(), nfcA.transceive(), nfcA.setTimeout() and nfcA.getMaxTransceiveLength()
我有一些 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. 我预计这是 return 4 个字节的用户数据(即对应于我的 pageNum 的 4 个字节),但它 returned 16 个字节。为什么会这样?
3. 在调用 nfcA.connect()
之前检查 nfcA.isConnected()
是一种好习惯吗?这样做? (我问,因为我从两者的知名来源中看到了代码示例。)
4.在nfcA.connect()
之前还是之后调用nfcA.setTimeout()
比较好?
5. For my NTAG213 tags nfcA.getMaxTransceiveLength()
returns 253. 这真的意味着我最多可以写入 251 字节的用户数据(加上其他 2 个字节)一次,如果是这样,建议还是最好用单独的 nfcA.transceive()
调用写入每个页面(4 个字节)?
1。 WRITE 命令的结果数组是一个值为 10 的字节。这是什么意思,我应该注意哪些其他值?
值 10(十六进制的 Ah 或二进制表示的 1010b)是显式 ACK,当 return 没有数据的命令成功时,return 确认。
可能的值为实际数据、ACK、被动 ACK 或 NACK。这些由 NFC 论坛数字协议规范和 NFC 论坛 2 类标签操作规范定义。
- 如果命令在成功时预期 return 实际数据,则数据 returned 而不是显式 ACK 值。
- ACK 被定义为一个 4 位短帧(参见 NFC 论坛数字协议规范和 ISO/IEC 14443-3 以获取更多详细信息),值为 1010b (Ah)。
- 被动 ACK 定义为标签在特定超时时间内根本不发送响应。
- NACK 定义为值为 0x0xb(其中 x 为 0 或 1)的 4 位短帧。
NTAG213/215/216 产品数据 sheet 在可能的 NACK 值上更具体一些:
- 0000b (0h) 表示命令参数无效。
- 0001b (1h) 表示奇偶校验或 CRC 错误。
- 0100b (4h) 表示无效的身份验证计数器溢出。
- 0101b (5h) 表示 EEPROM 写入错误。
除上述之外,某些 设备上的 NFC 堆栈实现无法正确地将 NACK 响应传播到应用程序。相反,他们要么抛出 TagLostException
或 return null
。同样,您可能(?)得到一个 TagLostException
指示被动 ACK。
因此,您通常会检查以下收发方法的结果(除非您发送的命令预计会导致被动 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 方法能够 return 4 个字节的用户数据(即对应于我的 pageNum 的 4 个字节),但它 returned 16 个字节。为什么会这样?
READ 命令被定义为 return 4 个以指定块号开始的数据块(在 NFC 论坛类型 2 标签操作规范中)。因此,如果您为块 4 发送 READ 命令,您将获得块 4、5、6 和 7 的数据。
3。在调用 nfcA.connect()
之前检查 nfcA.isConnected()
是一种好习惯吗?如果是这样,这样做是否会造成任何重大的性能损失?
如果您直接从 NFC 系统服务(通过 NFC 意图)收到 Tag
句柄,则不会连接标签。因此,除非您在调用 nfca.connect()
之前使用 Tag
句柄,否则我不明白您为什么要先调用 nfca.isConnected()
。然而,在连接之前调用该方法几乎没有任何性能开销,因为在关闭标签技术对象上调用 isConnected()
将由 famework API 处理,而无需调用 NFC 系统服务。因此,它并不比 NfcA
对象的布尔成员变量上的简单 if
多多少开销。
4。在nfcA.connect()
之前或之后调用nfcA.setTimeout()
更好吗?
我不确定那个。但是,收发超时通常会在断开标签技术时重置。
5。对于我的 NTAG213 标签 nfcA.getMaxTransceiveLength()
returns 253。这是否真的意味着我可以一次写入最多 251 个字节的用户数据(加上其他 2 个字节),如果是这样,是否可取或用单独的 nfcA.transceive()
调用写入每个页面(4 字节)是否更好?
不可以,一次只能写一个块。这个受限于NTAG213的WRITE命令,只支持一个block作为数据输入。
但是,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),
});
我有一些 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. 我预计这是 return 4 个字节的用户数据(即对应于我的 pageNum 的 4 个字节),但它 returned 16 个字节。为什么会这样?
3. 在调用 nfcA.connect()
之前检查 nfcA.isConnected()
是一种好习惯吗?这样做? (我问,因为我从两者的知名来源中看到了代码示例。)
4.在nfcA.connect()
之前还是之后调用nfcA.setTimeout()
比较好?
5. For my NTAG213 tags nfcA.getMaxTransceiveLength()
returns 253. 这真的意味着我最多可以写入 251 字节的用户数据(加上其他 2 个字节)一次,如果是这样,建议还是最好用单独的 nfcA.transceive()
调用写入每个页面(4 个字节)?
1。 WRITE 命令的结果数组是一个值为 10 的字节。这是什么意思,我应该注意哪些其他值?
值 10(十六进制的 Ah 或二进制表示的 1010b)是显式 ACK,当 return 没有数据的命令成功时,return 确认。
可能的值为实际数据、ACK、被动 ACK 或 NACK。这些由 NFC 论坛数字协议规范和 NFC 论坛 2 类标签操作规范定义。
- 如果命令在成功时预期 return 实际数据,则数据 returned 而不是显式 ACK 值。
- ACK 被定义为一个 4 位短帧(参见 NFC 论坛数字协议规范和 ISO/IEC 14443-3 以获取更多详细信息),值为 1010b (Ah)。
- 被动 ACK 定义为标签在特定超时时间内根本不发送响应。
- NACK 定义为值为 0x0xb(其中 x 为 0 或 1)的 4 位短帧。
NTAG213/215/216 产品数据 sheet 在可能的 NACK 值上更具体一些:
- 0000b (0h) 表示命令参数无效。
- 0001b (1h) 表示奇偶校验或 CRC 错误。
- 0100b (4h) 表示无效的身份验证计数器溢出。
- 0101b (5h) 表示 EEPROM 写入错误。
除上述之外,某些 设备上的 NFC 堆栈实现无法正确地将 NACK 响应传播到应用程序。相反,他们要么抛出 TagLostException
或 return null
。同样,您可能(?)得到一个 TagLostException
指示被动 ACK。
因此,您通常会检查以下收发方法的结果(除非您发送的命令预计会导致被动 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 方法能够 return 4 个字节的用户数据(即对应于我的 pageNum 的 4 个字节),但它 returned 16 个字节。为什么会这样?
READ 命令被定义为 return 4 个以指定块号开始的数据块(在 NFC 论坛类型 2 标签操作规范中)。因此,如果您为块 4 发送 READ 命令,您将获得块 4、5、6 和 7 的数据。
3。在调用 nfcA.connect()
之前检查 nfcA.isConnected()
是一种好习惯吗?如果是这样,这样做是否会造成任何重大的性能损失?
如果您直接从 NFC 系统服务(通过 NFC 意图)收到 Tag
句柄,则不会连接标签。因此,除非您在调用 nfca.connect()
之前使用 Tag
句柄,否则我不明白您为什么要先调用 nfca.isConnected()
。然而,在连接之前调用该方法几乎没有任何性能开销,因为在关闭标签技术对象上调用 isConnected()
将由 famework API 处理,而无需调用 NFC 系统服务。因此,它并不比 NfcA
对象的布尔成员变量上的简单 if
多多少开销。
4。在nfcA.connect()
之前或之后调用nfcA.setTimeout()
更好吗?
我不确定那个。但是,收发超时通常会在断开标签技术时重置。
5。对于我的 NTAG213 标签 nfcA.getMaxTransceiveLength()
returns 253。这是否真的意味着我可以一次写入最多 251 个字节的用户数据(加上其他 2 个字节),如果是这样,是否可取或用单独的 nfcA.transceive()
调用写入每个页面(4 字节)是否更好?
不可以,一次只能写一个块。这个受限于NTAG213的WRITE命令,只支持一个block作为数据输入。
但是,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),
});