如何用Kotlin实现Android与iOS设备间NFC UID互读
Android端(Kotlin)实现NFC UID互读方案
一、权限与配置
首先在AndroidManifest.xml中添加必要权限和NFC相关配置:
<!-- NFC权限 --> <uses-permission android:name="android.permission.NFC" /> <!-- 声明设备必须支持NFC --> <uses-feature android:name="android.hardware.nfc" android:required="true" /> <!-- 处理NFC事件的Activity配置 --> <activity android:name=".MainActivity"> <intent-filter> <action android:name="android.nfc.action.NDEF_DISCOVERED" /> <category android:name="android.intent.category.DEFAULT" /> <data android:mimeType="text/plain" /> </intent-filter> <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,指定支持的NFC技术类型:
<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>
二、Kotlin代码实现
1. 初始化NFC组件
在Activity中完成NFC适配器初始化,检查设备NFC支持状态:
import android.nfc.NfcAdapter import android.nfc.NfcManager import android.nfc.Tag import android.nfc.tech.Ndef import android.nfc.tech.NdefFormatable import android.content.Intent import android.os.Bundle import android.widget.TextView import androidx.appcompat.app.AppCompatActivity class MainActivity : AppCompatActivity() { private var nfcAdapter: NfcAdapter? = null private lateinit var deviceUidTv: TextView private lateinit var receivedUidTv: TextView override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_main) deviceUidTv = findViewById(R.id.tv_device_uid) receivedUidTv = findViewById(R.id.tv_received_uid) // 检查设备NFC支持情况 val nfcManager = getSystemService(NFC_SERVICE) as NfcManager nfcAdapter = nfcManager.defaultAdapter when { nfcAdapter == null -> deviceUidTv.text = "设备不支持NFC" !nfcAdapter!!.isEnabled -> deviceUidTv.text = "请先开启NFC" } } }
2. 前台调度与Intent处理
在Activity的生命周期中管理前台调度,确保App优先捕获NFC事件:
override fun onResume() { super.onResume() nfcAdapter?.let { adapter -> val pendingIntent = PendingIntent.getActivity( this, 0, intent.addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP), PendingIntent.FLAG_MUTABLE or PendingIntent.FLAG_UPDATE_CURRENT ) adapter.enableForegroundDispatch(this, pendingIntent, null, null) } } override fun onPause() { super.onPause() nfcAdapter?.disableForegroundDispatch(this) } override fun onNewIntent(intent: Intent?) { super.onNewIntent(intent) intent?.let { handleNfcIntent(it) } }
3. 读取对方UID并发送自身UID
实现核心逻辑,处理NFC标签的读取与写入:
private fun handleNfcIntent(intent: Intent) { val tag = intent.getParcelableExtra<Tag>(NfcAdapter.EXTRA_TAG) ?: return // 获取并显示当前设备的NFC UID val deviceUid = tag.id?.joinToString(separator = ":") { String.format("%02X", it) } ?: "无法获取UID" deviceUidTv.text = "当前设备UID: $deviceUid" // 读取对方设备发送的UID readNdefMessage(tag)?.let { receivedUid -> receivedUidTv.text = "收到对方UID: $receivedUid" } // 将自身UID写入对方设备(支持NDEF的设备) writeNdefMessage(tag, deviceUid) } private fun readNdefMessage(tag: Tag): String? { return try { val ndef = Ndef.get(tag) ndef.connect() val payload = ndef.ndefMessage.records[0].payload // 解析UTF-8格式的NDEF数据 String(payload, 1, payload.size - 1, Charsets.UTF_8) } catch (e: Exception) { null } finally { Ndef.get(tag)?.close() } } private fun writeNdefMessage(tag: Tag, uid: String) { try { val ndef = Ndef.get(tag) if (ndef != null) { ndef.connect() if (!ndef.isWritable) return // 创建文本类型的NDEF记录 val record = NdefRecord.createTextRecord("en", uid) val message = NdefMessage(arrayOf(record)) ndef.writeNdefMessage(message) } else { // 对未格式化的标签进行格式化并写入 val formatable = NdefFormatable.get(tag) formatable?.let { it.connect() it.format(NdefMessage(arrayOf(NdefRecord.createTextRecord("en", uid)))) it.close() } } } catch (e: Exception) { e.printStackTrace() } finally { Ndef.get(tag)?.close() NdefFormatable.get(tag)?.close() } }
三、iOS端配合要点
iOS端需使用CoreNFC框架完成对应逻辑:
- 在
Info.plist中添加NFCReaderUsageDescription权限描述 - 使用
NFCNDEFReaderSession读取Android设备发送的NDEF消息 - 使用
NFCNDEFWriterSession将自身UID写入Android设备
关键注意事项
- 部分Android机型默认开启NFC UID随机化,需在系统设置中关闭“NFC安全”类选项才能获取固定UID
- iOS仅在13+版本支持NFC读取,14+版本支持NDEF写入
- 双方设备需保持近距离接触,且均开启NFC功能
- 仅App在前台运行时能正常处理NFC事件,后台NFC存在功能限制
内容的提问来源于stack exchange,提问作者Sparx it solutions
相关产品推荐
相关产品推荐

