6

我知道这是一个没有明确答案的“讨论”话题,但我真的很想得到一些关于在为 Android 开发 NFC 应用程序时会发生什么的反馈,特别是使用 IsoDep 与使用 APDU 帧的 DESFire 卡进行通信。

  • 我可以期望发送到特定 DESFire 卡的相同 APDU 帧在 Android 设备和版本之间的响应相同吗?
  • 我应该至少在哪些 Android 版本和设备上进行测试才能得到合理的覆盖?
  • Android驱动程序中的错误或回归是否很常见,或者我可以期待这些在很久以前就被根除?
  • 你推荐支持的最早的安卓版本是什么,以免太麻烦?

到目前为止,我的体验出人意料地好坏参半(3 种设备,3 种差异),我真的很想听听其他开发人员的意见。例如:在 S3 (Android 4.1.2) 上工作的相同 APDU 命令在 S4 (Android 4.3) 上不起作用(在第 3 次 auenticate 握手时出现“错误长度”失败,直到那时一切正常)。这些手机有不同的 NFC 芯片组,但我没想到 APDU 帧的抽象级别会有所不同。

4

2 回答 2

8

这确实是一个讨论话题,但我认为它与 Android NFC 开发人员有关,因此我将在这里给出我的经验报告:

  • 我可以期望发送到特定 DESFire 卡的相同 APDU 帧在 Android 设备和版本之间的响应相同吗?

是的,但仅适用于满足 ISO/IEC 7816-4 要求并具有一些附加限制的 APDU 命令(例如,并非所有设备都支持扩展长度的 APDU,某些设备似乎对 case-1 APDU 有问题)。

最新版本的 Broadcom NFC 堆栈中也存在一些已知错误(见下文)。

  • 我应该至少在哪些 Android 版本和设备上进行测试才能得到合理的覆盖?

到目前为止,我遇到的最大问题是带有 Broadcom NFC 芯片组的三星设备。尽管与 APDU 无关,尤其是在使用 MIFARE Classic 时,它们的行为与其他具有 Broadcom 芯片组的设备完全不同。例如,S4 在系统级别阻止 MIFARE Classic 标签,因此不允许读取标签 (N)UID。(无论如何,Broadcom 芯片组都无法从 MF Classic 读取数据......)

关于测试,我建议每个 NFC 控制器至少使用一台 Nexus 设备(即一台使用 NXP 芯片组,一台使用 Broadcom 芯片组),并为一两个其他手机制造商提供相同的设备。(对于三星来说,采用 NXP 芯片组的设备与 Nexus 设备的行为非常相似,所以我猜你是 Nexus S/Galaxy Nexus,例如,在 NFC 读/写模式体验方面,S3 可以被视为等效的。)

关于 Android 平台,我会坚持使用用户最多的平台。(还有那些卸载率很高的平台。)

  • Android驱动程序中的错误或回归是否很常见,或者我可以期待这些在很久以前就被根除?

正如我之前所说的,Broadcom NFC 堆栈存在一些已知问题。特别是当涉及到 MIFARE DESFire 时,存在一个已知问题,即 NFC 堆栈在将基于 APDU 的任意命令传递给应用程序后将其发送到卡。因此,这些命令可能会干扰卡和该应用程序之间正在进行的通信(例如,强制基于 APDU 的通信模式而不是本机命令模式、更改应用程序/文件选择等)。有关详细信息,请参阅此错误报告和此stackoverflow 问题

并且通过错误跟踪器查看,肯定还有更多未解决的问题。

  • 你推荐支持的最早的安卓版本是什么,以免太麻烦?

对于基于 APDU 的通信(使用 DESFire 或其他卡),API 10 (Android 2.3.3) 和更高版本可以正常工作。当谈到 NFC API 的可用性(除了简单的 APDU 交换)和漂亮的应用程序设计时,我会坚持使用 Android 4.0.3 及更高版本。但请记住,最新的平台尤其是 Android 4.3 和 Android 4.4 引入了许多奇怪的行为/错误/(“功能”?)。

为了了解使用 NFC 设备的用户当前拥有哪些 Android 版本,我将分享NFC TagInfo的当前设备安装分布(尽管这可能会略有偏差,因为 NFC TagInfo 不适合普通用户):

  1. 安卓 4.1:36%
  2. 安卓 4.3:21%
  3. 安卓 4.2:19%
  4. 安卓 4.4:18%
  5. 安卓 4.0.3 - 4.0.4:4%
  6. 安卓 2.3.3 - 2.3.7:2%
  7. 安卓 4.0 - 4.0.2:0%
  8. 安卓 3.2:0%
于 2013-12-07T10:44:16.803 回答
8

这个答案与您在一台设备上工作但在其他设备上不工作的 APDU 的具体问题有关。正如 Michael Roland 所指出的,存在使用 NCI NFC 堆栈的设备经常发送 APDU 的问题,这可能会干扰您的应用程序发送的 APDU。该问题与此堆栈中存在检查的错误实现有关,并在此处记录。当在 DESFire 卡上执行身份验证过程时,这尤其是一个问题,因为它由多个 APDU 组成,如果被不相关的 APDU 中断,则会失败。但是,对于在 Android 版本 >= 4.4(API 级别 >= 19)上运行的设备,有一个解决方法。在这些设备上,您可以使用带有EXTRA_READER_PRESENCE_CHECK_DELAY的enableReaderMode方法额外配置存在检查的频率。通过增加延迟,您可以降低干扰应用程序 APDU 的可能性。

例如:

    Bundle options = new Bundle();
    options.putInt(NfcAdapter.EXTRA_READER_PRESENCE_CHECK_DELAY, 5000);

    getNfcAdapter().enableReaderMode(
            this,
            new ReaderCallback() {
                @Override
                public void onTagDiscovered(final Tag tag) {
                    // ... authenticate ...
                }
            },
            NfcAdapter.FLAG_READER_NFC_A
                    | NfcAdapter.FLAG_READER_SKIP_NDEF_CHECK, options);
于 2013-12-18T14:20:21.453 回答