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

React Native NFC Manager初始化失败,寻求解决方案

React Native NFC P2P传输:解决NFC Manager未初始化问题

我编写了以下代码,用于通过NFC与另一台支持NFC的手机连接并传输特定号码,但点击「Initiate Sharing」按钮时,始终提示NFC Manager未初始化。已尝试多个相关库但仍未解决,求合适的库或解决方法。

import React, { useEffect } from 'react';
import { View, Text, Button, Alert } from 'react-native';
import { NfcTech } from 'react-native-nfc-manager';
import NfcManager from 'react-native-nfc-manager';

const NFCWriterCom = () => {
  useEffect(() => {
    async function initNfc() {
      try {
        await NfcManager.start();
        console.log('NFC Manager initialized successfully.');

        // Check if NFC Manager is initialized before configuring P2P mode
        if (!NfcManager.isInitialized) {
          console.warn('NFC Manager not initialized.');
          Alert.alert('Error', 'NFC Manager not initialized.');
          return;
        }

        // Configure NFC for P2P mode (Android Beam)
        await configureNfcForP2PMode();

        // Cleanup when the component is unmounted
        return () => {
          NfcManager.stop();
        };
      } catch (ex) {
        console.warn('Error initializing NFC Manager:', ex);
      }
    }

    initNfc();
  }, []);

  async function configureNfcForP2PMode() {
    try {
      // Request NFC P2P technology
      await NfcManager.requestTechnology(NfcTech.Ndef);

      console.log('NFC P2P mode configured.');
    } catch (ex) {
      console.warn('Error configuring NFC for P2P mode:', ex);
      Alert.alert('Error', 'Failed to configure NFC for P2P mode.');
    }
  }

  async function initiateSharing() {
    try {
      // Check if NFC Manager is initialized
      if (!NfcManager.isInitialized) {
        console.warn('NFC Manager not initialized.');
        Alert.alert('Error', 'NFC Manager not initialized.');
        return;
      }
  
      // Check if NFC technology is available
      if (!NfcManager.ndef) {
        console.warn('NFC technology not available.');
        Alert.alert('Error', 'NFC technology not available.');
        return;
      }
  
      // Start NFC P2P sharing with the AFM number
      const afmNumber = '18109603490';
      const ndefMessage = [
        NfcTech.Ndef,
        NfcManager.ndef.textRecord(afmNumber),
      ];
      await NfcManager.setNdefPushMessage(ndefMessage);
  
      console.log('Sharing initiated with AFM number:', afmNumber);
    } catch (ex) {
      console.warn('Error initiating sharing:', ex);
      Alert.alert('Error', 'Failed to initiate sharing.');
    }
  }
  
  return (
    <View>
      <Text> NFC Writer (Phone as Tag) </Text>
      <Button title="Initiate Sharing" onPress={initiateSharing} />
    </View>
  );
};

export default NFCWriterCom;

问题分析

NfcManager.isInitialized 是异步更新的状态,NfcManager.start() 执行完成后可能并未及时同步这个属性值,导致按钮点击时的判断逻辑误报。另外,Android 10及以上版本已弃用Android Beam,若面向新设备需考虑兼容性方案。

解决方法

1. 用组件状态跟踪初始化状态

放弃依赖NfcManager.isInitialized,改用组件内部状态变量记录初始化完成状态:

const [nfcInitialized, setNfcInitialized] = useState(false);

// 在initNfc中设置状态
await NfcManager.start();
console.log('NFC Manager initialized successfully.');
setNfcInitialized(true);

2. 修正NDEF消息构造

setNdefPushMessage 仅需传入NDEF记录数组,不需要包含NfcTech.Ndef:

const ndefMessage = [
  NfcManager.ndef.textRecord(afmNumber),
];
await NfcManager.setNdefPushMessage(ndefMessage);

3. 补充Android权限配置

在AndroidManifest.xml中添加必要权限:

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

4. 兼容性与替代库

  • Android 10+ 不再支持Android Beam,如需跨设备传输可引导用户启用系统自带的Nearby Share,或使用react-native-nearby-api实现类似功能
  • 若react-native-nfc-manager问题较多,可尝试替代库:
    • react-native-nfc:轻量级NFC库,支持基础NDEF操作
    • expo-nfc:Expo生态下的NFC解决方案,配置更简单(仅适用于Expo项目)

完整修正代码

import React, { useEffect, useState } from 'react';
import { View, Text, Button, Alert, StyleSheet } from 'react-native';
import { NfcTech } from 'react-native-nfc-manager';
import NfcManager from 'react-native-nfc-manager';

const NFCWriterCom = () => {
  const [nfcInitialized, setNfcInitialized] = useState(false);

  useEffect(() => {
    async function initNfc() {
      try {
        await NfcManager.start();
        console.log('NFC Manager initialized successfully.');
        setNfcInitialized(true);
        await configureNfcForP2PMode();
      } catch (ex) {
        console.warn('Error initializing NFC Manager:', ex);
        Alert.alert('Error', 'NFC初始化失败');
      }
      return () => {
        NfcManager.stop();
        setNfcInitialized(false);
      };
    }

    initNfc();
  }, []);

  async function configureNfcForP2PMode() {
    try {
      await NfcManager.requestTechnology(NfcTech.Ndef);
      console.log('NFC P2P mode configured.');
    } catch (ex) {
      console.warn('Error configuring NFC for P2P mode:', ex);
      Alert.alert('Error', '配置NFC P2P模式失败');
    }
  }

  async function initiateSharing() {
    try {
      if (!nfcInitialized) {
        Alert.alert('Error', 'NFC Manager未初始化');
        return;
      }

      if (!NfcManager.ndef) {
        Alert.alert('Error', 'NFC技术不可用');
        return;
      }

      const afmNumber = '18109603490';
      const ndefMessage = [
        NfcManager.ndef.textRecord(afmNumber),
      ];
      await NfcManager.setNdefPushMessage(ndefMessage);

      console.log('开始分享AFM号码:', afmNumber);
      Alert.alert('提示', '请将两台手机靠近以完成传输');
    } catch (ex) {
      console.warn('分享启动失败:', ex);
      Alert.alert('Error', '分享启动失败');
    }
  }
  
  return (
    <View style={styles.container}>
      <Text style={styles.title}>NFC Writer (手机模拟标签)</Text>
      <Button title="启动分享" onPress={initiateSharing} />
    </View>
  );
};

const styles = StyleSheet.create({
  container: {
    padding: 20,
    alignItems: 'center',
    justifyContent: 'center',
    flex: 1,
  },
  title: {
    fontSize: 18,
    marginBottom: 20,
  },
});

export default NFCWriterCom;

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.10 08:27:13