如何读取另一个 Android 设备的 NFC ID?

How can I read the NFC ID of another Android device?

我想将 NFC 标签 ID 从一个 Android 设备交换(或只读取)到另一个设备,但我不知道我是否应该使用点对点模式或模拟 NFC 标签HCE.

如果我使用 HCE,模拟的标签 ID 是否唯一?

更好的选择是什么还是有更简单的选择?

P2P 和 HCE 都不会为您提供唯一 ID,至少在我所知道的任何 phone 上都不会。对于 P2P,要求在 ATR 中交换的 ID 是随机的。使用 HCE,仿真标签 ID 通常设置为 08h 加上一个随机数。可能有 API 呼叫设置,但我不知道这样。但是,phone 不能被任何阅读者唯一识别,这很有意义。

如何读取另一个 Android 设备的 NFC ID?

我假设你在这里谈论的是防碰撞identifier/UID。在读取Android设备上,可以使用reader模式API访问HCE模式的设备:

nfcAdapter.enableReaderMode(this, new NfcAdapter.ReaderCallback() {
    public void onTagDiscovered (Tag tag) {
        byte[] uid = tag.getId();
        // TODO: do something with the UID ...
    }
}, NfcAdapter.FLAG_READER_NFC_A | NfcAdapter.FLAG_READER_SKIP_NDEF_CHECK, null);

模拟的标签ID是否唯一?

参见 . Typically, neither P2P mode nor HCE should provide a unique and stable ID. However, there are some exceptions to this and the point of time when a non-stable ID changes may vary (also see this answer)。可能是:

  • 设备有一个安全元素并使用该安全元素的静态 UID。
  • 设备每次开机都会生成一个新的随机 UID,但会继续使用相同的 UID,直到关机。
  • 设备在外部 reader 设备每次激活时生成一个新的随机 UID。 IE。每当外部 HF 场应用于 Android 设备的 NFC 天线时。

另请注意,某些 NFC 设备将使用随机生成的 UID,这些 UID 不以随机前缀 0x08 开头。

我可以强制设备使用 fixed/stable UID 吗?

Android 没有提供 API 来影响 UID/anti-collision 标识符,所以简短的回答是 没有 。但是,如果可以选择生根或创建自定义 ROM,则可以更改 UID 和其他协议参数:

  • Host-based Card Emulation with Fixed Card ID

您应该使用 UID 来识别(甚至验证)设备吗?

不,你绝对不应该这样做。当您尝试将 HCE 设备集成到某些遗留系统中时,有时您没有太多选择,但您绝对应该考虑不同的设计。

首先,作为 ,如果 NFC 设备公开 fixed/stable 标识符,这可能会引入隐私问题,因为任何人都可以读取和跟踪 ID。

其次,虽然许多系统仍然使用这些 ID 来验证(!)卡,但 UID 不一定是唯一的(特别是 4 字节的 UID 比现有的卡少)并且 UID 可以很容易地被克隆。有关详细信息,请参阅 this answer