为了账号安全,请及时绑定邮箱和手机立即绑定

如何正确写入 MifareUltralight NFC 标签?

如何正确写入 MifareUltralight NFC 标签?

喵喵时光机 2021-06-29 17:57:57
使用该MifareUltralight.writePage()方法的正确方法是什么?查询该getMaxTransceiveLength()方法返回 253 个字节。然而,该标签以 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)
查看完整描述

1 回答

?
温温酱

TA贡献1752条经验 获得超4个赞

MIFARE Ultralight 和 NTAG 标签的内存被组织成每页 4 字节的页面。因此,WRITE 命令 ( MifareUltralight.writePage()) 一次写入 4 个字节。(请注意,READ 命令 ( MifareUltralight.readPages()) 一次读取 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 个字节的数据有效载荷、1 个地址字节和 1 个命令代码字节)。对于 READ 响应,这将是 16 字节的数据负载。的值getMaxTransceiveLength()表示底层库、HAL 和硬件理论上可能的最大收发长度。


查看完整回答
反对 回复 2021-07-07
  • 1 回答
  • 0 关注
  • 390 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信