Java SmartCardIO and JavaFX: NFC On-Tap Functionality or Non-Blocking Waiting for Card Present

82 Views Asked by At

I am trying to accomplish something similar to the post here: Reading events from javax.smartcardio to detect presence of NFC tag, where an action is performed only when an NFC card is tapped to the reader. Ideally, it would be something like:

nfcReader.onTap(()->{
    //do something for that NFC card
})

But the SmartCardIO library doesn't have anything like that.

I've tried using the waitForCardPresent and waitForCardAbsent method (https://docs.oracle.com/javase/8/docs/jre/api/security/smartcardio/spec/javax/smartcardio/CardTerminal.html), which blocks the code until a card is placed/removed, but unfortunately it stops the application while it's waiting. Additionally, I am leveraging a for loop, where unique data is written to each card, and the application is unresponsive until the loop finishes. The logic is as below:

for (String customData : data){
     mPresenter.iSmartCardManager.waitForCardPresent();
    // Write customData to card
    mPresenter.iSmartCardManager.waitForCardAbsent();
}

During the entire time the code above is executing, I am unable to interface with the application. I am using a JavaFX library (leveraging the TapLinx sample application https://www.mifare.net/developer/home/), and the application is unable to have buttons pressed or logs updated in this non-responsive state. This isn't ideal when I have multiple cards that need to be read/written, with logs that need to be updated for each card.

In order to overcome the blocking nature of the waitForCardPresent method, I've tried multiple async options so that the application won't wait on the waitForCardPresent method, from this doc: https://docs.oracle.com/en/java/javase/21/core/virtual-threads.html#GUID-C0FEE349-D998-4C9D-B032-E01D06BE55F2.

Thread thread = Thread.ofVirtual().start(() -> {
    tagPresent = mPresenter.iSmartCardManager.waitForCardPresent();
    });
thread.join();
try (ExecutorService myExecutor =
    Executors.newVirtualThreadPerTaskExecutor()) {
    Future<?> future = myExecutor.submit(() -> {
    tagPresent = mPresenter.iSmartCardManager.waitForCardPresent();
    });
    future.get();
} catch (Exception e) {
    LOG.error("Error in thread", e);
}
Thread t = new Thread(new Runnable() {
    public void run() {
        tagPresent = mPresenter.iSmartCardManager.waitForCardPresent();

    }
    });
t.start();

None of these work, the application still blocks and is unresponsive. Is it possible to have an onTap() method that triggers when an NFC tag is placed on the reader? Or, to have a running for-loop that waits for the card to be placed/removed without causing the application to be unresponsive?

Thanks!

0

There are 0 best solutions below