跨平台实战:Android Studio与iOS手机读写MifareUltralight NFC卡的完整流程与避坑指南
2026/4/18 5:00:18 网站建设 项目流程

1. 跨平台NFC开发入门指南

最近在做一个智能门禁项目时,需要实现手机读写NFC卡的功能。经过反复测试,我发现市面上常见的MifareUltralight卡(芯片型号215)是个不错的选择,价格便宜(1-2元/张)且兼容性好。但实际开发过程中,Android和iOS平台的差异让我踩了不少坑,特别是iOS的读写限制让人头疼。

如果你是刚接触NFC开发的工程师,可能会遇到这些问题:为什么同样的卡在安卓上能直接读写,在iPhone上却只能读不能写?为什么读取的卡号显示乱码?如何正确设置卡的Lock位?这篇文章将用最直白的语言,带你完整走通Android和iOS双平台的开发流程。

2. 开发环境准备

2.1 硬件选购要点

建议购买前先确认卡片参数:

  • 芯片型号必须是MifareUltralight(常见型号215)
  • 存储容量512bit(16页×4字节)
  • 支持ISO14443-3A协议

我在淘宝买的卡片单价1.5元,测试了20张全部可用。有个小技巧:让卖家提供NDEF格式测试记录,确保卡片出厂时未被错误锁定。

2.2 安卓开发环境

Android Studio配置很简单:

  1. 新建项目时最低API设为19(Android 4.4)
  2. 在AndroidManifest.xml添加权限:
<uses-permission android:name="android.permission.NFC" /> <uses-feature android:name="android.hardware.nfc" android:required="true" />
  1. 在res/xml下新建nfc_filter.xml:
<tech-list> <tech>android.nfc.tech.MifareUltralight</tech> </tech-list>

2.3 iOS开发环境配置

Xcode需要额外注意:

  1. 必须使用iPhone 7及以上机型
  2. iOS版本需≥13.0(建议用最新稳定版)
  3. 在工程配置中启用Near Field Communication Tag Reading
  4. 添加NFC权限描述:
<key>NFCReaderUsageDescription</key> <string>需要NFC权限读取门禁卡</string>

3. Android端核心开发

3.1 基础读写实现

先初始化NFC适配器:

NfcAdapter nfcAdapter = NfcAdapter.getDefaultAdapter(this); PendingIntent pendingIntent = PendingIntent.getActivity( this, 0, new Intent(this, getClass()) .addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP), 0);

重写onNewIntent处理卡片感应:

@Override protected void onNewIntent(Intent intent) { super.onNewIntent(intent); Tag tag = intent.getParcelableExtra(NfcAdapter.EXTRA_TAG); if (tag != null) { readCard(tag); // 自定义读取方法 } }

3.2 关键代码解析

读取序列号的正确姿势:

public String readSerialNumber(Tag tag) throws Exception { MifareUltralight mu = MifareUltralight.get(tag); try { mu.connect(); byte[] page0 = mu.readPages(0); byte[] page1 = mu.readPages(1); // 组合SN0-SN6共7字节 byte[] sn = new byte[7]; System.arraycopy(page0, 0, sn, 0, 3); System.arraycopy(page1, 0, sn, 3, 4); return bytesToHex(sn); // 转16进制字符串 } finally { mu.close(); } }

写入Lock位的注意事项:

public void lockPages(Tag tag, int startPage) throws Exception { MifareUltralight mu = MifareUltralight.get(tag); try { mu.connect(); // 计算lock位(示例锁定4-7页) byte lock0 = (byte) 0b00001111; // 前4页不锁 byte lock1 = (byte) 0b11110000; // 后4页锁定 mu.writePage(2, new byte[]{0, 0, lock0, lock1}); } finally { mu.close(); } }

4. iOS端特殊处理

4.1 读取限制突破方案

由于iOS的封闭性,实测发现:

  1. 无法直接读取原始序列号
  2. 必须先用安卓写入NDEF消息
  3. iPhone只能读取NDEF格式内容

解决方案分三步:

  1. 在Android设备上用NXP TagWriter写入测试数据
  2. 格式选择"Text"类型
  3. 内容建议包含卡号(如"Card:XXXXXX")

4.2 Swift实现代码

初始化阅读会话:

import CoreNFC class NFCReader: NSObject, NFCNDEFReaderSessionDelegate { func beginScan() { guard NFCNDEFReaderSession.readingAvailable else { print("设备不支持NFC") return } let session = NFCNDEFReaderSession( delegate: self, queue: nil, invalidateAfterFirstRead: true) session.begin() } func readerSession(_ session: NFCNDEFReaderSession, didDetectNDEFs messages: [NFCNDEFMessage]) { for message in messages { for record in message.records { if let payload = String(data: record.payload, encoding: .utf8) { print("读取到数据: \(payload)") } } } } }

5. 避坑指南

5.1 常见问题排查

  1. 读取返回空数据?
  • 检查卡片是否已锁定
  • 确认使用了正确的readPages参数
  1. 写入失败?
  • Page2-3是特殊控制页,不要随意写入
  • 确保没有重复锁定已锁定的页
  1. iOS无法识别?
  • 必须先用安卓写入NDEF格式数据
  • 检查iPhone的NFC功能是否开启

5.2 安全注意事项

  1. Lock位一旦设置无法撤销
  2. Page3是OTP区,写入后永久不可改
  3. 建议先读取全部数据备份后再操作

实际项目中,我遇到过团队小伙伴误锁整张卡的情况。后来我们建立了标准操作流程:开发阶段使用未锁定卡片,正式环境才启用写保护。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询