Android NFC HCE双向通信:读卡器向HCE设备发送数据的实现方案咨询
NFC双向通信:读卡器向HCE设备发送数据及替代方案
一、实现读卡器向HCE设备发送数据
你的当前代码中,读卡器端尝试用Ndef.writeNdefMessage()写入数据,但HCE的HostApduService只处理了SELECT和READ_BINARY指令,未处理写入相关的APDU,导致数据无法被HCE接收。以下是具体修改方案:
1. HCE端:添加写入指令处理逻辑
在processCommandApdu方法中,增加对**WRITE_BINARY(0x00 D0)**指令的处理,接收读卡器发送的数据:
override fun processCommandApdu(commandApdu: ByteArray, extras: Bundle?): ByteArray { // 保留原有SELECT和READ_BINARY逻辑 if (Arrays.equals(SELECT_APPLICATION, commandApdu)) { mAppSelected = true mCcSelected = false mNdefSelected = false return SUCCESS_SW } else if (mAppSelected && Arrays.equals(SELECT_CAPABILITY_CONTAINER, commandApdu)) { mCcSelected = true mNdefSelected = false return SUCCESS_SW } else if (mAppSelected && Arrays.equals(SELECT_NDEF_FILE, commandApdu)) { mCcSelected = false mNdefSelected = true return SUCCESS_SW } else if (commandApdu[0] == 0x00.toByte() && commandApdu[1] == 0xb0.toByte()) { // READ_BINARY逻辑保留 return responseApdu } // 新增WRITE_BINARY指令处理 else if (mNdefSelected && commandApdu[0] == 0x00.toByte() && commandApdu[1] == 0xd0.toByte()) { // 提取偏移量(APDU的第3、4字节) val offset = ((commandApdu[2].toInt() and 0xFF) shl 8) or (commandApdu[3].toInt() and 0xFF) // 提取写入的数据(从第5字节开始) val receivedData = commandApdu.copyOfRange(5, commandApdu.size) // 处理数据:比如保存到本地变量、更新NDEF消息等 // 示例:mNdefData = receivedData return SUCCESS_SW // 返回成功状态字(0x9000) } return FAILURE_SW }
2. 读卡器端:两种发送数据的方式
方式一:基于IsoDep直接发送APDU(推荐,灵活性高)
HCE本质是模拟ISO-DEP协议的卡片,读卡器可通过IsoDep直接发送自定义APDU指令,与HCE端交互:
@Override public void onTagDiscovered(Tag tag) { runOnUiThread(() -> readResult.setText("")); IsoDep isoDep = IsoDep.get(tag); if (isoDep != null) { try { isoDep.connect(); // 1. 先发送SELECT指令选中HCE应用(与HCE端的SELECT_APPLICATION一致) byte[] selectApdu = SELECT_APPLICATION; // 替换为你定义的SELECT指令字节数组 byte[] response = isoDep.transceive(selectApdu); // 检查是否选中成功 if (Arrays.equals(response, new byte[]{(byte)0x90, 0x00})) { // 2. 发送自定义写入APDU,示例:发送数据"hello HCE" byte[] writeApdu = new byte[]{0x00, (byte)0xD0, 0x00, 0x00, 0x05, 0x68, 0x65, 0x6C, 0x6C, 0x6F}; response = isoDep.transceive(writeApdu); if (Arrays.equals(response, new byte[]{(byte)0x90, 0x00})) { runOnUiThread(() -> readResult.setText("数据发送成功")); } else { runOnUiThread(() -> readResult.setText("发送失败:响应异常")); } } isoDep.close(); } catch (Exception e) { runOnUiThread(() -> readResult.setText("发送失败:" + e.getMessage())); } } else { runOnUiThread(() -> readResult.setText("设备不支持ISO-DEP协议")); } }
方式二:基于NDEF写入(需HCE完整模拟NDEF标签)
如果坚持用Ndef.writeNdefMessage(),需确保HCE端完整实现NDEF Type4标签的逻辑,包括处理WRITE_BINARY指令更新NDEF数据,这样读卡器的写入操作才能被HCE正确接收。
二、其他NFC双向通信方案
- NFC Peer-to-Peer(P2P)模式:两个NFC设备直接以对等模式连接,基于NFCIP-1协议交换数据,无需HCE模拟卡片,可通过
Ndef或IsoDep在P2P模式下通信。 - 自定义APDU协议:脱离标准NDEF/Type4标签规范,在HCE端自定义一套APDU指令集,读卡器按约定发送指令,适合特定业务场景,灵活性最高。
- Android Beam(兼容旧设备):Android 10之前的原生功能,通过NDEF消息在设备间快速传输数据,现已被Nearby Share替代,但部分旧设备仍支持。
内容的提问来源于stack exchange,提问作者Kamal Kumar Majhi
相关产品推荐
相关产品推荐

