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

Android Kotlin NFC标签无法被应用读取,请求技术支持

问题分析与解决方案

1. 修正TECH_DISCOVERED的Intent Filter配置

你的AndroidManifest.xml中仅添加了TECH_DISCOVERED的meta-data,但缺少对应的intent-filter声明,导致系统无法将TECH_DISCOVERED的Intent路由到你的Activity。需要补充:

<intent-filter>
    <action android:name="android.nfc.action.TECH_DISCOVERED"/>
    <category android:name="android.intent.category.DEFAULT"/>
</intent-filter>

同时,nfc_tech_filter.xml将多个NFC技术放在同一个<tech-list>下,这要求标签同时支持所有列出的技术才会触发——但NfcA和NfcB是互斥的标准(一个标签只会支持其中一种),所以需要拆分为独立的tech-list:

<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
    <tech-list>
        <tech>android.nfc.tech.Ndef</tech>
    </tech-list>
    <tech-list>
        <tech>android.nfc.tech.NfcA</tech>
    </tech-list>
    <tech-list>
        <tech>android.nfc.tech.NfcB</tech>
    </tech-list>
</resources>

2. 添加TAG_DISCOVERED作为兜底Intent Filter

如果标签不包含NDEF数据,或者数据格式不匹配你的NDEF_DISCOVERED过滤规则,系统会优先调用内置NFC应用。添加TAG_DISCOVERED的Intent Filter可以捕获所有未被更具体规则匹配的NFC标签:

<intent-filter>
    <action android:name="android.nfc.action.TAG_DISCOVERED"/>
    <category android:name="android.intent.category.DEFAULT"/>
</intent-filter>

3. 启用前台调度系统(Foreground Dispatch)

当应用处于前台时,启用前台调度可确保系统优先将NFC Intent发送到你的应用,而非跳转至系统内置功能。在MainActivity中添加以下代码:

override fun onResume() {
    super.onResume()
    nfcAdapter?.let { adapter ->
        val pendingIntent = PendingIntent.getActivity(
            this,
            0,
            Intent(this, javaClass).addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP),
            PendingIntent.FLAG_MUTABLE or PendingIntent.FLAG_UPDATE_CURRENT
        )
        adapter.enableForegroundDispatch(this, pendingIntent, null, null)
    }
}

override fun onPause() {
    super.onPause()
    nfcAdapter?.disableForegroundDispatch(this)
}

注:Android 12及以上需使用PendingIntent.FLAG_MUTABLE(NFC场景通常需要该标记)。

4. 验证标签的NDEF数据格式

你的NDEF_DISCOVERED过滤规则仅匹配text/plain类型的MIME数据,如果标签中的NDEF记录是其他类型(如URI、自定义MIME),则不会触发你的Intent Filter。可通过第三方NFC工具查看标签具体数据格式,调整过滤规则以匹配。

5. 完善Intent处理逻辑

虽然已设置singleTop,但需确保在onCreate中也处理初始Intent(比如应用刚启动时就检测到NFC标签的情况):

override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    binding = ActivityMainBinding.inflate(layoutInflater)
    setContentView(binding.root)
    nfcAdapter = NfcAdapter.getDefaultAdapter(this)
    // 处理启动时的NFC Intent
    handleNfcIntent(intent)
}

override fun onNewIntent(intent: Intent?) {
    super.onNewIntent(intent)
    setIntent(intent) // 更新当前Intent
    handleNfcIntent(intent)
}

private fun handleNfcIntent(intent: Intent?) {
    intent ?: return
    Log.d("CHKI", "NEW NFC DETECTED")

    when (intent.action) {
        NfcAdapter.ACTION_NDEF_DISCOVERED -> Log.d("CHKI", "ACTION_NDEF_DISCOVERED")
        NfcAdapter.ACTION_TECH_DISCOVERED -> Log.d("CHKI", "ACTION_TECH_DISCOVERED")
        NfcAdapter.ACTION_TAG_DISCOVERED -> Log.d("CHKI", "ACTION_TAG_DISCOVERED")
    }
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.03 09:26:16