如何通过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
相关产品推荐
相关产品推荐

