public abstract class HostCardEmulationService

  1. Object
  2. 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

  1. Reader / POS terminal sends an ISO 7816 SELECT APDU naming an AID that matches getAids().
  2. OS routes that APDU and every subsequent APDU in the same field session to [#processCommand(byte[])].
  3. The implementation returns the response (data + 2-byte status word). Use ApduResponse helpers to construct typical responses.
  4. 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 the AndroidManifest.xml service entry and the apduservice.xml resource from getAids() / 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 the com.apple.developer.nfc.hce / com.apple.developer.nfc.hce.iso7816.select-identifiers entitlements. 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 = 0reason value for onDeactivated(int) – the reader left the field.
public static final int DEACTIVATION_DESELECTED = 1reason 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"
Categories accepted by Android’s HostApduService – “payment” is reserved for EMV-conformant payment apps; everything else uses “other”.

CATEGORY_PAYMENT

public static final String CATEGORY_PAYMENT = "payment"

DEACTIVATION_DESELECTED

public static final int DEACTIVATION_DESELECTED = 1
reason value for onDeactivated(int) – the reader sent a SELECT for a different AID.

Constructor 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()
HCE category – one of CATEGORY_OTHER or CATEGORY_PAYMENT. Defaults to CATEGORY_OTHER.

getServiceDescription

public String getServiceDescription()
Human-readable description registered with Android (shown to the user when they pick a default HCE app in system settings). Default is the service class’ simple name.

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)
Called when the reader leaves the field or sends a SELECT for a different AID. reason is one of DEACTIVATION_LINK_LOSS or DEACTIVATION_DESELECTED.