You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Flutter(Android平台)的主机卡模拟(HCE)中写入NDEF消息?

Hey there! Let's work through your NFC NDEF payload sending problem for your Android Flutter pass wallet app. Since Google Smart Tap isn't an option, and the nfc_emulator library fell short (no NDEF write support, plus it didn't work for you), here's a practical, reliable approach to get this done:

This library has solid support for Android NFC operations—including Host Card Emulation (HCE) which lets your phone act as an NDEF tag for scanning devices. It’s actively maintained and handles NDEF reads/writes seamlessly.

Step 1: Add the Dependency

First, add the library to your pubspec.yaml:

dependencies:
  flutter:
    sdk: flutter
  nfc_manager: ^3.3.0

Run flutter pub get to install it.

Step 2: Configure Android Manifest

Update your android/app/src/main/AndroidManifest.xml to enable NFC permissions and HCE support:

<!-- Required NFC permission -->
<uses-permission android:name="android.permission.NFC" />
<!-- Declare NFC hardware requirement (adjust to "false" if you want to support non-NFC devices) -->
<uses-feature android:name="android.hardware.nfc" android:required="true" />

<!-- Add HCE service configuration inside the <application> tag -->
<service
    android:name="dev.nfc_manager.platform.android.NfcHostApduService"
    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/apduservice" />
</service>

Next, create a new file android/app/src/main/res/xml/apduservice.xml with this content (defines the AIDs your HCE service will respond to):

<?xml version="1.0" encoding="utf-8"?>
<host-apdu-service xmlns:android="http://schemas.android.com/apk/res/android"
    android:description="@string/app_name"
    android:requireDeviceUnlock="false">
    <aid-group android:description="NDEF AIDs" android:category="other">
        <aid-filter android:name="F0010203040506" />
        <aid-filter android:name="D2760000850101" /> <!-- Standard NDEF AID -->
    </aid-group>
</host-apdu-service>

Step 3: Implement NDEF Payload Sending in Flutter

Here’s a complete code snippet that checks NFC availability, sets up HCE, and sends your string as an NDEF payload when a scanning device connects:

import 'package:flutter/material.dart';
import 'package:nfc_manager/nfc_manager.dart';

class NfcSenderScreen extends StatefulWidget {
  const NfcSenderScreen({super.key});

  @override
  State<NfcSenderScreen> createState() => _NfcSenderScreenState();
}

class _NfcSenderScreenState extends State<NfcSenderScreen> {
  bool _isNfcAvailable = false;
  bool _isSending = false;

  @override
  void initState() {
    super.initState();
    _checkNfcAvailability();
  }

  Future<void> _checkNfcAvailability() async {
    final available = await NfcManager.instance.isAvailable();
    setState(() => _isNfcAvailable = available);
  }

  Future<void> _sendNdefMessage(String text) async {
    if (!_isNfcAvailable) {
      if (!mounted) return;
      ScaffoldMessenger.of(context).showSnackBar(
        const SnackBar(content: Text("NFC不可用,请先开启设备NFC")),
      );
      return;
    }

    setState(() => _isSending = true);

    try {
      // Create an NDEF message with your text payload
      final ndefMessage = NdefMessage([
        NdefRecord.createText(text),
        // Optional: Add other record types if needed (e.g., URI)
        // NdefRecord.createUri(Uri.parse("https://example.com")),
      ]);

      // Start NFC session to listen for scanning devices
      await NfcManager.instance.startSession(
        onDiscovered: (NfcTag tag) async {
          try {
            final ndef = Ndef.from(tag);
            if (ndef != null && ndef.isWritable) {
              await ndef.write(ndefMessage);
              if (!mounted) return;
              ScaffoldMessenger.of(context).showSnackBar(
                const SnackBar(content: Text("NDEF消息发送成功!")),
              );
            } else {
              throw Exception("扫描设备不支持NDEF写入");
            }
          } catch (e) {
            if (!mounted) return;
            ScaffoldMessenger.of(context).showSnackBar(
              SnackBar(content: Text("发送失败: ${e.toString()}")),
            );
          } finally {
            await NfcManager.instance.stopSession();
            if (mounted) setState(() => _isSending = false);
          }
        },
      );
    } catch (e) {
      if (mounted) {
        setState(() => _isSending = false);
        ScaffoldMessenger.of(context).showSnackBar(
          SnackBar(content: Text("初始化NFC失败: ${e.toString()}")),
        );
      }
    }
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: const Text("NFC发送器")),
      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: [
            if (!_isNfcAvailable)
              const Text("请开启设备NFC功能", style: TextStyle(color: Colors.red)),
            const SizedBox(height: 20),
            ElevatedButton(
              onPressed: _isSending ? null : () => _sendNdefMessage("你的通行证字符串内容"),
              child: _isSending
                  ? const CircularProgressIndicator(color: Colors.white)
                  : const Text("开始发送NFC消息"),
            ),
          ],
        ),
      ),
    );
  }
}
Key Tips & Troubleshooting
  • HCE Compatibility: Ensure your Android device runs Android 4.4 (API level 19) or higher—most modern devices support HCE.
  • NFC Toggle: Always check if NFC is enabled before attempting to send messages; prompt users to turn it on if not.
  • Test with Real Devices: Emulators don’t support NFC, so test with two physical Android devices (or a dedicated NFC scanner).
  • Custom AIDs: If your scanning device expects a specific AID, update the apduservice.xml with the correct aid-filter value.
  • Native Backup: If the library still has issues, you can build a custom Android HCE service and call it via Flutter’s Method Channel for full control over the NFC logic.

内容的提问来源于stack exchange,提问作者ungali

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.29 12:07:40