如何让Android/iPhone向PN532 NFC阅读器发送固定标识以实现设备识别
解决方案
核心思路
PN532当前采用被动读取模式(仅读取标签UID),但手机作为NFC设备时,需让其模拟成NDEF格式的NFC标签,主动发送固定数据,这样PN532就能读取到稳定的设备标识,实现设备识别。
Android端实现(发送固定ID)
Android可通过NfcAdapter模拟NDEF标签,靠近PN532时发送固定文本记录:
- 在
AndroidManifest.xml中添加NFC权限与配置:
<uses-permission android:name="android.permission.NFC" /> <uses-feature android:name="android.hardware.nfc" android:required="true" /> <activity ...> <intent-filter> <action android:name="android.nfc.action.TECH_DISCOVERED" /> </intent-filter> <meta-data android:name="android.nfc.action.TECH_DISCOVERED" android:resource="@xml/nfc_tech_filter" /> </activity>
- 在
res/xml目录下创建nfc_tech_filter.xml,声明支持NDEF格式:
<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> <tech-list> <tech>android.nfc.tech.Ndef</tech> <tech>android.nfc.tech.NdefFormatable</tech> </tech-list> </resources>
- 编写Activity代码,生成固定NDEF消息:
import android.nfc.NdefMessage; import android.nfc.NdefRecord; import android.nfc.NfcAdapter; import android.nfc.NfcEvent; import android.os.Bundle; import androidx.appcompat.app.AppCompatActivity; public class NfcSimulateActivity extends AppCompatActivity implements NfcAdapter.CreateNdefMessageCallback { private NfcAdapter nfcAdapter; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); nfcAdapter = NfcAdapter.getDefaultAdapter(this); if (nfcAdapter != null) { nfcAdapter.setNdefPushMessageCallback(this, this); } } @Override public NdefMessage createNdefMessage(NfcEvent event) { // 自定义固定设备ID,例如"MY_PHONE_001" String fixedId = "MY_PHONE_001"; NdefRecord record = NdefRecord.createTextRecord("en", fixedId); return new NdefMessage(new NdefRecord[]{record}); } }
iOS端实现(发送固定ID)
iOS需使用CoreNFC框架(iOS 13+支持,iPhone 7及以上设备可用),步骤如下:
- 在
Info.plist中添加NFC权限:
<key>NFCReaderUsageDescription</key> <string>需要使用NFC识别设备</string> <key>com.apple.developer.nfc.readersession.formats</key> <array> <string>NDEF</string> </array>
- 编写代码模拟NFC标签发送固定NDEF数据:
import UIKit import CoreNFC class ViewController: UIViewController, NFCNDEFWriterSessionDelegate { var writerSession: NFCNDEFWriterSession? override func viewDidLoad() { super.viewDidLoad() startSimulatingNdefTag() } func startSimulatingNdefTag() { guard NFCNDEFWriterSession.readingAvailable else { print("NFC功能不可用") return } writerSession = NFCNDEFWriterSession(delegate: self, queue: nil, invalidateAfterFirstWrite: false) writerSession?.begin() } func writerSession(_ session: NFCNDEFWriterSession, didBecomeActiveWith activationError: Error?) { // 创建固定ID的NDEF记录 let fixedId = "MY_PHONE_001" guard let payload = fixedId.data(using: .utf8) else { return } let record = NFCNDEFPayload(format: .nfcWellKnown, type: "T".data(using: .utf8)!, identifier: Data(), payload: payload) let message = NFCNDEFMessage(records: [record]) // 启动标签模拟 session.connect(to: message) { error in if let error = error { print("模拟启动失败: \(error.localizedDescription)") return } print("已开始模拟NFC标签") } } func writerSession(_ session: NFCNDEFWriterSession, didInvalidateWith error: Error) { print("会话失效: \(error.localizedDescription)") } }
注意:iOS模拟NFC标签仅支持前台运行模式。
ESP32端代码修改(读取固定NDEF数据)
原代码仅能读取标签UID,需修改为读取NDEF文本记录,从而获取手机发送的固定ID:
#include <Wire.h> #include <PN532_I2C.h> #include <PN532.h> #include <NfcAdapter.h> PN532_I2C pn532i2c(Wire); NfcAdapter nfc = NfcAdapter(pn532i2c); void setup() { Serial.begin(115200); pinMode(2, OUTPUT); // 示例:控制GPIO2引脚 nfc.begin(); nfc.setPassiveActivationRetries(0x02); nfc.SAMConfig(); } void loop() { if (nfc.tagPresent()) { NfcTag tag = nfc.read(); if (tag.hasNdefMessage()) { NdefMessage message = tag.getNdefMessage(); if (message.getRecordCount() > 0) { NdefRecord record = message.getRecord(0); if (record.isText()) { String fixedId = record.getText(); Serial.print("识别到设备: "); Serial.println(fixedId); // 执行特定任务逻辑,例如控制GPIO if (fixedId == "MY_PHONE_001") { digitalWrite(2, HIGH); delay(2000); digitalWrite(2, LOW); } } } } } delay(100); }
说明:需先在Arduino库管理器中安装NfcAdapter库。
关键注意事项
- Android和iOS均需发送NDEF格式文本记录,避免依赖动态变化的设备UID。
- Android可配置后台发送NDEF数据,iOS仅支持前台模式。
- 确保PN532供电稳定,避免读取失败。
内容的提问来源于stack exchange,提问作者Ba Ta
相关产品推荐
相关产品推荐

