概述
NFC(近场通信)在门禁卡、公交卡、支付等场景广泛使用。本文说明App Inventor 2中NFC的能力边界和实现方法。
⚠️ 重要限制
App Inventor不能复制门禁卡! 原因:
- 大多数门禁卡使用加密扇区(如Mifare Classic的Key A/B)
- 复制门禁卡需要专门的NFC写入硬件
- Android系统限制了NFC卡模拟的权限
- 这涉及安全和法律问题
App Inventor能做的:
- 读取NFC标签的基本信息(UID、NDEF数据)
- 读取未加密的NFC标签内容
- 写入NDEF数据到可写标签
- 基于NFC标签触发App操作
NFC组件
组件位置
App Inventor没有内置NFC组件,需要使用扩展。推荐:
| 扩展 | 功能 | 来源 |
|---|---|---|
| NFCTools | 读写NFC标签 | 社区 |
| NfcExtension | 基本NFC读取 | GitHub |
| TaifunNFC | 读写+高级功能 | puravidaapps |
添加NFC扩展
- 下载NFC扩展.aix文件
- App Inventor → Designer → Extension → Import Extension
- 选择.aix文件导入
读取NFC标签
基本读取
when Screen1.Initialize() {
NFC1.Enabled = true
}
when NFC1.Label(标签类型, 标签ID, NDEF数据) {
标签_类型.Text = join("标签类型:", 标签类型)
标签_ID.Text = join("UID:", 标签ID)
标签_数据.Text = join("数据:", NDEF数据)
}
读取标签UID
when NFC1.Label(标签类型, 标签ID, NDEF数据) {
// UID是NFC标签的唯一标识
var UID = 标签ID
标签_UID.Text = join("卡片UID:", UID)
// 根据UID判断是哪种卡
if 标签类型 == "MifareClassic" {
标签_信息.Text = "Mifare Classic 卡(常见门禁卡)"
} else if 标签类型 == "MifareUltralight" {
标签_信息.Text = "Mifare Ultralight 卡(常见公交卡)"
} else if 标签类型 == "Ndef" {
标签_信息.Text = "NDEF 标签(可读写)"
} else if 标签类型 == "IsoDep" {
标签_信息.Text = "ISO 14443 卡(银行卡等)"
}
}
读取NDEF内容
NDEF(NFC Data Exchange Format)是NFC标准数据格式:
while NFC1.NDEF消息读取(记录列表) {
var i = 1
while i <= length(记录列表) {
var 记录 = 记录列表[i]
var 类型 = dictLookup(记录, "type", "")
var 内容 = dictLookup(记录, "payload", "")
if 类型 == "text" {
标签_内容.Text = join("文本:", 内容)
} else if 类型 == "uri" {
标签_内容.Text = join("URL:", 内容)
} else if 类型 == "smartposter" {
标签_内容.Text = join("智能海报:", 内容)
}
var i = i + 1
}
}
写入NFC标签
写入文本
while 按钮_写入被点击 {
var 文本内容 = 文本输入框_内容.Text
NFC1.Text(文本内容)
标签_状态.Text = "将NFC标签靠近手机写入..."
}
写入URL
when 按钮_写入URL.Click() {
var URL = "https://www.fun123.cn"
NFC1.写入NDEF_URI(URL)
}
实战案例:NFC门禁识别
虽然不能复制门禁卡,但可以读取卡的UID做身份识别:
设 授权UID列表 = [
"04:A3:B2:C1:D4:E5:6F", ' 张三的卡
"04:B4:C3:D2:E1:F0:7A", ' 李四的卡
"04:C5:D4:E3:F2:A1:8B" ' 王五的卡
]
设 授权名称 = [
"张三",
"李四",
"王五"
]
当 NFC1.标签检测到(标签类型, 标签ID, NDEF数据)
设 UID = 标签ID
设 索引 = 列表中(授权UID列表) 查找 UID
如果 索引 > 0
设 姓名 = 列表第索引项(授权名称)
标签_状态.文本 = "✅ 欢迎回来," & 姓名
标签_状态.文本颜色 = 绿色
' 触发开门动作(通过蓝牙/WiFi发送指令)
调用 蓝牙.发送文本("OPEN")
否则
标签_状态.文本 = "❌ 未授权的卡片"
标签_状态.文本颜色 = 红色
实战案例:NFC智能名片
将NFC标签贴在名片上,触碰后自动打开个人主页:
当 按钮_写入名片.被点击
设 名片URL = "https://example.com/mycard?" &
"name=" & 调用 Web客户端1.网址编码(文本输入框_姓名.文本) &
"&phone=" & 文本输入框_电话.文本 &
"&email=" & 文本输入框_邮箱.文本
调用 NFC1.写入NDEF_URI(名片URL)
标签_状态.文本 = "✅ 名片信息已写入NFC标签"
门禁卡知识
常见门禁卡类型
| 类型 | 加密 | 可读取 | 可复制 |
|---|---|---|---|
| Mifare Classic 1K | 部分扇区加密 | ✅UID+公开扇区 | ❌需专用设备 |
| Mifare Classic 4K | 部分扇区加密 | ✅UID+公开扇区 | ❌需专用设备 |
| Mifare Ultralight | 无/简单加密 | ✅ | ❌ |
| IC卡(ID卡, 125KHz) | 无 | ✅UID | ⚠️可复制 |
| CPU卡 | 完全加密 | ❌ | ❌ |
为什么手机不能当门禁卡?
- 硬件限制:大多数手机的NFC控制器不支持卡模拟模式(Card Emulation)
- 系统限制:Android只允许系统级应用(如Google Pay)进行卡模拟
- 安全密钥:门禁卡的加密密钥不对用户开放
- 部分手机支持:华为、小米等支持模拟未加密的门禁卡,但这不是App Inventor能实现的
与已有文档的关系
| 技术 | 已有文档 | NFC场景中的用途 |
|---|---|---|
| 蓝牙通信 | bluetooth_remote.md |
NFC识别后通过蓝牙开门 |
| Web API | api_communication.md |
上传NFC读取记录 |
| 加密 | text_encryption.md |
NFC数据加密传输 |
| 数据库 | db.md |
存储授权UID列表 |
常见问题
Q1: 能用App Inventor复制门禁卡吗?
不能。 门禁卡复制需要:专用NFC读写器(如ACR122U)、解密密钥、专用软件。手机NFC硬件不支持写入门禁卡所需的加密扇区。
Q2: 读取NFC时提示”不支持”?
- 确认手机有NFC硬件(设置→NFC→开启)
- 部分低价手机没有NFC芯片
- Android版本需要4.0+
Q3: 读取银行卡安全吗?
只读取UID和非加密数据是安全的。App Inventor无法读取银行卡的加密交易数据。
总结
| 能力 | 支持 |
|---|---|
| 读取NFC标签UID | ✅ |
| 读取NDEF数据 | ✅ |
| 写入NDEF数据 | ✅ |
| 复制门禁卡 | ❌ |
| 手机模拟门禁卡 | ❌ |
| NFC身份识别 | ✅ |
版权声明:MIT App Inventor 官方文档采用 CC BY-SA 4.0 授权,本文档由 ai2claw 🐝 整理。
扫码添加客服咨询