如何解决为什么我的 HCE 应用重置了物理 POS 设备?
我正在我的华为手机 (Android 10) 上使用基于 Android 主机的卡模拟 (HCE)。我的第一个目标是让我的手机意识到销售点 (POS) 正在与它通话。到目前为止我不需要支付它。因为我不知道如何在我的地方可靠地测试我的应用程序,所以我打扰了当地的面包店(每天去一次面包店在法国并不罕见)。
不幸的是,今天早上我在实际的面包店 POS 上测试我的应用时,尽管我的应用 processCommandApdu
功能没有触发,但 POS 重置为 0.00。我再次尝试接近我的手机(在面包师重新输入金额之后),POS 再次重置,而我的应用程序端没有显示任何消息(Google Pay 也没有显示,因为它没有设置为 NFC 的默认应用程序)。我没有尝试第三次(因为有其他客户在场)并使用支持 NFC 的信用卡付款。
请注意,我的手机 NFC 设置如下:NFC 已启用,默认应用是我的应用,并使用当前运行的应用。
我关注了 this guide 和 Android documentation on HCE。所以我的 apduservice.xml
注册了 wikipedia 上显示的所有 Visa Card AID,看起来像:
<host-apdu-service xmlns:android="http://schemas.android.com/apk/res/android"
android:description="@string/servicedesc"
android:requiredeviceUnlock="false">
<aid-group
android:category="payment"
android:description="@string/aiddescription">
<aid-filter android:name="A0000000031010"/>
<aid-filter android:name="A0000000032010"/>
<aid-filter android:name="A0000000032020"/>
<aid-filter android:name="A0000000038010"/>
</aid-group>
</host-apdu-service>
HCE 服务就像
class HostCardEmulatorService : HostApduService() {
companion object {
val TAG = "Host Card Emulator"
val STATUS_SUCCESS = "9000"
val STATUS_Failed = "6F00"
}
/**
* The function always returns success as this is just a test
*/
override fun processCommandApdu(commandApdu: ByteArray?,extras: Bundle?): ByteArray {
Toast.makeText(this,"ProcessCommandApdu called with \n $commandApdu",Toast.LENGTH_SHORT).show()
println("ProcessCommandApdu called!")
return Utils.hexStringToByteArray(STATUS_SUCCESS)
}
/**
* The `onDeactiveted` method will be called when the a different AID has been selected or the NFC connection has been lost.
*/
override fun onDeactivated(reason: Int) {
Toast.makeText(this,"Connection lost because of $reason!",Toast.LENGTH_SHORT).show()
}
}
清单文件需要 NFC 权限并请求 NFC 服务:
<uses-permission android:name="android.permission.NFC" />
<uses-feature
android:name="android.hardware.nfc"
android:required="true" />
<uses-permission android:name="android.permission.NFC_TRANSACTION_EVENT" />
... (standard ANdroid project)
<service
android:name=".HostCardEmulatorService"
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>
然后 MainActivity
启动/停止 HCE 服务:
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
binding = ActivityMainBinding.inflate(layoutInflater)
setContentView(binding.root)
//...
val hceService: HostCardEmulatorService = HostCardEmulatorService()
val hceIntent = Intent(applicationContext,HostCardEmulatorService::class.java)
binding.mainButton.setonClickListener {
when (serviceEnabled) {
false -> {
applicationContext.startService(hceIntent)
if (isServiceRunning(HostCardEmulatorService::class.java)) {
binding.output.setText("Service enabled!")
// Changing state
serviceEnabled = true;
}
}
true -> {
applicationContext.stopService(hceIntent)
binding.output.setText("Service disabled!")
// Changing state
serviceEnabled = false;
}
}
}
}
现在我想知道为什么我的应用程序 processCommandApdu
功能没有触发,而 POS 显然在我的手机上找到了一些东西?
此外,我是否可以通过 NFC 阅读器应用程序使用另一部支持 NFC 的手机可靠地测试我的第一个目标(检测 POS 正在与我的应用程序通话),这样我就不会每天用我的极客测试来打扰面包师?我的意思是,在另一部手机上运行的 NFC 阅读器应用是否足以触发我的应用processCommandApdu
与实际 POS 的触发方式相同?
最后(如果可以回答)将实际 POS 重置为 0.00 并且没有保留金额并要求再次试用,因为我在 processCommandApdu
函数中返回了“成功命令”(在这种情况下它会意思是函数运行了但是 toast 消息没有出现或者我错过了)?
感谢任何帮助:-)
解决方法
多亏了 this older SO question,我的第一个问题关于 processCommandApdu
函数的非触发可以得到解答。事实上,它没有触发,因为它不期望 EMV POS 发送的应用程序 ID。此 AID 对应于 PPSE (Proximity Payment System Environment) which requests the list of all the AIDs supported by the smart card。
在 apduservice.xml
中使用此 PPSE AID 使 HCE 服务按预期工作
<aid-filter android:name="325041592E5359532E4444463031"/>
关于我的应用程序的测试,使用 NFC 读卡器不起作用,因为它们不像 EMV POS 那样发送 PPSE AID。编写我自己的应用来发送这个特殊的 AID 应该可以工作。
就EMV POS显示金额的重置而言,可能是由于Sim Card NFC芯片或移动NFC天线以POS未预期的某种方式做出反应所致。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。