React Native NFC Manager仅读取ID和Tech Type,无法读取写入内容求助
排查React Native NFC Manager读取NDEF内容问题
以下是针对你代码的排查和修复步骤:
1. 先确认标签本身有有效NDEF数据
用手机系统自带的NFC工具(比如安卓的「NFC标签读取器」)扫描标签,确认标签内确实存储了可读取的文本/URI等内容。如果系统工具也读不到,那问题出在标签本身,不是代码。
2. 修正代码中的实例大小写问题
你代码里混用了NfcManager和nfcManager,确保是同一个实例:
// 正确导入并使用单例 import NfcManager, { NfcTech } from 'react-native-nfc-manager'; // 后续代码统一用NfcManager try { await NfcManager.requestTechnology(NfcTech.Ndef); const tag = await NfcManager.getTag(); // 这里改成NfcManager,和前面一致 if (tag) { const message = await NfcManager.ndefHandler.getNdefMessage(); const status = await NfcManager.ndefHandler.getNdefStatus(); // 解析NDEF消息成可读内容 const parsedData = parseNdefMessage(message); await db.collection('Tags').add({ tag: tag, rawData: message, // 保留原始数据 parsedData: parsedData, // 存储解析后的可读内容 status: status, }); } } catch (ex) { console.error('NFC读取失败:', ex); } finally { // 必须释放NFC资源,否则下次请求会失败 await NfcManager.cancelTechnologyRequest(); }
3. 解析NDEF原始消息成可读内容
getNdefMessage()返回的是原始二进制结构,需要手动解析成文本/URI等格式,添加这个解析函数:
function parseNdefMessage(message) { if (!message || message.length === 0) return null; return message.map(record => { // 处理文本类型记录(TNF=1, Type=T) if (record.tnf === 1 && record.type?.join('') === 'T') { const langCodeLength = record.payload[0]; const langCode = String.fromCharCode(...record.payload.slice(1, 1 + langCodeLength)); const text = String.fromCharCode(...record.payload.slice(1 + langCodeLength)); return { type: 'Text', content: text, language: langCode }; } // 处理URI类型记录(TNF=1, Type=U) else if (record.tnf === 1 && record.type?.join('') === 'U') { const uriPrefixes = [ 'http://www.', 'https://www.', 'http://', 'https://', 'tel:', 'mailto:', 'ftp://anonymous:anonymous@', 'ftp://ftp.', 'ftps://', 'sftp://', 'smb://', 'nfs://', 'ftp://', 'dav://', 'news:', 'telnet://', 'imap:', 'rtsp://', 'urn:', 'pop:', 'sip:', 'sips:', 'tftp:', 'btspp://', 'btl2cap://', 'btgoep://', 'tcpobex://', 'irdaobex://', 'file://', 'urn:epc:id:', 'urn:epc:tag:', 'urn:epc:pat:', 'urn:epc:raw:', 'urn:epc:', 'urn:nfc:' ]; const prefixIndex = record.payload[0]; const uriSuffix = String.fromCharCode(...record.payload.slice(1)); return { type: 'URI', content: uriPrefixes[prefixIndex] + uriSuffix }; } // 其他类型记录返回原始结构,按需扩展 else { return { type: 'Unknown', payload: record.payload }; } }); }
4. 检查平台权限配置
- 安卓:确保
AndroidManifest.xml包含NFC权限和特性声明:
同时在主Activity中添加NDEF过滤(可选,但能提升识别效率):<uses-permission android:name="android.permission.NFC" /> <uses-feature android:name="android.hardware.nfc" android:required="false" /><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> - iOS:确保
Info.plist添加NFC权限描述和支持的应用ID:<key>NFCReaderUsageDescription</key> <string>需要访问NFC功能读取标签内容</string> <key>com.apple.developer.nfc.readersession.iso7816.select-identifiers</key> <array> <string>A0000002471001</string> <!-- 通用NFC标签应用ID,按需修改 --> </array>
5. 完善错误捕获和资源释放
必须添加catch块捕获读取过程中的错误(比如标签不支持NDEF、读取超时等),并在finally块中调用cancelTechnologyRequest()释放NFC资源,避免后续请求失败。
内容的提问来源于stack exchange,提问作者JS Coder
相关产品推荐
相关产品推荐

