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

为何关闭应用后NFC_TAG仍被检测?如何限定仅在指定组件扫描?

解决NFC仅在指定Fragment/Activity中扫描的问题

问题场景

应用当前就算关闭了,还会一直检测NFC标签,想要改成只在特定Fragment或Activity页面里才触发NFC扫描。当前Manifest配置如下:

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools">

    <uses-permission android:name="android.permission.NFC" />
    <uses-feature
        android:name="android.hardware.nfc"
        android:required="true" />

    <application
        android:allowBackup="true"
        android:dataExtractionRules="@xml/data_extraction_rules"
        android:fullBackupContent="@xml/backup_rules"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:roundIcon="@mipmap/ic_launcher_round"
        android:supportsRtl="true"
        android:theme="@style/Theme.Testing"
        tools:targetApi="31">
        <activity
            android:name=".MainActivity"
            android:exported="true"
            android:launchMode="singleTask"
            android:label="@string/app_name">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />
                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
            <intent-filter>
                <action android:name="android.nfc.action.TAG_DISCOVERED" />
                <category android:name="android.intent.category.DEFAULT" />
            </intent-filter>
        </activity>
    </application>

</manifest>

解决方案

1. 删掉Manifest里的NFC静态Intent过滤器

你现在给MainActivity加了TAG_DISCOVERED的静态Intent过滤器,这会让系统一检测到NFC标签就唤醒应用,不管应用有没有在前台运行。第一步得把这个过滤器删掉:

修改后的Activity配置:

<activity
    android:name=".MainActivity"
    android:exported="true"
    android:launchMode="singleTask"
    android:label="@string/app_name">
    <intent-filter>
        <action android:name="android.intent.action.MAIN" />
        <category android:name="android.intent.category.LAUNCHER" />
    </intent-filter>
    <!-- 移除NFC相关的intent-filter -->
</activity>

2. 在目标页面动态注册NFC监听

只在需要NFC扫描的Fragment或Activity里,通过NfcAdapter动态开启和关闭监听,确保只有页面在前台时才检测标签。

举个Fragment的实现例子:

  • 先初始化NFC相关实例:
private var nfcAdapter: NfcAdapter? = null
private var pendingIntent: PendingIntent? = null

override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
    super.onViewCreated(view, savedInstanceState)
    nfcAdapter = NfcAdapter.getDefaultAdapter(requireContext())
    // 创建PendingIntent,检测到标签时会把Intent发送给当前Activity
    pendingIntent = PendingIntent.getActivity(
        requireContext(),
        0,
        Intent(requireContext(), MainActivity::class.java).addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP),
        PendingIntent.FLAG_MUTABLE or PendingIntent.FLAG_UPDATE_CURRENT
    )
}
  • 页面可见时开启监听:
override fun onResume() {
    super.onResume()
    nfcAdapter?.enableForegroundDispatch(requireActivity(), pendingIntent, null, null)
}
  • 页面不可见时关闭监听:
override fun onPause() {
    super.onPause()
    nfcAdapter?.disableForegroundDispatch(requireActivity())
}
  • 处理扫描到的标签数据:
    在宿主Activity的onNewIntent里接收NFC Intent,再传给对应的Fragment:
override fun onNewIntent(intent: Intent?) {
    super.onNewIntent(intent)
    if (NfcAdapter.ACTION_TAG_DISCOVERED == intent?.action) {
        // 找到当前显示的目标Fragment
        val currentFragment = supportFragmentManager.findFragmentById(R.id.fragment_container)
        if (currentFragment is YourTargetNFCFragment) {
            currentFragment.handleNfcTag(intent)
        }
    }
}

然后在目标Fragment里加个方法处理标签内容:

fun handleNfcTag(intent: Intent) {
    val tag = intent.getParcelableExtra<Tag>(NfcAdapter.EXTRA_TAG)
    // 这里写处理标签的逻辑,比如读取NDEF数据等
}

3. 补充说明

  • 动态注册的enableForegroundDispatch只有在当前Activity处于前台时生效,页面退到后台或应用关闭时,监听会自动失效(我们也在onPause里手动注销了),这样就不会在应用关闭时触发NFC检测了。
  • 如果需要过滤特定类型的NFC标签(比如NDEF格式、特定技术类型),可以在enableForegroundDispatch的第三个和第四个参数里设置对应的过滤规则,实现更精准的扫描。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.07 06:50:02