You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

小米设备NFC调用nfcV.transceive()超13字节报Tag Was Lost问题求助

问题描述

开发一款搭载NFC功能的应用,使用ST25标签。当通过nfcV.transceive()命令发送超过13字节的数据时,小米智能手机会触发“TAG WAS LOST”错误,其他设备可正常运行。错误触发条件为messageBytes.size大于13字节。

相关代码

private fun readTag(intent: Intent) {

    if (NfcAdapter.ACTION_NDEF_DISCOVERED == intent.action
        || NfcAdapter.ACTION_TECH_DISCOVERED == intent.action
        || NfcAdapter.ACTION_TAG_DISCOVERED == intent.action) {
        val tag: Tag? = intent.getParcelableExtra(NfcAdapter.EXTRA_TAG, Tag::class.java)

        if (tag != null)  {
            val st25 = ST25DVTag.get(tag)
            st25?.connect()
            val stringToConvert = etDataToWrite.text.toString()
            val messageBytes = stringToConvert.toByteArray(Charset.forName("UTF-8"))
            try {
                st25.WriteMB(messageBytes.size - 1, messageBytes)
            } catch (e: IOException) {
                e.printStackTrace()
                Toast.makeText(this, "ERROR Write tag NFC: $e",Toast.LENGTH_SHORT).show()
                Log.e("NFC ERROR","OK write tag NFC: $e")
            } finally {
                try {
                    st25.close()
                } catch (e: IOException) {
                    e.printStackTrace()
                }
            }
    }


fun WriteMB(size: Int , data:ByteArray): ByteArray {
    val writecommandLength = 4 + data.size // Calculate total length including data
    val writecommand = ByteArray(writecommandLength)
    // Copy ST25DV_REQUEST_HEADER, 0xCA, IC_MFG_CODE, and size
    System.arraycopy(byteArrayOf(ST25DV_REQUEST_HEADER,0xAA.toByte(),IC_MFG_CODE,size.toByte()),0, writecommand, 0, 4)
    // Copy the data to the end of writecommand
    System.arraycopy(data, 0, writecommand, 4, data.size)
    var lenmax = tag.maxTransceiveLength
    return safeTransceive(writecommand)
}

private fun safeTransceive(command: ByteArray): ByteArray {
    var nTry = 0
    var errorCode = COMMAND_OK
    do {
        val response = tag.transceive(command)
        errorCode = response[0]
        Log.d("Transceive","ErrorCode:"+errorCode)
        if (errorCode == COMMAND_OK)
            return response.copyOfRange(1,response.size)
        else {
            nTry++
            Thread.sleep(COMMAND_DELAY)
        }
    } while (nTry < COMMAND_RETRY)
    throw ST25DVException("IOError: code " + errorCode)
}
解决方案

问题定位

这不一定是小米纯硬件问题,更可能是小米NFC驱动对NFC-V协议的收发长度限制或处理逻辑差异导致的。部分小米机型的NFC驱动在处理超过特定长度的NFC-V指令时,可能存在超时或帧处理错误,误报“TAG WAS LOST”。

具体解决办法

  • 拆分数据分批写入:把超过13字节的数据拆分成多个小数据块,分多次调用写入接口。注意对应ST25标签的地址偏移,确保数据写入到正确的存储位置。
  • 适配maxTransceiveLength:代码中已获取tag.maxTransceiveLength但未实际利用,小米机型的该值可能更小。需要根据这个值动态调整单次发送的指令长度,避免超出设备支持的最大收发字节数。示例逻辑:
    val maxDataLen = tag.maxTransceiveLength - 4 // 减去指令头的4字节
    if (data.size > maxDataLen) {
        // 实现数据拆分、分批写入逻辑
    } else {
        // 直接执行原写入逻辑
    }
    
  • 调整超时与重试策略:在safeTransceive中延长指令间隔时间(Thread.sleep的时长),给小米设备足够的处理时间;同时可以尝试增大重试次数,提升长指令的成功率。
  • 使用ST官方SDK方法:优先使用ST官方提供的ST25DV SDK封装的写入接口,这些方法通常已适配不同机型的兼容性问题,比自定义指令更稳定。

内容的提问来源于stack exchange,提问作者AndersonFw

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.22 04:52:42