Android NFC读写异常:onNewIntent无法获取Tag与Action信息
Android NFC前台调度Intent无有效信息(Action异常、Tag为null)问题排查与解决
问题核心
已实现NFC前台调度逻辑,onNewIntent可正常触发,但Intent的Action状态异常,通过NfcAdapter.EXTRA_TAG获取的Tag对象始终为null。已配置Manifest的NDEF_DISCOVERED IntentFilter、NFC权限,尝试过切换为TAG_DISCOVERED等配置,多设备测试均未解决。
排查与解决方案
1. 前台调度IntentFilter与Manifest配置冲突
前台调度中设置的NfcAdapter.ACTION_NDEF_DISCOVERED IntentFilter,与Manifest中同Action下指定text/plain MIME类型的配置存在匹配歧义,导致系统无法正确传递NFC数据。
两种修正方式:
- 若需接收所有NFC标签事件,直接将
filters设为null:
val pendingIntent = PendingIntent.getActivity(activity, 101, Intent(activity, classType).addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP), PendingIntent.FLAG_IMMUTABLE or PendingIntent.FLAG_UPDATE_CURRENT) val filters: Array<IntentFilter>? = null // 不指定过滤规则,接收所有NFC动作 val techLists = arrayOf(arrayOf(Ndef::class.java.name), arrayOf(NdefFormatable::class.java.name)) nfcAdapter.enableForegroundDispatch(activity, pendingIntent, filters, techLists)
- 若仅需检测
text/plain类型NDEF标签,需为前台调度的IntentFilter补充MIME类型配置:
val nfcIntentFilter = IntentFilter(NfcAdapter.ACTION_NDEF_DISCOVERED) try { nfcIntentFilter.addDataType("text/plain") } catch (e: IntentFilter.MalformedMimeTypeException) { throw RuntimeException("Invalid MIME type", e) } val filters = arrayOf(nfcIntentFilter) // 后续pendingIntent和techLists配置同上,必须添加FLAG_UPDATE_CURRENT
2. PendingIntent缺少FLAG_UPDATE_CURRENT标记
原PendingIntent仅设置FLAG_IMMUTABLE,未添加FLAG_UPDATE_CURRENT,导致新的NFC数据无法更新到Intent中,获取到的始终是旧的空数据。修正后的代码:
val pendingIntent = PendingIntent.getActivity(activity, 101, Intent(activity, classType).addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP), PendingIntent.FLAG_IMMUTABLE or PendingIntent.FLAG_UPDATE_CURRENT)
3. onNewIntent中Tag获取代码变量名错误
原代码中使用it作为Intent对象,但onNewIntent的参数为intent,变量名不匹配导致无法正确获取数据。修正后的获取逻辑:
override fun onNewIntent(intent: Intent) { super.onNewIntent(intent) val action = intent.action val tag = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) { intent.getParcelableExtra(NfcAdapter.EXTRA_TAG, Tag::class.java) } else { @Suppress("DEPRECATION") intent.getParcelableExtra<Tag>(NfcAdapter.EXTRA_TAG) } // 验证Action有效性并处理Tag if (arrayOf(NfcAdapter.ACTION_NDEF_DISCOVERED, NfcAdapter.ACTION_TECH_DISCOVERED, NfcAdapter.ACTION_TAG_DISCOVERED).contains(action)) { tag?.let { // 此处编写Tag处理逻辑 } } }
4. 前台调度需绑定Activity生命周期
确保在Activity的onResume()中启用前台调度,onPause()中禁用,避免后台占用NFC资源:
override fun onResume() { super.onResume() nfcAdapter?.enableForegroundDispatch(this, pendingIntent, filters, techLists) } override fun onPause() { super.onPause() nfcAdapter?.disableForegroundDispatch(this) }
额外检查项
- 确认设备NFC功能已开启,测试标签为有效的NDEF标签或可格式化标签(与
techLists配置匹配) - 可移除Manifest中NFC相关IntentFilter,前台调度优先级高于Manifest配置,保留仅作为后台触发备用即可
内容的提问来源于stack exchange,提问作者Miriana Itani
相关产品推荐
相关产品推荐

