Skip to main content

Requirements

  • minSdkVersion 23 or higher
  • Android device with NFC hardware

1. App-Level build.gradle

Open android/app/build.gradle and add the following inside the android {} block and under dependencies:
android/app/build.gradle
android {
    defaultConfig {
        minSdkVersion 23       // Required for Keychain & NFC APIs
        // ...
    }
}

dependencies {
    // Required by react-native-keychain v8
    implementation "androidx.datastore:datastore-core:1.0.0"
    implementation "androidx.datastore:datastore-preferences:1.0.0"
    implementation "androidx.datastore:datastore-preferences-core:1.0.0"

    // Fix Kotlin stdlib version conflicts
    configurations.all {
        resolutionStrategy {
            force "org.jetbrains.kotlin:kotlin-stdlib:1.8.0"
            force "org.jetbrains.kotlin:kotlin-stdlib-jdk7:1.8.0"
            force "org.jetbrains.kotlin:kotlin-stdlib-jdk8:1.8.0"
        }
    }
}

2. Project-Level build.gradle

Open android/build.gradle and ensure Kotlin is configured in the buildscript block:
android/build.gradle
buildscript {
    ext {
        kotlinVersion = "1.8.0"
    }
    dependencies {
        classpath("org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlinVersion")
    }
}

3. AndroidManifest.xml — Permissions & HCE Service

Open android/app/src/main/AndroidManifest.xml and add the NFC permissions and the HCE card service:
android/app/src/main/AndroidManifest.xml
<manifest xmlns:android="http://schemas.android.com/apk/res/android">

  <!-- NFC Permissions -->
  <uses-permission android:name="android.permission.NFC" />
  <uses-feature android:name="android.hardware.nfc" android:required="true" />
  <uses-feature android:name="android.hardware.nfc.hce" android:required="true" />

  <application ...>

    <!-- TapRails HCE Service (merchant NFC emulation) -->
    <service
      android:name="com.reactnativehce.services.CardService"
      android:exported="true"
      android:enabled="false"
      android:permission="android.permission.BIND_NFC_SERVICE">
      <intent-filter>
        <action android:name="android.nfc.cardemulation.action.HOST_APDU_SERVICE" />
        <category android:name="android.intent.category.DEFAULT"/>
      </intent-filter>
      <meta-data
        android:name="android.nfc.cardemulation.host_apdu_service"
        android:resource="@xml/aid_list" />
    </service>

  </application>
</manifest>
android:enabled="false" is correct — the SDK enables this service dynamically when the merchant starts an NFC session. It does not run persistently in the background.

4. AID List XML

Create the file android/app/src/main/res/xml/aid_list.xml (create the xml/ directory if it doesn’t exist):
android/app/src/main/res/xml/aid_list.xml
<host-apdu-service
  xmlns:android="http://schemas.android.com/apk/res/android"
  android:description="@string/app_name"
  android:requireDeviceUnlock="false">
  <aid-group android:category="other" android:description="@string/app_name">
    <aid-filter android:name="D2760000850101" />
  </aid-group>
</host-apdu-service>
This AID (Application Identifier) tells the Android NFC stack which APDU service to route incoming NFC requests to — specifically the TapRails HCE emulation service.

5. Verify

Build and run your Android app:
npm run android
# or
react-native run-android
The app should launch without build errors. To confirm NFC is working, proceed to the Get Started and run the merchant flow on an Android device.
All done on Android! No additional linking is required — React Native’s autolinking handles the native module registration.