Permissions

Host app permission requirements for the Flutter Verifier SDK.

Host App Changes Required

Before testing NFC delivery on device, your host application must declare the required native setup in AndroidManifest.xml, Android XML resources, and register a Kotlin HCE service. The SDK cannot configure these for you — they live in your app's platform directories. Core QR-only verification does not require any of this setup.

Why This Matters

The SDK can support flows that rely on device capabilities such as:

  • QR display for verifier-initiated presentation requests
  • Android NFC Host Card Emulation for request delivery (optional)

The SDK cannot grant these permissions or register native services for your app. Your host application must add the required native configuration before NFC delivery can work on device. Core QR-only verification does not require any platform-specific setup.

NFC Delivery Setup (Send)

NfcSendService can expose the active presentation request over Android NFC Host Card Emulation (HCE). A nearby wallet app can then receive the same request by tapping instead of scanning the QR code. On iOS, NfcSendService automatically falls back to QR delivery — iOS does not support HCE for custom AIDs.

The Flutter SDK does not bundle a native HCE implementation. Instead, the SDK's MethodChannelHceAdapter drives a Kotlin service that your host app provides, so you keep control over the package name and can sign it with your own app identity.

Android — NFC permission and feature flags

Add to android/app/src/main/AndroidManifest.xml:

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

Android — HCE service registration

Add the host APDU service inside the <application> element:

<service
  android:name=".VerifierHostApduService"
  android:description="@string/hce_service_description"
  android:exported="true"
  android:permission="android.permission.BIND_NFC_SERVICE">
  <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/verifier_host_apdu_service" />
</service>

Create android/app/src/main/res/xml/verifier_host_apdu_service.xml with the VECU proprietary AID:

<?xml version="1.0" encoding="utf-8"?>
<host-apdu-service xmlns:android="http://schemas.android.com/apk/res/android"
  android:description="@string/hce_service_description"
  android:requireDeviceUnlock="false">
  <aid-group
    android:category="other"
    android:description="@string/hce_service_description">
    <aid-filter android:name="F056454355000001" />
  </aid-group>
</host-apdu-service>

Why a proprietary AID?

The VECU protocol uses F056454355000001 (in the ISO 7816 user-assigned F0-FF range) rather than the standard NDEF Tag AID D2760000850101. On Samsung Galaxy devices, the standard AID is intercepted by Samsung Wallet and Samsung Pay before it reaches third-party apps. Using a proprietary AID sidesteps that interception entirely.

Android — Kotlin host APDU service

Create android/app/src/main/kotlin/<your-package>/VerifierHostApduService.kt. The full implementation with CC file, NDEF file, and READ BINARY handling is referenced by the SDK's MethodChannelHceAdapter over a platform channel. See the example app for the complete ISO 7816-4 APDU handler. Minimum scaffolding:

class VerifierHostApduService : HostApduService() {
    override fun processCommandApdu(commandApdu: ByteArray?, extras: Bundle?): ByteArray {
        // SELECT VECU AID, SELECT NDEF FILE, READ BINARY handling
        // Delegates the NDEF payload to VerifierHceSessionManager set by
        // the Flutter method-channel bridge.
    }
    override fun onDeactivated(reason: Int) { /* cleanup */ }
}

Consumers also need to wire the method channel vecu_verifier_flutter_sdk/hce (for session control) and event channel vecu_verifier_flutter_sdk/hce/events (for read notifications) in their MainActivity.kt. The example app in the SDK repository has a working reference implementation.

iOS behaviour for NFC send

iOS cannot host Android-style HCE for custom AIDs. On iOS verifier devices, NfcSendService returns the QR fallback automatically. No iOS-specific setup is required for NFC send.

Optional: Proximity Verification

If you use ProximityConfig on VerificationView, the SDK reads GPS coordinates so the backend can compare driver and verifier locations.

Android

<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />

iOS — Info.plist

<key>NSLocationWhenInUseUsageDescription</key>
<string>Confirm proximity to the vehicle pickup site</string>

Platform Availability Check

The SDK exports platform-detection helpers so your app can gracefully hide flows that aren't supported:

import 'package:vecu_verifier_flutter_sdk/vecu_verifier_flutter_sdk.dart';

final hceReady = await isHceAvailable(); // Android only, false on iOS

Related Guidance