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

Android NFC标签开发疑问:NFC_READ_COMMAND定义及数据展示

问题描述
  • 身份:NFC领域新手,官方文档理解困难
  • 开发场景:基于Android SDK 32开发NFC学习测试应用,目标是读取NFC标签数据并显示在text_view_nfc组件中
  • 当前问题:
    1. NFC_READ_COMMAND未定义导致编译失败
    2. 不确定如何正确获取并处理NFC标签数据
  • 使用的NFC卡片:西班牙亚马逊在售的普通NFC卡片
解决方案

1. 修复NFC_READ_COMMAND未定义问题

NfcA.transceive()需要传入符合ISO 14443-3A标准的指令字节数组。针对常见的MIFARE Classic类型NFC卡,标准读块指令为0x30 + 目标块地址(字节格式)。示例定义:

// 读取块0的指令,可根据需求修改块地址(MIFARE Classic 1K支持0-63块)
private val NFC_READ_COMMAND = byteArrayOf(0x30.toByte(), 0x00.toByte())

2. 正确读取并处理NFC数据

修改onNewIntent方法,增加异常捕获(NFC操作易触发IO/连接异常),并将字节数据转为可显示字符串:

override fun onNewIntent(intent: Intent?) {
    super.onNewIntent(intent)
    val tagFromIntent: Tag? = intent?.getParcelableExtra(NfcAdapter.EXTRA_TAG)
    tagFromIntent?.let { tag ->
        NfcA.get(tag)?.use { nfcA -> // use语法自动管理连接关闭
            try {
                nfcA.connect()
                val receivedData = nfcA.transceive(byteArrayOf(0x30.toByte(), 0x00.toByte()))
                // 按UTF-8编码转为字符串,可根据卡片实际存储编码调整
                val dataStr = String(receivedData, Charsets.UTF_8)
                text_view_nfc?.text = "读取数据:$dataStr"
            } catch (e: Exception) {
                Log.e("NFC_ERR", "读取失败: ${e.message}")
                text_view_nfc?.text = "读取失败:${e.message}"
            }
        }
    } ?: run {
        text_view_nfc?.text = "未检测到NFC标签"
    }
}

3. 优化前台调度配置

原enableForegroundDispatch仅监听NDEF格式标签,改为兼容所有类型NFC标签的配置:

private fun enableForegroundDispatch(activity: AppCompatActivity, adapter: NfcAdapter?) {
    val intent = Intent(activity.applicationContext, activity.javaClass).apply {
        flags = Intent.FLAG_ACTIVITY_SINGLE_TOP
    }
    // SDK32及以上需指定FLAG_MUTABLE
    val pendingIntent = PendingIntent.getActivity(activity.applicationContext, 0, intent, PendingIntent.FLAG_MUTABLE)
    // 监听所有NFC标签发现事件
    val filters = arrayOf(
        IntentFilter(NfcAdapter.ACTION_TAG_DISCOVERED),
        IntentFilter(NfcAdapter.ACTION_TECH_DISCOVERED),
        IntentFilter(NfcAdapter.ACTION_NDEF_DISCOVERED)
    )
    // 指定支持的NFC技术类型
    val techList = arrayOf(arrayOf(NfcA::class.java.name))
    adapter?.enableForegroundDispatch(activity, pendingIntent, filters, techList)
}

4. 父类代码修复

父类ActividadGestoraDeNFCsBase缺少nfcAdapter初始化逻辑,补充后避免空指针:

override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    nfcAdapter = NfcAdapter.getDefaultAdapter(this) ?: run {
        Toast.makeText(this, "设备不支持NFC", Toast.LENGTH_LONG).show()
        finish()
        return
    }
}
额外注意事项
  • 在AndroidManifest.xml中添加NFC权限:
    <uses-permission android:name="android.permission.NFC" />
    <uses-feature android:name="android.hardware.nfc" android:required="true" />
    
  • 字节转字符串时,需匹配卡片实际存储的编码格式(如ASCII、UTF-16)
  • 若需读取多块数据,循环调用transceive并修改块地址即可

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.07 03:20:38