DEV Community

Cover image for 🟢 Part 2: Android HCE Implementation — Build a Complete Type 4 NFC Tag with HostApduService
Sushil Kumar Prajapat
Sushil Kumar Prajapat

Posted on

🟢 Part 2: Android HCE Implementation — Build a Complete Type 4 NFC Tag with HostApduService

šŸš€ Introduction

In Part 1 we explored the architecture behind Android Host-Based Card Emulation (HCE), ISO-DEP, and APDU structure. In this Part 2, you will build a complete Android HCE implementation step-by-step using HostApduService, handling SELECT, READ, and response logic to emulate an NFC Type 4 Tag in Kotlin.


šŸ”µ 1. Android HCE Architecture

Reader → NFC Controller → Android OS → HostApduService → Response APDU
Enter fullscreen mode Exit fullscreen mode

šŸ”µ 2. Project Setup

  • Android Studio
  • Min SDK 19+
  • Target SDK 36
  • Kotlin (recommended)
  • Required permissions (uses NFC)
  • Emulator vs physical device note (NFC only works on real devices)

Note: NFC HCE cannot be tested on many emulators — use a physical device with NFC support.


šŸ”µ 3. Create HostApduService

class MyHostApduService : HostApduService() {
 // Status Word on success (used in response)
    private val SUCCESS_SW = byteArrayOf(0x90.toByte(), 0x00.toByte())

    // Status Word in case of failure (used in response)
    private val FAILURE_SW = byteArrayOf(0x6a.toByte(), 0x82.toByte())
    override fun processCommandApdu(
        commandApdu: ByteArray?,
        extras: Bundle?
    ): ByteArray {

        if (commandApdu == null) return FAILURE_SW
        /*This block handles the SELECT command for the NDEF 
          application AID. When the NFC reader selects this AID, we 
          respond with 90 00 (success).*/
        // Match incoming APDU to SELECT Application AID
        if (commandApdu.contentEquals(SELECT_APP)) {
            return SUCCESS_SW
        }
         /*This block handles the SELECT command for the NDEF 
          application Capability Container. 
          When the NFC reader selects this CC, we 
          respond with 90 00 (success).*/
        // Match incoming APDU to SELECT CC File
        if (commandApdu.contentEquals(SELECT_CC)) {
            return SUCCESS_SW
        }

        return FAILURE_SW
    }

    override fun onDeactivated(reason: Int) {}
}
Enter fullscreen mode Exit fullscreen mode

šŸ’  Lifecycle Diagram

how HostApduService methods are called:

Android routes incoming ISO-DEP APDU commands to processCommandApdu() inside your HostApduService, where your logic determines the response.

šŸ’  Flow Chart

Your implementation must follow this sequence to correctly emulate a Type 4 NFC Tag and avoid communication failures.


šŸ”µ 4. apduservice.xml

<host-apdu-service
    android:description="@string/app_name"
    android:requireDeviceUnlock="false">

    <aid-group android:category="other">
        <aid-filter android:name="D2760000850101"/>
    </aid-group>

</host-apdu-service>

Enter fullscreen mode Exit fullscreen mode

šŸ”µ 5. AndroidManifest

<service
    android:name=".MyHostApduService"
    android:permission="android.permission.BIND_NFC_SERVICE"
    android:exported="true">

    <intent-filter>
        <action android:name="android.nfc.cardemulation.action.HOST_APDU_SERVICE"/>
    </intent-filter>

    <meta-data
        android:name="android.nfc.cardemulation.host_apdu_service"
        android:resource="@xml/apduservice"/>
</service>

Enter fullscreen mode Exit fullscreen mode

šŸ”µ 6. Implement CC File Response

When receiving:

CLA = 0x00
INS = 0xB0
Enter fullscreen mode Exit fullscreen mode

Return CC file bytes + 90 00.


šŸ”µ 7. Return NLEN

If LE == 2:

Return:

NLEN + 90 00
Enter fullscreen mode Exit fullscreen mode

šŸ”µ 8. Return NDEF Data

Return:

NLEN + NDEF Message + 90 00
Enter fullscreen mode Exit fullscreen mode

šŸ”µ 9. Security Considerations

HCE is software-based.

Important:

  • Not hardware-secure like Secure Element
  • Encrypt sensitive payload
  • Validate on backend
  • Prevent replay attacks
  • Add timeout/session control

šŸ”µ 10. Full Communication Sequence Diagram

Reader                     Android HCE
  │                              │
  │ --- SELECT AID ------------> │
  │ <--- 90 00 ----------------- │
  │ --- SELECT CC -------------->│
  │ <--- 90 00 ------------------│
  │ --- READ CC ---------------->│
  │ <--- CC DATA + 90 00 ------- │
  │ --- SELECT NDEF ------------>│
  │ <--- 90 00 ------------------│
  │ --- READ NLEN -------------->│
  │ <--- NLEN + 90 00 ---------- │
  │ --- READ NDEF -------------->│
  │ <--- DATA + 90 00 ---------- │

Enter fullscreen mode Exit fullscreen mode

Common Mistakes

  • Forgetting to respond with correct status words
  • Not handling unknown APDU commands
  • Testing only on emulator (HCE requires real NFC hardware)
  • Not validating APDU length before parsing

šŸ Final Thoughts

In this article, we built a complete Android HCE Type 4 Tag implementation using HostApduService and handled the full APDU exchange sequence.

Host-Based Card Emulation allows Android to behave like a Type 4 NFC smart card using:

  • ISO 14443-4
  • ISO 7816-4
  • APDU communication
  • NDEF file structure

With this knowledge, you can build:

  • Access control apps
  • Enterprise NFC solutions
  • Identity systems
  • IoT pairing solutions

If you're building NFC or HCE-based systems and have questions, drop them in the comments — I’d love to discuss and help.

This concludes the 2-part deep dive into Android HCE.

Top comments (0)