如何保证Android应用写入NFC标签时无标签场景不会发生崩溃
问题根因
你当前遇到的空指针异常完全来自代码执行顺序的逻辑错误:
- 你将
val ndef = Ndef.get(tag)放在了checkNFCStatus(tag)校验逻辑之前,当用户全程没有放置标签、入参tag为null时,Ndef.get方法会直接调用tag的hasTech方法,根本走不到后面的校验逻辑就触发空指针。 - 额外的冗余逻辑问题:
checkNFCStatus方法内部已经做了一次Ndef对象的获取、连接、断开操作,两次操作的间隙标签可能被用户移走,会导致你后续拿到的Ndef对象依然不可用。
修复后的代码
@Throws(IOException::class, FormatException::class) fun write(text: String, tag: Tag?, context: Context): Boolean { // 先校验tag非空,直接拦截无标签场景 if (tag == null) { DebugUtils().showToast( context, "请调整卡片位置,设备未检测到有效NFC标签" ) return false } val records = arrayOf(createRecord(text)) val message = NdefMessage(records) val ndef = Ndef.get(tag) try { ndef.connect() if (!ndef.isConnected) { Log.d("MAIN", "NDEF未连接") DebugUtils().showToast( context, "请调整卡片位置,设备未检测到有效NFC标签" ) return false } Log.d(TAG, "ndef类型 : " + ndef.type) Log.d(TAG, "ndef消息内容 : ${ndef.ndefMessage}") if (ndef.isWritable) { Log.d("MAIN", "NDEF标签可写入") ndef.writeNdefMessage(message) return true } else { Log.d("MAIN", "NDEF标签只读") DebugUtils().showToast(context, "当前NFC标签为只读状态,无法写入内容") return false } } catch (e: IOException) { e.printStackTrace() DebugUtils().showToast( context, "请调整卡片位置,设备未检测到有效NFC标签" ) return false } finally { // 统一在finally里关闭连接,避免异常时资源泄漏 if (ndef.isConnected) { ndef.close() } } }
优化说明
- 方法入口先判断tag是否为空,直接拦截用户全程未放标签的场景,避免空指针
- 移除了冗余的checkNFCStatus重复连接逻辑,将状态校验和写入逻辑合并,减少中间状态异常的概率
- 增加finally块统一关闭NFC连接,避免异常触发时资源泄漏
- 新增只读标签的提示,覆盖更多异常场景
内容的提问来源于stack exchange,提问作者James
相关产品推荐
相关产品推荐

