本文目录导读:

通用检测思路
硬件层面检测
- 检查NFC功能是否开启
- 检测NFC硬件是否可用
- 监听NFC标签发现事件
数据层面检测
- 读取标签ID(唯一标识)
- 检查数据完整性(CRC校验)
- 验证数据格式是否符合预期
Android平台(Java/Kotlin)
// 1. 检查NFC硬件和功能
val nfcAdapter = NfcAdapter.getDefaultAdapter(context)
if (nfcAdapter == null) {
// 设备不支持NFC
} else if (!nfcAdapter.isEnabled()) {
// NFC功能未开启
}
// 2. 监听标签发现
class NfcReaderActivity : AppCompatActivity() {
override fun onNewIntent(intent: Intent) {
super.onNewIntent(intent)
if (NfcAdapter.ACTION_TAG_DISCOVERED == intent.action) {
val tag = intent.getParcelableExtra<Tag>(NfcAdapter.EXTRA_TAG)
// 读取标签ID
val tagId = tag.id
// 尝试读取NDEF数据
if (NfcAdapter.ACTION_NDEF_DISCOVERED == intent.action) {
val messages = intent.getParcelableArrayExtra(NfcAdapter.EXTRA_NDEF_MESSAGES)
// 解析NDEF消息
}
// 检测读取是否成功
if (tagId != null && tagId.isNotEmpty()) {
// 读取正常
}
}
}
}
// 3. 错误处理
try {
// 读取操作
} catch (e: IOException) {
// 读取失败
} catch (e: FormatException) {
// 数据格式错误
}
iOS平台(Swift)
import CoreNFC
class NFCReader: NSObject, NFCReaderSessionDelegate {
var session: NFCNDEFReaderSession?
func beginScanning() {
guard NFCNDEFReaderSession.readingAvailable else {
// 设备不支持NFC
return
}
session = NFCNDEFReaderSession(delegate: self, queue: nil, invalidateAfterFirstRead: false)
session?.begin()
}
// 成功发现标签
func readerSession(_ session: NFCNDEFReaderSession, didDetectNDEFs messages: [NFCNDEFMessage]) {
for message in messages {
for record in message.records {
let payload = record.payload
// 解析数据
// 检测读取状态
if payload.count > 0 {
// 读取正常
}
}
}
}
// 读取失败
func readerSession(_ session: NFCNDEFReaderSession, didInvalidateWithError error: Error) {
// 处理错误(标签移除、超时、格式错误等)
}
}
Web(Web NFC API)
// 浏览器支持检测
if ('NDEFReader' in window) {
const ndef = new NDEFReader();
// 开始扫描
ndef.scan().then(() => {
console.log("扫描已启动");
ndef.addEventListener("reading", ({ message, serialNumber }) => {
// serialNumber - 标签ID
// message - NDEF消息
// 读取数据
for (const record of message.records) {
const decoder = new TextDecoder();
console.log("记录类型: " + record.recordType);
console.log("数据: " + decoder.decode(record.data));
}
// 检测读取状态
if (serialNumber) {
console.log("读取正常, 标签ID: " + serialNumber);
}
});
ndef.addEventListener("readingerror", () => {
console.log("读取失败: 标签可能损坏或格式错误");
});
}).catch(error => {
console.log("扫描启动失败: " + error);
});
} else {
console.log("浏览器不支持NFC");
}
// 高级检测 - 读取超时
const timeoutId = setTimeout(() => {
// 10秒未读取到标签
console.log("读取超时");
}, 10000);
检测指标
成功读取指标
// 通用检测条件
const isReadSuccessful = {
hasValidId: tagId !== null && tagId.length > 0,
hasValidData: dataChecksum === calculatedChecksum,
dataFormatValid: validateDataFormat(rawData),
readTime: readDuration < 2000 // 2秒内完成
};
常见异常检测
| 异常类型 | 检测方式 |
|---|---|
| 硬件不可用 | 检查NFC适配器/控制器 |
| 功能未开启 | 检查系统设置 |
| 标签脱离 | 监听断开事件 |
| 数据损坏 | CRC校验失败 |
| 格式错误 | 预期格式不匹配 |
| 读取超时 | 设置超时定时器 |
完整检测示例(Android)
class NfcHealthChecker {
enum class NfcStatus {
NOT_SUPPORTED, // 不支持
DISABLED, // 未开启
SCANNING, // 扫描中
READING, // 读取中
COMPLETE, // 读取完成
ERROR // 出错
}
fun checkNfcHealth(context: Context, tag: Tag): NfcStatus {
// 1. 硬件检查
val adapter = NfcAdapter.getDefaultAdapter(context)
if (adapter == null) return NfcStatus.NOT_SUPPORTED
if (!adapter.isEnabled) return NfcStatus.DISABLED
// 2. 标签连接检查
return try {
val techList = tag.techList
if (techList.isEmpty()) return NfcStatus.ERROR
// 3. 读取测试
val ndef = Ndef.get(tag)
if (ndef != null) {
ndef.connect()
val message = ndef.ndefMessage
// 4. 数据完整性检查
if (message?.records?.isNotEmpty() == true) {
NfcStatus.COMPLETE
} else {
NfcStatus.ERROR
}
} else {
NfcStatus.SCANNING
}
} catch (e: Exception) {
NfcStatus.ERROR
}
}
}
最佳实践
- 异步处理:NFC读取是异步操作,不要阻塞主线程
- 超时处理:设置合理的超时时间(通常2-5秒)
- 重试机制:失败时允许用户重试
- 用户反馈:显示读取状态提示
- 错误分级:区分硬件问题、格式错误、数据损坏等
通过以上方法,可以全面检测NFC标签读取是否正常,并给出相应的状态反馈。