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

如何通过Flutter或Kotlin编程检测设备NFC标签(无需额外阅读器)

无需额外阅读器检测NFC标签的实现方案

完全可行——只要目标Android设备内置NFC模块(目前绝大多数主流Android设备都具备此硬件),无需外接额外阅读器即可检测并交互NFC标签。以下分别提供Flutter端基于nfc_manager包的实现,以及Android原生Kotlin的实现方案:

一、Flutter 端使用 nfc_manager 包实现

1. 配置Android权限与清单

首先在android/app/src/main/AndroidManifest.xml中添加NFC相关配置:

<!-- 声明NFC权限 -->
<uses-permission android:name="android.permission.NFC" />
<!-- 声明设备需要NFC硬件 -->
<uses-feature android:name="android.hardware.nfc" android:required="true" />

<!-- 在主Activity中添加NFC意图过滤器 -->
<activity android:name=".MainActivity">
    <!-- 监听NDEF格式标签 -->
    <intent-filter>
        <action android:name="android.nfc.action.NDEF_DISCOVERED" />
        <category android:name="android.intent.category.DEFAULT" />
        <data android:mimeType="text/plain" /> <!-- 根据标签类型调整MIME类型 -->
    </intent-filter>
    <!-- 监听特定NFC技术类型的标签 -->
    <intent-filter>
        <action android:name="android.nfc.action.TECH_DISCOVERED" />
    </intent-filter>
    <meta-data 
        android:name="android.nfc.action.TECH_DISCOVERED"
        android:resource="@xml/nfc_tech_filter" />
</activity>

接着在android/app/src/main/res/xml目录下创建nfc_tech_filter.xml文件,定义支持的NFC技术类型:

<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
    <tech-list>
        <tech>android.nfc.tech.Ndef</tech>
        <tech>android.nfc.tech.NdefFormatable</tech>
        <!-- 按需添加其他技术类型,比如MifareClassic等 -->
    </tech-list>
</resources>

2. Flutter核心代码实现

在Flutter代码中初始化NFC管理器并监听标签:

import 'package:nfc_manager/nfc_manager.dart';

void initNfcDetection() async {
    // 检查设备是否支持NFC
    bool nfcAvailable = await NfcManager.instance.isAvailable();
    if (!nfcAvailable) {
        // 提示用户设备不支持NFC
        return;
    }

    // 请求NFC权限(Android 12+需动态申请)
    bool hasPermission = await NfcManager.instance.requestPermission();
    if (!hasPermission) {
        // 引导用户前往设置授予权限
        return;
    }

    // 启动NFC会话,监听标签发现事件
    NfcManager.instance.startSession(
        onDiscovered: (NfcTag tag) async {
            // 解析NDEF格式标签
            Ndef? ndefTag = Ndef.from(tag);
            if (ndefTag != null) {
                NdefMessage? message = ndefTag.cachedMessage;
                if (message != null) {
                    for (NdefRecord record in message.records) {
                        // 读取标签内容
                        String content = String.fromCharCodes(record.payload);
                        // 这里处理读取到的内容,比如展示给用户
                    }
                }
            }
            // 结束会话,避免重复触发检测
            NfcManager.instance.stopSession();
        },
    );
}

二、Android原生(Kotlin)实现

如果需要更底层的NFC控制逻辑,可以直接用Kotlin编写原生代码:

1. 清单配置(同Flutter端的AndroidManifest配置)

2. Kotlin核心代码

import android.nfc.NfcAdapter
import android.nfc.Tag
import android.nfc.tech.Ndef
import android.content.Intent
import android.app.PendingIntent
import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle

class NfcScanActivity : AppCompatActivity() {
    private var nfcAdapter: NfcAdapter? = null

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_nfc_scan)

        // 获取系统NFC适配器
        nfcAdapter = NfcAdapter.getDefaultAdapter(this)
        nfcAdapter ?: run {
            // 提示设备不支持NFC
            return
        }
    }

    override fun onResume() {
        super.onResume()
        // 开启前台NFC调度,确保应用在前台时能捕获NFC事件
        nfcAdapter?.enableForegroundDispatch(
            this,
            PendingIntent.getActivity(
                this,
                0,
                Intent(this, javaClass).addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP),
                PendingIntent.FLAG_MUTABLE
            ),
            arrayOf(
                IntentFilter(NfcAdapter.ACTION_NDEF_DISCOVERED).apply {
                    addCategory(Intent.CATEGORY_DEFAULT)
                    try {
                        addDataType("text/plain")
                    } catch (e: IntentFilter.MalformedMimeTypeException) {
                        e.printStackTrace()
                    }
                },
                IntentFilter(NfcAdapter.ACTION_TECH_DISCOVERED)
            ),
            arrayOf(arrayOf(Ndef::class.java.name))
        )
    }

    override fun onPause() {
        super.onPause()
        // 关闭前台调度,避免后台占用资源
        nfcAdapter?.disableForegroundDispatch(this)
    }

    override fun onNewIntent(intent: Intent?) {
        super.onNewIntent(intent)
        intent?.let {
            when (it.action) {
                NfcAdapter.ACTION_NDEF_DISCOVERED, NfcAdapter.ACTION_TECH_DISCOVERED -> {
                    val tag = it.getParcelableExtra<Tag>(NfcAdapter.EXTRA_TAG)
                    tag?.let { scannedTag ->
                        // 读取NDEF标签内容
                        val ndef = Ndef.get(scannedTag)
                        ndef?.run {
                            connect()
                            cachedNdefMessage?.records?.forEach { record ->
                                val content = String(record.payload)
                                // 处理读取到的标签内容
                            }
                            close()
                        }
                    }
                }
            }
        }
    }
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.08 02:28:28