I'm developing payment terminal simulator that acts as a standalone POS terminal. It works ok with chip contactless cards (it can communicate with them on proper protocol), initiate transaction, read data from them etc.
I also wanted to handle transactions done by Google Pay (POS terminals recognize Google Pay as normal contactless card - same protocol). But when I have one Android device with my POS terminal app running, and another Android device with Google Pay, when I touch both devices together, my POS app is minimized and "Touch to send beam" is shown. I would have expected that instead the onNewIntent
method is called in the POS terminal app.
How to handle this? The expected behaviour is that my app (POS terminal) is not minimized, and on the other phone the Google Pay app is triggered.
Should I send something at the begginng, so that Android with Google Pay can recognize that this is a payment transaction? Or maybe some specific intent-filter to handle this on the POS terminal Android device?
I also observed that in one of three to four tries, I seem to get the expected behaviour - onNewIntent
is called in my app. This looks like some race condition beetween my app and the default Android Beam behaviour.
You can't use the regular tag dispatch mechanisms (intent filter or foreground dispatch system) to interact with another Android device that operates in card emulation (HCE) mode. The problem is that the two Android devices will typically automatically discover their peer-to-peer mode capabilities. Hence, they connect in P2P mode and trigger Android Beam (SNEP on top of LLCP on top of P2P). Note that even if you disable Android Beam on both devices, they will still choose P2P mode.
To overcome this, you will need to use the reader mode API. This allows you to disable P2P mode and selectively enable reader/writer mode functionality (e.g. different technologies) while your activity is in the foreground.