You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何让Android/iPhone向PN532 NFC阅读器发送固定标识以实现设备识别

解决方案

核心思路

PN532当前采用被动读取模式(仅读取标签UID),但手机作为NFC设备时,需让其模拟成NDEF格式的NFC标签,主动发送固定数据,这样PN532就能读取到稳定的设备标识,实现设备识别。


Android端实现(发送固定ID)

Android可通过NfcAdapter模拟NDEF标签,靠近PN532时发送固定文本记录:

  1. 在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>
  1. 在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>
  1. 编写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及以上设备可用),步骤如下:

  1. 在Info.plist中添加NFC权限:
<key>NFCReaderUsageDescription</key>
<string>需要使用NFC识别设备</string>
<key>com.apple.developer.nfc.readersession.formats</key>
<array>
    <string>NDEF</string>
</array>
  1. 编写代码模拟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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.23 00:07:04