使用MifareUltralight.writePage()
方法的正确方法是什么?
查询getMaxTransceiveLength()
方法将返回253个字节。 tag的广告位为888字节。 transceive()
并因此writePage()
是否应该被多次调用?正在写入的有效负载大小为457字节。
val jsonString = Gson().toJson(casualty)
val casualtyBytes = toBlob(casualty)
var currentPage = PAGE_OFFSET
val pageBytes = ByteArray(MifareUltralight.PAGE_SIZE)
var byteIndex = 0
for(i in 0 until casualtyBytes.size){
pageBytes[byteIndex] = casualtyBytes[i]
byteIndex++
if(byteIndex == 4 || i == (casualtyBytes.size-1)) {
tag.writePage(currentPage, pageBytes)
currentPage++
byteIndex = 0
}
}
fun toBlob(item : Any) : ByteArray{
val bos = ByteArrayOutputStream()
val gzip = GZIPOutputStream(bos) //compress
val oos = ObjectOutputStream(gzip)
oos.writeObject(item)
oos.close()
return bos.toByteArray()
}
例外
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.MifareUltralight.writePage(MifareUltralight.java:193)
at some.package.nfc.NfcCasualtyPublisher.writeToTag(NfcCasualtyPublisher.kt:42)
at some.package.nfc.NfcCasualtyPublisher.access$writeToTag(NfcCasualtyPublisher.kt:11)
at some.package.nfc.NfcCasualtyPublisher$publishCasualty$1.run(NfcCasualtyPublisher.kt:21)
at java.lang.Thread.run(Thread.java:818)
答案 0 :(得分:2)
MIFARE Ultralight和NTAG标签的存储分为4页,每页4个字节。因此,WRITE命令(SomeModel
)一次写入4个字节。 (请注意,READ命令(MifareUltralight.writePage()
)一次读取4页(= 16字节)。
因此,当您要写入NTAG216标签时,需要将数据分成4个字节的块。您似乎已经在代码中使用了for循环来做到这一点(尽管您会遇到一些问题,因为如果数据未按页面对齐,则不会清除最后一页的未使用字节)。
并非MIFARE Ultralight / NTAG标签的所有页面均可自由用于数据存储。仅第4到225页(用于NTAG216)中的用户存储区。前2页(第0和1页)是只读的,并保留给标签序列号。接下来的2页(第2页和第3页)包含一次写入存储器(即曾经被写入1的位不能再次变为0的存储区)。具体来说,第2页中有锁定位(第226页中也有锁定位,但是如果您的数据仅为457字节,则不应该触摸它们)。如果设置了锁定位,则将阻止对部分用户存储器页面的写访问,这将导致“发送失败”异常。因此,如果PAGE_OFFSET的值小于4,则可能通过将数据写入保留的存储区来使标记不可用。
通常,如果您仅打算存储(自由读取)数据,并且不使用标签的其他功能(例如密码保护),则强烈建议您不要使用低级IO访问NFC标签的方法。相反,请坚持使用NDEF抽象层并将数据存储在NDEF记录中。然后,Android将负责将数据放入任何NFC标签上的适当内存位置。
最后,收发长度是一个命令或响应中可以传输的字节数。因此,例如,对于WRITE命令,这总共是6个字节(4个字节的数据有效载荷,一个地址字节和一个命令代码字节)。对于READ响应,这将是16字节的数据有效负载。 MifareUltralight.readPages()
的值表示基础库,HAL和硬件在理论上可能的最大收发长度。