react native实现RFID(NFC)卡的扇区读写操作

硬件使用的nxp恩智浦的型号(NT3H2111_2211)的nfc板子,协议是ISO/IEC 14443A标准。

使用框架 react-native-nfc-manager

在项目内集成框架后官方按照文档进行对应的配置

直接上代码,ios不支持读取所有扇区,其余功能已经适配,具备的功能有:
Android:读取卡片信息、读取所有扇区、根据某个扇区进行读写操作
IOS:读取卡片信息、根据某个扇区进行读写操作

在产品文档中,读取到命令部分的内容如下,纵而在操作设备过程中需要按照产品文档进行开发
在这里插入图片描述
可以看到,READ的命令是30,WRITE的命令是A2

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

const App = () => {
  const [supported, setSupported] = useState(false);
  const [enabled, setEnabled] = useState(false);
  const [tag, setTag] = useState(null);
  const [sectors, setSectors] = useState([]);
  const [page, setPage] = useState('4'); // 默认页码为4
  const [data, setData] = useState(''); // 数据输入框
  const [readResult, setReadResult] = useState('');

  useEffect(() => {
    async function initNfc() {
      const isSupported = await NfcManager.isSupported();
      setSupported(isSupported);
      if (isSupported) {
        await NfcManager.start();
        const isEnabled = await NfcManager.isEnabled();
        setEnabled(isEnabled);
      }
    }
    initNfc();

    return () => {
      // NfcManager.setEventListener('NfcManagerDiscoverTag', null);
      // NfcManager.close();
    };
  }, []);

  // 读取NFC标签
  const readNfcTag = async () => {
    try {
      await NfcManager.requestTechnology(NfcTech.Ndef);
      const tag = await NfcManager.getTag();
      setTag(tag);
    } catch (ex) {
      console.warn(ex);
    } finally {
      NfcManager.cancelTechnologyRequest();
    }
  };

  // Android读取所有扇区,ios不支持
  const readAllSectors = async () => {
    try {
      await NfcManager.requestTechnology(NfcTech.NfcA);
      const sectorCount = 16; // 根据NFC标签类型调整扇区数量
      let sectorsData = [];
      for (let i = 0; i < sectorCount; i++) {
        let response;
        response = await NfcManager.transceive([0x30, i]); // 0x30 是MIFARE读扇区命令
        // 格式化数据
        const formattedData = formatData(response);
        sectorsData.push({sector: i, data: formattedData});
      }
      setSectors(sectorsData);
    } catch (ex) {
      console.warn(ex);
      Alert.alert('Error', 'Failed to read sectors');
    } finally {
      NfcManager.cancelTechnologyRequest();
    }
  };

  const formatData = data => {
    return data.map(byte => ('00' + byte.toString(16)).slice(-2)).join(' ');
  };

  // Android读取特定页
  async function readPage(page) {
    try {
      await NfcManager.requestTechnology(NfcTech.NfcA);
      const response = await NfcManager.transceive([0x30, page]);
      console.log(`Page ${page} content:`, response);
      const formattedData = formatData(response);
      setReadResult(formattedData);
    } catch (ex) {
      console.warn(ex);
    } finally {
      NfcManager.cancelTechnologyRequest();
    }
  }

  // Android写入特定页
  async function writePage(page, data) {
    try {
      await NfcManager.requestTechnology(NfcTech.NfcA);
      const payload = [0xa2, page, ...data];
      await NfcManager.transceive(payload);
      console.log(`Page ${page} written`);
      Alert.alert(`Page ${page} 写入成功`);
    } catch (ex) {
      console.warn(ex);
    } finally {
      NfcManager.cancelTechnologyRequest();
    }
  }
  // ios写入特定页
  const writeIosNfcTag = async (page, data) => {
    try {
      await NfcManager.requestTechnology([
        NfcTech.NfcA,
        NfcTech.Ndef,
        NfcTech.IsoDep,
      ]);

      const tagData = await NfcManager.getTag();
      if (tagData) {
        console.log('Tag found', tagData);

        // 示例命令,根据标签文档调整
        const command = [0xa2, page, ...data]; // 示例写入命令
        const response = await NfcManager.sendMifareCommandIOS(command);
        console.log('Response:', response);
        Alert.alert(`Page ${page} 写入成功`);
      }
    } catch (ex) {
      console.warn(ex);
    } finally {
      NfcManager.cancelTechnologyRequest();
    }
  };

  // iOS 读取特定页
  const readIosNfcPageTag = async page => {
    try {
      await NfcManager.requestTechnology([
        NfcTech.NfcA,
        NfcTech.Ndef,
        NfcTech.IsoDep,
      ]);
      const tagData = await NfcManager.getTag();
      if (tagData) {
        const command = [0x30, page];
        const response = await NfcManager.sendMifareCommandIOS(command);
        console.log(`Page ${page} content:`, response);
        const formattedData = formatData(response);
        setReadResult(formattedData);
        // const decodedResponse = response
        //   .map(byte => String.fromCharCode(byte))
        //   .join('');
        // console.log('Decoded Response:', decodedResponse);
      }
    } catch (ex) {
      console.warn(ex);
    } finally {
      NfcManager.cancelTechnologyRequest();
    }
  };

  return (
    <View>
      <Text>NFC 是否支持: {supported ? 'Yes' : 'No'}</Text>
      <Text>NFC 已启用: {enabled ? 'Yes' : 'No'}</Text>
      <Text>Tag: {tag ? JSON.stringify(tag) : 'None'}</Text>
      <Button title="Read NFC" onPress={readNfcTag} />
      <Button title="Read All" onPress={readAllSectors} />

      <Text>读取NFC标签特定页</Text>
      <TextInput
        style={{
          height: 40,
          borderColor: 'gray',
          borderWidth: 1,
          marginVertical: 10,
        }}
        placeholder="输入页码"
        value={page}
        onChangeText={setPage}
        keyboardType="numeric"
      />
      <Button
        title="读取页"
        onPress={() =>
          Platform.OS === 'ios'
            ? readIosNfcPageTag(parseInt(page, 10))
            : readPage(parseInt(page, 10))
        }
      />
      <Text>读取结果: {readResult.toString()}</Text>

      <Text>写入NFC标签特定页</Text>
      <TextInput
        style={{
          height: 40,
          borderColor: 'gray',
          borderWidth: 1,
          marginVertical: 10,
        }}
        placeholder="输入数据 (4字节,逗号分隔)"
        value={data}
        onChangeText={setData}
      />
      <Button
        title="写入页"
        onPress={() => {
          const byteArray = data.split(',').map(val => {
            const byte = parseInt(val, 10);
            if (isNaN(byte) || byte < 0 || byte > 255) {
              Alert.alert('Invalid Input', '请确保输入的每个字节在0-255范围内');
              throw new Error('Invalid input');
            }
            return byte;
          });
          if (byteArray.length !== 4) {
            Alert.alert('Invalid Input', '请确保输入4个字节数据');
            return;
          }

          Platform.OS === 'ios'
            ? writeIosNfcTag(parseInt(page, 10), byteArray)
            : writePage(parseInt(page, 10), byteArray);
        }}
      />
      <ScrollView>
        {sectors.map((sector, index) => (
          <View key={index} style={{marginVertical: 10}}>
            <Text>
              Sector {sector.sector}: {sector.data}
            </Text>
          </View>
        ))}
      </ScrollView>
    </View>
  );
};

export default App;

很抱歉,我作为一个语言模型,无法向您提供完整的 React Native 代码。不过,我可以提供一些思路和参考资料。 首先,您需要确保您的 React Native 项目已经安装了 `react-native-nfc-manager` 这个库。在您的项目目录下运行以下命令安装: ``` npm install react-native-nfc-manager --save ``` 接下来,您可以使用以下代码实现 NFC 的读写功能: ```typescript import NfcManager from 'react-native-nfc-manager'; // 初始化NFC管理器 async function initNfcManager() { await NfcManager.start(); } // 停止NFC管理器 async function stopNfcManager() { await NfcManager.stop(); } // 检查设备是否支持NFC async function checkNfcSupport() { const isSupported = await NfcManager.isSupported(); if (!isSupported) { console.log('此设备不支持NFC'); } } // 监听NFC标签 async function startNfcListener() { NfcManager.registerTagEvent( tag => { console.log('发现NFC标签'); console.log(tag); }, { alertMessage: '请触碰NFC标签' }, ); } // 停止监听NFC标签 async function stopNfcListener() { NfcManager.unregisterTagEvent(); } // 写入数据到NFC标签 async function writeDataToNfcTag(bytes: number[]) { const message = NfcManager.Ndef.encodeMessage([NfcManager.Ndef.record(NfcManager.Ndef.TNF_WELL_KNOWN, NfcManager.Ndef.RTD_TEXT, [], bytes)]); await NfcManager.requestTechnology(NfcManager.tech.Ndef, { alertMessage: '请将NFC标签放在手机背面', }); await NfcManager.ndefHandler.writeNdefMessage(message); await NfcManager.cancelTechnologyRequest(); } // 从NFC标签读取数据 async function readDataFromNfcTag() { await NfcManager.requestTechnology(NfcManager.tech.Ndef, { alertMessage: '请将NFC标签放在手机背面', }); const tag = await NfcManager.ndefHandler.getTag(); if (tag) { const message = tag.ndefMessage; if (message && message.length > 0) { const payload = message[0].payload; console.log('NFC标签中的数据:', payload); } } await NfcManager.cancelTechnologyRequest(); } // 主函数 async function handleNfc() { await initNfcManager(); await checkNfcSupport(); await startNfcListener(); await writeDataToNfcTag([1, 2, 3, 4, 5]); await readDataFromNfcTag(); await stopNfcListener(); await stopNfcManager(); } handleNfc(); ``` 以上代码仅供参考,具体实现可根据您的需求进行修改。另外,如果您对 `react-native-nfc-manager` 的使用仍有疑问,可以参考官方文档:https://github.com/whitedogg13/react-native-nfc-manager。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

壮士阿

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值