revtel / react-native-nfc-manager

React Native NFC module for Android & iOS
MIT License
1.33k stars 317 forks source link

[Question] How to use Tech Ndef and NfcA together on Android #661

Closed moony-chen closed 11 months ago

moony-chen commented 11 months ago

Hello there,

We have a NXP Ntag215, and we'd like to:

  1. Write a ndef to it
  2. then write some data to certain pages

My code is something like this:

<Button
        title="Android techs test"
        onPress={async () => {
          try {
            await NfcManager.requestTechnology([NfcTech.Ndef, NfcTech.NfcA]);

            const tag = await NfcManager.getTag();
            console.log(tag?.id);
            const ndefbytes = Ndef.encodeMessage([Ndef.textRecord('test ndef')]);

            await NfcManager.ndefHandler.writeNdefMessage(ndefbytes);
            console.log('write ndef ok!');

            await NfcManager.nfcAHandler.transceive([0xa2, 0x12, 0x32, 0x33, 0x33, 0x34]);
            console.log('write memory ok!');

          } catch (ex) {
            console.warn('Oops!', ex);
            throw ex;
          } finally {
            await NfcManager.cancelTechnologyRequest();
          }

        }}></Button>

This I got Error: unsupported tag api If I switch the order in requestTechnology, then I got Error: java.lang.ClassCastException: android.nfc.tech.NfcA cannot be cast to android.nfc.tech.Ndef

Seems I cannot use them together, any advice to make this work?

Thank you!

victorcorreae commented 11 months ago

Having the same issue. I wanted to add password block for safety.

await NfcManager.requestTechnology(NfcTech.Ndef, { alertMessage: gettext('Pronto per scrivere NFC!') });

const bytes = Ndef.encodeMessage([Ndef.textRecord(info.id)]);

if (bytes) {
    await NfcManager.nfcAHandler.transceive([0x1b, ...password]);

    await NfcManager.ndefHandler.writeNdefMessage(bytes);

    if (Platform.OS === 'ios') {
        await NfcManager.setAlertMessageIOS(gettext('Tag scritta correttamente!'));
    }
}
moony-chen commented 11 months ago

By comparing a working native android example, I found a workaround by adding below code between the use of ndefHandler and nfcAHandler

if (isAndroid) {
  await (NfcManager as any).close();
  await (NfcManager as any).connect([NfcTech.NfcA]);
}

However, this works only if reader mode is enabled. For the default foreground dispatch mode, I have to patch the NfcManager.java file:

private WritableMap parseNfcIntent(Intent intent) {
        ...
        Tag tag = intent.getParcelableExtra(NfcAdapter.EXTRA_TAG);
        ...
        synchronized(this) {
            this.tag = tag;   <--- add this line
            if (writeNdefRequest != null) {
whitedogg13 commented 11 months ago

Hi @moony-chen #662 has been merged and included in latest release v3.14.8, thanks for the contribution!