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
- Overview — main verifier quick start
- API Reference — SDK configuration and types