Sometimes NFC stops working for short period of time
Asked Answered
S

0

0

I am working with NFC smart card. Typically it is 2-8 commands in a row to get some data, perform some actions and get result.

.

So I call NFC activity from fragment using registerForActivityResult() In this NFC Activity I am calling nfcAdapter.enableReaderMode() in onResume() and nfcAdapter.disableReaderMode() in onPause

So after sending a bunch of commands Activity return result to fragment through setResult().

.

Problem is: Sometimes happens that NFC stops discovering tag.

.

Flow is next:

Fragment -> NFCActivity -> tap card to phone -> TAG discovered -> send 5 APDU commands to card and get result -> return result to Fragment to handle

-> then Fragment opens NFCActivity again to send another commands list -> tap card to phone -> NFC TAG is not discovering for 5-20 seconds. (So I need to wait like 10 seconds and tap card again.

.

What can be the problem? Maybe I use tag / isoDep in wrong way? Or maybe NFC can't be used to many times for short period of time?

Thank you!

Code:

    // in activity onResume()
    fun enableReaderMode(activity: NFCCryptoHandlerActivity) {
        nfcAdapter!!.enableReaderMode(
            activity,
            activity,
            NfcAdapter.FLAG_READER_NFC_A or
                    NfcAdapter.FLAG_READER_NFC_B or
                    NfcAdapter.FLAG_READER_NFC_F or
                    NfcAdapter.FLAG_READER_NFC_V or
                    NfcAdapter.FLAG_READER_NFC_BARCODE or
                    NfcAdapter.FLAG_READER_SKIP_NDEF_CHECK or
                    NfcAdapter.FLAG_READER_NO_PLATFORM_SOUNDS,
            Bundle()
        )
    }

    // in activity onPause()
    fun disableReaderMode(activity: NFCCryptoHandlerActivity) {
        nfcAdapter?.disableReaderMode(activity)
    }


    override fun onTagDiscovered(tag: Tag?) {
        [email protected] = tag
        isoDep = IsoDep.get(tag)
        isoDep?.timeout = 200000
    }



    private fun sendCommandArray(apduCommands: List<ApduCommand>) {
        thread {
            try {
                isoDep = IsoDep.get(tag)
                isoDep?.connect()

                if (isoDep!!.isConnected) {
                    apduCommands.forEach { apduCommand ->
                        val result = isoDep?.transceive(apduCommand.bytes)

                        runOnUiThread {
                            // post result in UI 
                        }
                    }
                }
            } catch (e: Exception) { } 
            
            finally {
                try {
                    isoDep?.close();
                } catch (e: Exception) { }
            }
        }
    }


Salian answered 14/4, 2023 at 11:20 Comment(7)
It is always good to send little sized commands. Recommend you not to use commands with more than 100 bytes. It was what I faced on my NFC project.Laura
@AmrahAziz thanks! Actually I do not send commands more than 100 bytes, most of the commands not more than let's say 12-26 bytes. But sometimes it's 70-80 bytesSalian
It has been known for there to be some bugs in some hardware on the frequency of the "presence" checks. Instead of providing a empty Bundle to the enable command, add option to control the frequency of "presence" checks yourself (something like bundle.putInt(NfcAdapter.EXTRA_READER_PRESENCE_CHECK_DELAY, 250); in Java for a 250ms time between "presence" checks)Pampero
The other thought is that you should actively close your connection to the Tag when you have finished handling each Tag detection, e.g. at the end of onTagDiscovered call isoDep?.close() as your long timeout might be blocking new Tag detection.Pampero
@Pampero thank you! Will add EXTRA_READER_PRESENCE_CHECK_DELAY. Actually I do isoDep?.close() right after send all commands. I mean once tag discovered I start sending commands, when last command from array is sent and result received - I'm closing tag.Salian
@Pampero as I understand you have a huge experience working with NFC in Android, maybe you can share your nfc settings like timeout, etc?)Salian
I do less with isoDep but unless you are expecting the Tag to take a long time to respond to your commands I would not bother changing the default timeout.Pampero

© 2022 - 2024 — McMap. All rights reserved.