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 (2)

Collapse
 
mateusfernandes profile image
Mateus Fernandes

can you share the code?

Collapse
 
shinajr10 profile image
Shina Lasisi Jr

Thank you for the article.....Very Knowledgable