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

Android Reader模式下无法与Android HCE通信的技术求助

问题分析与解决方案

核心问题定位

你的场景中iPhone阅读器能正常通信但Android阅读器(S21)不行,主要原因集中在APDU格式错误、Android NFC系统的NDEF自动处理干扰、HCE服务未被正确选中、代码常量缺失这几点:

  1. APDU长度字段用了16位整数,不符合短APDU的单字节Lc要求,Android HCE对格式校验更严格,导致指令被拒绝
  2. Android NFC系统会自动检测NDEF标签并优先处理,干扰HCE服务激活,导致后续自定义APDU无法路由
  3. Android阅读器未显式发送SELECT AID指令,HCE服务未进入激活状态
  4. HCE代码中引用了未定义的SELECT_PSW常量,指令匹配逻辑失效

具体修复步骤

1. 修正Flutter端APDU格式

将自定义APDU的长度字段改为单字节:

List<int> commandSignaturePin(List<int> data) {
  var result = <int>[];
  result.addAll(commandPinVerify);
  // 替换为单字节长度,符合短APDU规范
  result.add(data.length);
  result.addAll(data);
  return result;
}
final commandPinVerify = [0x00, 0x20, 0x00, 0x80];

2. 关闭Android端NDEF自动检测

修改poll方法参数,避免系统自动处理NDEF干扰HCE通信:

var tag = await FlutterNfcKit.poll(
    iosMultipleTagMessage: "Multiple tags found!",
    androidCheckNDEF: false, // 关闭自动NDEF检测
    iosAlertMessage: "Scan your tag", 
    readIso14443A: true, 
    readIso14443B: false, 
    readIso15693: false, 
    readIso18092: false);

3. 显式发送SELECT AID指令

在自定义指令前先发送SELECT AID,确保HCE服务激活:

// 定义和HCE端一致的SELECT AID指令
final selectAidApdu = [0x00, 0xA4, 0x04, 0x00, 0x07, 0xD2, 0x76, 0x00, 0x00, 0x85, 0x01, 0x01, 0x00];
// 先发送SELECT指令激活HCE服务
var selectResult = await FlutterNfcKit.transceive(Uint8List.fromList(selectAidApdu), timeout: Duration(seconds: 5));
print("SELECT AID结果: ${selectResult}");

// 再发送自定义指令
final pswApdu = commandSignaturePin("ciao".codeUnits);
final ss = Uint8List.fromList(pswApdu);
var result = await FlutterNfcKit.transceive(ss, timeout: Duration(seconds: 20));
print("自定义指令结果: ${result}");

4. 修复Android HCE服务的常量定义

在MyHostApduService中补充缺失的常量和变量定义:

public class MyHostApduService extends HostApduService {
    private final static String TAG = "MyHostApduService";
    private static final byte[] SELECT_APPLICATION = {(byte) 0x00,(byte) 0xA4,(byte) 0x04,(byte) 0x00,(byte) 0x07,(byte) 0xD2,(byte) 0x76,(byte) 0x00,(byte) 0x00,(byte) 0x85,(byte) 0x01,(byte) 0x01,(byte) 0x00};
    // 补充缺失的SELECT_PSW常量
    private static final byte[] SELECT_PSW = {(byte)0x00, (byte)0x20, (byte)0x00, (byte)0x80};
    private static final byte[] SUCCESS_SW = new byte[] {(byte)0x90,(byte)0x00};
    private static final byte[] FAILURE_SW = new byte[] {(byte)0x6a,(byte)0x82};
    private boolean mAppSelected;
    private boolean mCcSelected;
    private boolean mNdefSelected;
    // 补充datiRicevuti变量定义
    private String datiRicevuti;

    // 原有其他代码保持不变
}

额外验证建议

  • 查看HCE服务的Logcat输出,确认是否收到SELECT AID和自定义指令
  • 确保Android阅读器设备的NFC功能未被省电模式限制
  • 测试时保持两台设备的NFC感应区域对齐,避免通信中断

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.19 11:44:55