public abstract class HostCardEmulationService
- Object
- HostCardEmulationService
Application-supplied handler for Host Card Emulation (HCE) – the mode where the device acts as a contactless smart card and answers APDUs from a nearby reader/terminal.
Subclass this and register the instance via
Nfc.registerHostCardEmulationService(HostCardEmulationService) before
the OS routes a terminal’s APDU to the app.
Lifecycle
- Reader / POS terminal sends an ISO 7816
SELECTAPDU naming an AID that matchesgetAids(). - OS routes that APDU and every subsequent APDU in the same field session to [#processCommand(byte[])].
- The implementation returns the response (data + 2-byte status word).
Use
ApduResponsehelpers to construct typical responses. onDeactivated(int)fires when the reader leaves the field or routes a SELECT for a different AID.
Platform support
- Android – backed by
android.nfc.cardemulation.HostApduService. The Codename One Maven plugin and BuildDaemon auto-generate theAndroidManifest.xmlservice entry and theapduservice.xmlresource fromgetAids()/getServiceDescription()/getCategory()when an app references this class. - iOS – backed by Core NFC’s
CardSession(iOS 17.4+, EU only as of 2026-05-21) and requires thecom.apple.developer.nfc.hce/com.apple.developer.nfc.hce.iso7816.select-identifiersentitlements. The IPhoneBuilder injects both entitlements when the app references this class. - JavaSE simulator – the Simulate -> NFC menu fires synthetic APDUs at the registered service so the implementation can be exercised without a terminal.
- All other platforms – the OS never invokes the service.
Fields
public static final String CATEGORY_OTHER = "other" | Categories accepted by Android’s HostApduService – “payment” is reserved for EMV-conformant payment apps; everything else uses “other”. |
public static final String CATEGORY_PAYMENT = "payment" | |
public static final int DEACTIVATION_LINK_LOSS = 0 | reason value for onDeactivated(int) – the reader left the field. |
public static final int DEACTIVATION_DESELECTED = 1 | reason value for onDeactivated(int) – the reader sent a SELECT for a different AID. |
Constructors
public HostCardEmulationService() |
Methods
public abstract String[] getAids() | The application identifiers (AIDs) this service is willing to answer. |
public String getCategory() | HCE category – one of CATEGORY_OTHER or CATEGORY_PAYMENT. |
public String getServiceDescription() | Human-readable description registered with Android (shown to the user when they pick a default HCE app in system settings). |
public abstract byte[] processCommand(byte[] apdu) | Handles a single APDU command and returns the response. |
public void onDeactivated(int reason) | Called when the reader leaves the field or sends a SELECT for a different AID. |
Inherited methods
Field details
CATEGORY_OTHER
public static final String CATEGORY_OTHER = "other"HostApduService – “payment” is
reserved for EMV-conformant payment apps; everything else uses
“other”.CATEGORY_PAYMENT
public static final String CATEGORY_PAYMENT = "payment"DEACTIVATION_LINK_LOSS
public static final int DEACTIVATION_LINK_LOSS = 0reason value for onDeactivated(int) – the reader left the
field.DEACTIVATION_DESELECTED
public static final int DEACTIVATION_DESELECTED = 1Constructor details
HostCardEmulationService
public HostCardEmulationService()Method details
getAids
public abstract String[] getAids()The application identifiers (AIDs) this service is willing to answer. Each AID is 5-16 bytes long. Must be non-empty – a service that returns an empty array is never invoked.
The platform routes terminal APDUs to the longest matching AID, so list specific AIDs before catch-alls.
getCategory
public String getCategory()getServiceDescription
public String getServiceDescription()processCommand
public abstract byte[] processCommand(byte[] apdu)Handles a single APDU command and returns the response. Must return
in less than ~500 ms; longer responses are dropped by the
controller. The return value must end with a 2-byte ISO 7816 status
word; see ApduResponse helpers.
The first APDU after activation is always a SELECT for one of the
AIDs reported by getAids(); subsequent APDUs are
application-specific.
onDeactivated
public void onDeactivated(int reason)SELECT for a
different AID. reason is one of DEACTIVATION_LINK_LOSS or
DEACTIVATION_DESELECTED.