【问题标题】:How to transfer plain text via Android NFC?如何通过 Android NFC 传输纯文本?
【发布时间】:2020-07-03 20:56:20
【问题描述】:

我是 Android NFC 的新手,并在 android 中开发 NFC 应用程序。我的想法是设备 A 需要向设备 B 发送纯文本。在 Android NFC 中是否可能? 我刚刚在 Reader 和 Writer 上尝试了 Tag Dispatcher (enableForegroundDispatch, disableForegroundDispatch)。 我的读者端代码是:

nfcAdapter.enableForegroundDispatch(this, pendingIntent, intentFilters, techList)
override fun onNewIntent(intent: Intent?) {
intent.getParcelableArrayExtra(NfcAdapter.EXTRA_NDEF_MESSAGES)?.also { rawMessages ->
            val messages: List<NdefMessage> = rawMessages.map { it as NdefMessage }

            for (message in messages) {
                for (record in message.records) {
                    println(" ${record.toString()}")
                }
            }
        }
}

我的 Writer 端代码是:

nfcAdapter.enableForegroundDispatch(
        this, pendingIntent, intentFilters, techList)
override fun onNewIntent(intent: Intent?) {
if (action.equals(NfcAdapter.EXTRA_TAG)) {
        val tagFromIntent = intent.getParcelableExtra<Tag>(NfcAdapter.EXTRA_TAG)
        if (NfcAdapter.ACTION_TECH_DISCOVERED.equals(action)
            || NfcAdapter.ACTION_NDEF_DISCOVERED.equals(action)
        ) {
            println("testing=============== tag discovered ")
            writeNdefMessage(tagFromIntent!!, "This is my first app")
        }
    }}

private fun writeNdefMessage(tag: Tag, message: String) {
    val record: NdefRecord = newTextRecord(message, Locale.ENGLISH, true)!!
    val ndefMessage = NdefMessage(arrayOf(record))
    try {
        if (isExist(tag.techList, NdefFormatable::class.java.name)) {
            val ndefFormatable = NdefFormatable.get(tag)
            try {
                if (!ndefFormatable.isConnected) {
                    ndefFormatable.connect()
                }
                ndefFormatable.format(ndefMessage)
            } finally {
                ndefFormatable.close()
            }
        } else if (isExist(tag.techList, Ndef::class.java.name)) {
            val ndef = Ndef.get(tag)
            try {
                if (!ndef.isConnected) {
                    ndef.connect()
                }
                if (ndef.isWritable) {
                    ndef.writeNdefMessage(ndefMessage)
                }
            } finally {
                ndef.close()
            }
        }
    } catch (e: FormatException) {
        println("Format failed exception")
    } catch (e: IOException) {
        println("")
    }
}

当我扫描标签时应用程序启动(通过 AndroidManifest.xml 详细信息)。但我无法通过 NFC 发送纯文本。我不知道我做错了什么。我不知道这种方法是对还是错。请帮助我进行此操作。

提前致谢。

【问题讨论】:

    标签: android kotlin nfc data-transfer plaintext


    【解决方案1】:

    因此,在 Android 点对点 NFC(设备到设备)中,也称为 Android Beam,自 API 29 起已被弃用

    https://developer.android.com/reference/android/nfc/NfcAdapter#setNdefPushMessage(android.nfc.NdefMessage,%20android.app.Activity,%20android.app.Activity...)

    您在较旧的 Android 版本中使用了错误的方法来使用 Android Beam。 有关实际如何使用它的更多详细信息,请参阅https://developer.android.com/guide/topics/connectivity/nfc/nfc#p2p。 (您正在使用写入 NFC 卡而不是其他设备的方法)

    注意通过 NFC 的点对点仅适用于 Android,iOS 不支持它,它已被贬低以支持蓝牙/Wifi Direct

    请注意,仍然可以让一台 Android 设备使用主机卡仿真来仿真带有 NDEF 消息的 Type 4 NFC 卡,但这实现起来相当复杂。

    更新:

    链接到主机卡模拟 https://developer.android.com/guide/topics/connectivity/nfc/hce 和类型 4 卡规范 http://apps4android.org/nfc-specifications/NFCForum-TS-Type-4-Tag_2.0.pdf

    【讨论】:

    • 感谢@Andrew 的回复。我检查对等实施。
    • 嗨@Andrew,我刚刚实现了点对点,现在我可以将疼痛文本传输到其他应用程序。但是 CreateNdefMessageCallback 在 29 中已弃用。有什么想法可以替换已弃用的方法吗?
    • 如答案中所述,从技术上讲,可以将主机卡仿真用于一个设备来仿真带有 NDEF 消息的 Type 4 NFC 卡,然后第二个设备像普通卡一样读取它.仍然支持主机卡仿真和读卡,但实现起来很复杂
    • 非常感谢@Andrew。如果 HCE 上的作者和读者有任何链接,请发布链接。
    • 抱歉,我以为我已经更正了指向类型 4 卡规范的链接的重复发布,现在已修复。 apps4android.org/nfc-specifications/… PDF 的第 5 节是读/写只是不同的 C-APDU 你的 HCE 实现必须处理,HCE 中的机制对于两个 C-APDU 是相同的