React-Native NFC标签读取异常求助:红米11无法识别NFC标签
红米11上React-Native NFC读取失败的排查与解决
针对你在红米11上使用 ejected Expo + React-Native 环境,react-native-nfc-manager无法识别NFC标签的问题,可从以下几个方面排查:
一、Android配置补全
完善权限与硬件声明
除了基础NFC权限,需在AndroidManifest.xml中补充NFC硬件支持声明,确保系统知道应用依赖NFC功能:<uses-permission android:name="android.permission.NFC" /> <uses-feature android:name="android.hardware.nfc" android:required="true" />添加Activity的NFC Intent Filter
在主Activity标签内添加NFC相关的Intent Filter,让系统将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> <!-- 处理非NDEF类型的NFC技术 --> <intent-filter> <action android:name="android.nfc.action.TECH_DISCOVERED" /> </intent-filter> <!-- 关联NFC技术过滤配置 --> <meta-data android:name="android.nfc.action.TECH_DISCOVERED" android:resource="@xml/nfc_tech_filter" /> </activity>创建NFC技术过滤文件
在res/xml目录下新建nfc_tech_filter.xml(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> <tech>android.nfc.tech.MifareClassic</tech> <tech>android.nfc.tech.MifareUltralight</tech> </tech-list> </resources>
二、代码逻辑优化
现有代码存在几处可能导致读取失败的问题,调整后的代码如下:
import React, { useEffect, useState } from 'react'; import { View, Text, TouchableOpacity } from 'react-native'; import NfcManager, { NfcTech } from 'react-native-nfc-manager'; const App = () => { const [nfcData, setNfcData] = useState(null); useEffect(() => { NfcManager.start(); return () => { NfcManager.stop(); }; }, []); const startNfcListener = async () => { try { // 请求NDEF技术支持,同时设置提示文案 await NfcManager.requestTechnology(NfcTech.Ndef, { alertMessage: '请将NFC标签靠近设备' }); // 使用官方推荐的registerTagEvent注册监听 const unregister = await NfcManager.registerTagEvent(tag => { console.log('NFC标签数据:', tag); // 将对象转为格式化字符串,避免Text组件显示异常 setNfcData(JSON.stringify(tag, null, 2)); NfcManager.setAlertMessageIOS('NFC标签已识别'); // 读取完成后清理事件与技术请求 unregister(); NfcManager.cancelTechnologyRequest().catch(() => {}); }); } catch (ndefErr) { console.warn('NDEF标签读取失败:', ndefErr); // 降级处理非NDEF格式标签(如Mifare系列) try { await NfcManager.requestTechnology(NfcTech.MifareClassic); const unregister = await NfcManager.registerTagEvent(tag => { console.log('Mifare标签数据:', tag); setNfcData(JSON.stringify(tag, null, 2)); unregister(); NfcManager.cancelTechnologyRequest().catch(() => {}); }); } catch (mifareErr) { console.warn('Mifare标签读取失败:', mifareErr); alert('无法识别该NFC标签类型'); } } }; return ( <View style={{ flex: 1, justifyContent: 'center', alignItems: 'center', padding: 20 }}> <Text style={{ fontSize: 16, marginBottom: 20 }}>NFC读取数据:</Text> <Text style={{ fontSize: 14, color: '#666', textAlign: 'center' }}>{nfcData || '未读取到数据'}</Text> <TouchableOpacity onPress={startNfcListener} style={{ marginTop: 30, padding: 12, backgroundColor: '#2196F3', borderRadius: 8 }}> <Text style={{ color: '#fff', fontSize: 16 }}>启动NFC读取</Text> </TouchableOpacity> </View> ); }; export default App;
代码修改说明:
- 替换
setEventListener为官方推荐的registerTagEvent,确保事件注册逻辑正确 - 读取完成后主动清理事件监听与技术请求,避免残留状态影响后续操作
- 将标签对象转为格式化字符串,解决原代码中
Text组件无法显示对象的问题 - 增加NDEF读取失败后的降级处理,兼容非NDEF格式的常见NFC标签
三、系统与设备检查
- 确认红米11的系统NFC开关已开启(路径:设置-连接与共享-NFC)
- 检查应用的NFC权限是否开启(路径:设置-应用管理-你的应用-权限-NFC)
- 确保测试用NFC标签有效:空白标签需先格式化为NDEF格式;Mifare卡需确认未加密
- 修改配置后重新执行
react-native run-android,确保配置变更已编译生效
内容的提问来源于stack exchange,提问作者Gabriel Geisler
相关产品推荐
相关产品推荐

