跨平台实战:Android Studio与iOS手机读写MifareUltralight NFC卡的完整流程与避坑指南

张开发
2026/4/18 5:00:23 15 分钟阅读

分享文章

跨平台实战:Android Studio与iOS手机读写MifareUltralight NFC卡的完整流程与避坑指南
1. 跨平台NFC开发入门指南最近在做一个智能门禁项目时需要实现手机读写NFC卡的功能。经过反复测试我发现市面上常见的MifareUltralight卡芯片型号215是个不错的选择价格便宜1-2元/张且兼容性好。但实际开发过程中Android和iOS平台的差异让我踩了不少坑特别是iOS的读写限制让人头疼。如果你是刚接触NFC开发的工程师可能会遇到这些问题为什么同样的卡在安卓上能直接读写在iPhone上却只能读不能写为什么读取的卡号显示乱码如何正确设置卡的Lock位这篇文章将用最直白的语言带你完整走通Android和iOS双平台的开发流程。2. 开发环境准备2.1 硬件选购要点建议购买前先确认卡片参数芯片型号必须是MifareUltralight常见型号215存储容量512bit16页×4字节支持ISO14443-3A协议我在淘宝买的卡片单价1.5元测试了20张全部可用。有个小技巧让卖家提供NDEF格式测试记录确保卡片出厂时未被错误锁定。2.2 安卓开发环境Android Studio配置很简单新建项目时最低API设为19Android 4.4在AndroidManifest.xml添加权限uses-permission android:nameandroid.permission.NFC / uses-feature android:nameandroid.hardware.nfc android:requiredtrue /在res/xml下新建nfc_filter.xmltech-list techandroid.nfc.tech.MifareUltralight/tech /tech-list2.3 iOS开发环境配置Xcode需要额外注意必须使用iPhone 7及以上机型iOS版本需≥13.0建议用最新稳定版在工程配置中启用Near Field Communication Tag Reading添加NFC权限描述keyNFCReaderUsageDescription/key string需要NFC权限读取门禁卡/string3. 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的封闭性实测发现无法直接读取原始序列号必须先用安卓写入NDEF消息iPhone只能读取NDEF格式内容解决方案分三步在Android设备上用NXP TagWriter写入测试数据格式选择Text类型内容建议包含卡号如Card:XXXXXX4.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 常见问题排查读取返回空数据检查卡片是否已锁定确认使用了正确的readPages参数写入失败Page2-3是特殊控制页不要随意写入确保没有重复锁定已锁定的页iOS无法识别必须先用安卓写入NDEF格式数据检查iPhone的NFC功能是否开启5.2 安全注意事项Lock位一旦设置无法撤销Page3是OTP区写入后永久不可改建议先读取全部数据备份后再操作实际项目中我遇到过团队小伙伴误锁整张卡的情况。后来我们建立了标准操作流程开发阶段使用未锁定卡片正式环境才启用写保护。

更多文章