import React, { Component } from 'react'; import { View, Text, Platform, TouchableOpacity, TextInput, ScrollView, } from 'react-native'; import NfcManager, { ByteParser, NfcTech } from 'react-native-nfc-manager'; const KeyTypes = ['A', 'B']; class App extends Component { constructor(props) { super(props); this.state = { supported: false, enabled: false, isDetecting: false, mode: 'read', keyAorB: KeyTypes[1], // 'B' keyToUse: 'FFFFFFFFFFFF', sector: 0, tag: null, sectorCount: null, blocksInSector: null, parsedText: null, firstBlockInSector: null, textToWrite: 'Hello, world!', }; } componentDidMount() { NfcManager.isSupported(NfcTech.MifareClassic).then(supported => { this.setState({ supported }); if (supported) { this._startNfc(); } }); } componentWillUnmount() { if (this._stateChangedSubscription) { this._stateChangedSubscription.remove(); } } render() { let { supported, enabled, isDetecting, keyAorB, keyToUse, sector, tag, sectorCount, blocksInSector, parsedText, firstBlockInSector, textToWrite, } = this.state; return ( {Platform.OS === 'ios' && } {`Is MifareClassic supported ? ${supported}`} {`Is NFC enabled (Android only)? ${enabled}`} {!isDetecting && ( this._startDetection()} > {`CLICK TO START DETECTING ${this.state.mode === 'read' ? 'READ' : 'WRITE'}`} )} {isDetecting && ( this._stopDetection()} > {`CLICK TO STOP DETECTING ${this.state.mode === 'read' ? 'READ' : 'WRITE'}`} )} { this.setState({ tag: null, mode: 'read', sectorCount: null, blocksInSector: null, parsedText: null, firstBlockInSector: null, })} > READ this.setState({ tag: null, mode: 'write', sectorCount: null, blocksInSector: null, parsedText: null, firstBlockInSector: null, })} > WRITE Key to use: {KeyTypes.map(key => ( this.setState({ keyAorB: key })} > Use key {key} ))} Key (hex): this.setState({ keyToUse })} /> Sector (0-15): this.setState({ sector: sector })} /> {this.state.mode !== 'read' && ( Text to write: this.setState({ textToWrite })} /> )} } {`Original tag content:`} {`${ tag ? `${JSON.stringify(tag)} (${sectorCount} sectors)` : '---' }`} {parsedText && ( {`Parsed Text:\n${parsedText}`} )} {firstBlockInSector && ( {`First block in sector:\n${firstBlockInSector} [${blocksInSector} blocks]`} )} Clear above message ); } _startDetection = () => { const cleanUp = () => { this.setState({ isDetecting: false }); NfcManager.closeTechnology(); NfcManager.unregisterTagEvent(); }; const read = () => { return NfcManager.mifareClassicGetBlockCountInSector(parseInt(this.state.sector)) .then(blocksInSector => { this.setState({ blocksInSector }); }) .then(() => NfcManager.mifareClassicReadSector(parseInt(this.state.sector)), ) .then(tag => { let parsedText = ByteParser.byteToHexString(tag); this.setState({ parsedText }); }) .then(() => NfcManager.mifareClassicSectorToBlock(parseInt(this.state.sector)), ) .then(block => NfcManager.mifareClassicReadBlock(block)) .then(data => { const parsedText = ByteParser.byteToString(data); this.setState({ firstBlockInSector: parsedText }); }) }; const write = () => { return NfcManager.mifareClassicSectorToBlock(parseInt(this.state.sector)) .then(block => { // Create 1 block let data = []; for (let i = 0; i < NfcManager.MIFARE_BLOCK_SIZE; i++) { data.push(0); } // Fill the block with our text, but don't exceed the block size for (let i = 0; i < this.state.textToWrite.length && i < NfcManager.MIFARE_BLOCK_SIZE; i++) { data[i] = parseInt(this.state.textToWrite.charCodeAt(i)); } return NfcManager.mifareClassicWriteBlock(block, data); }) .then(read) }; this.setState({ isDetecting: true }); NfcManager.registerTagEvent(tag => console.log(tag)) .then(() => NfcManager.requestTechnology(NfcTech.MifareClassic)) .then(() => NfcManager.getTag()) .then(tag => { this.setState({ tag }); return NfcManager.mifareClassicGetSectorCount(); }) .then(sectorCount => { this.setState({ sectorCount }); }) .then(() => { let sector = parseInt(this.state.sector); if (isNaN(sector)) { this.setState({ sector: '0' }); sector = 0; } // Convert the key to a UInt8Array const key = []; for (let i = 0; i < this.state.keyToUse.length - 1; i += 2) { key.push(parseInt(this.state.keyToUse.substring(i, i + 2), 16)); } if (this.state.keyAorB === KeyTypes[0]) { return NfcManager.mifareClassicAuthenticateA(sector, key); } else { return NfcManager.mifareClassicAuthenticateB(sector, key); } }) .then(() => { return this.state.mode === 'read' ? read() : write() }) .then(cleanUp) .catch(err => { console.warn(err); cleanUp(); }); }; _stopDetection = () => { NfcManager.cancelTechnologyRequest() .then(() => this.setState({ isDetecting: false })) .catch(err => console.warn(err)); }; _startNfc = () => { NfcManager.start() .then(() => NfcManager.isEnabled()) .then(enabled => this.setState({ enabled })) .catch(err => { console.warn(err); this.setState({ enabled: false }); }); }; _clearMessages = () => { this.setState({ tag: null, sectorCount: null, blocksInSector: null, parsedText: null, firstBlockInSector: null, }); }; } export default App;