Android HCE仅接收终端一条命令,服务因原因1停用求助
Android EMV卡模拟:PPSE后无法接收后续命令的修复方案
问题分析
服务因原因1(DEACTIVATION_LINK_LOSS,NFC链路丢失)停用,核心原因通常是:
- PPSE响应不符合EMV规范,导致终端拒绝继续通信
- 未处理后续终端命令,返回错误响应触发终端断开
- AID配置不完整,终端无法匹配到服务
修复步骤
1. 验证PPSE响应的合规性
你的PPSE响应必须严格遵循EMV FCI格式,检查以下几点:
- 以
6F(FCI模板标签)开头 - 包含
84标签(DF名称,值为PPSE AID325041592E5359532E4444463031) - 包含
A5标签(FCI专有模板) - 结尾必须是
9000(成功状态字) - 确保响应字节长度与标签值匹配,避免截断或多余字节
2. 完善命令处理逻辑
当前代码仅处理PPSE命令,其他命令返回6A82(文件未找到)会触发终端断开。需添加对后续常见命令的处理:
public class MyEmvCardService extends HostApduService { private static final String PPSE_SELECT = "00A404000E325041592E5359532E444446303100"; private static final String VISA_AID_SELECT = "00A4040007A000000003101000"; @Override public byte[] processCommandApdu(byte[] commandApdu, Bundle extras) { String cmdHex = Hex.encodeHexString(commandApdu); Log.d("EMV", "Received APDU: " + cmdHex); // 处理SELECT命令 if (cmdHex.startsWith("00A40400")) { if (cmdHex.equals(PPSE_SELECT)) { // 返回合规的PPSE响应 return Hex.decodeHex("6F23840E325041592E5359532E4444463031A511BF0C0E610C4F07A00000000310108701019000".toCharArray()); } else if (cmdHex.equals(VISA_AID_SELECT)) { // 返回Visa卡FCI响应 return Hex.decodeHex("6F1A8407A0000000031010A50F50085649534120444542497001019000".toCharArray()); } } // 处理读取记录命令(示例) else if (cmdHex.startsWith("00B2")) { return Hex.decodeHex("701057123456789012345678901234569000".toCharArray()); } // 暂不支持的命令返回"功能不支持"而非"文件未找到" Log.d("EMV", "Unsupported command, returning 6A81"); return Hex.decodeHex("6A81".toCharArray()); } @Override public void onDeactivated(int reason) { Log.d("EMV", "Service deactivated, reason: " + reason); } }
3. 修正APDU服务配置
确保apdu_service.xml包含终端可能访问的所有AID,避免终端无法匹配服务:
<host-apdu-service xmlns:android="http://schemas.android.com/apk/res/android" android:description="@string/emv_service_desc" android:requireDeviceUnlock="false"> <aid-group android:description="@string/payment_aids" android:category="payment"> <aid-filter android:name="325041592E5359532E4444463031"/> <!-- PPSE --> <aid-filter android:name="A0000000031010"/> <!-- Visa --> <aid-filter android:name="A0000000041010"/> <!-- Mastercard --> <aid-filter android:name="A0000002771010"/> <!-- Amex --> </aid-group> </host-apdu-service>
4. 日志调试
添加详细日志记录所有收发的APDU,便于定位未处理的命令:
- 记录每个收到的命令APDU
- 记录返回的响应APDU
- 在
onDeactivated中记录停用原因,确认是否为链路丢失或其他原因
5. 检查Manifest配置
确保HCE服务声明正确,权限和intent-filter无遗漏:
<service android:name=".MyEmvCardService" android:exported="true" 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/apdu_service"/> </service>
关键注意事项
- 所有APDU响应必须符合EMV规范,错误的响应会直接导致终端断开NFC连接
- 不要忽略任何终端发送的命令,即使是暂不支持的命令,也应返回
6A81(功能不支持)而非6A82 - 确保设备NFC功能正常,且应用已获得NFC相关权限(无需单独申请,HCE服务声明已隐含权限)
内容的提问来源于stack exchange,提问作者Asad373
相关产品推荐
相关产品推荐

