简介这份《NFC程序设计三自动运行程序》PPT课件面向Android NFC开发初学者与移动开发学习者系统讲解NDEF标签读写、Uri格式结构、Android应用程序记录AAR及前台调度系统等核心知识点。资源为单份PPT文档压缩包大小仅542KB内容紧凑精炼适合课堂学习或自学复习。目前已有85人学习下载。课件沿课程节奏展开包含上次作业回顾、预习检查、NDEF文本格式与Uri格式的详细结构说明、AAR记录的创建方法以及通过标签自动运行程序和打开网页的完整流程并附有电子名片标签编写等应用示例与课后作业。其中对NDEF payload结构、状态字节、语言编码、Uri前缀表、NdefRecord常用方法等细节均有直观展示便于对照理解和实际编码。对希望快速理解NFC事件处理、NdefMessage解析与写入机制、前台调度配置的开发者而言这份课件能提供清晰的思路和可直接参考的代码要点。 做NFC开发这些年最让我觉得神奇的时刻不是读卡写卡那些基础操作而是手机靠近标签那一下App自己弹出来、页面自动跳转——整个过程手都不用碰屏幕。NFC程序设计里管这个叫“自动运行程序”也是很多实际项目里最出效果的一环。这篇文章就是围绕这个主题把底层的触发原理、三种主流实现方式、完整的标签写入流程和调试中的坑都梳理一遍适合刚接触NFC程序设计的开发者参考也适合产品、方案选型阶段的小伙伴了解自动运行能做到什么程度。1. 为什么NFC能实现“贴一下就走”的自动拉起1.1 从一次贴标签说起NDEF消息与系统分发先还原一下最常见的场景你把手机靠近一张贴在展板上的NFC标签手机屏幕自动亮起跳转到某个App的具体页面。这个过程的源头在于标签里存了一段NDEF消息也就是NFC论坛定义的标准数据格式。NDEF的全称是NFC Data Exchange Format它不关心底层是Mifare Classic还是NTAG芯片统一封装成一条一条的记录Record。每条记录有自己的类型比如URI记录、文本记录、MIME类型记录还有后面要重点讲的应用程序记录AAR。当手机靠近标签时NFC控制器把标签里的NDEF消息读出来交给系统服务解析。Android系统根据记录类型做一次“分发”匹配到哪一类Intent过滤器就把数据打包成Intent拉起对应的App。这里有一个关键点系统在分发时有明确优先级不是所有记录一起拉。优先处理的是AAR记录其次是MIME/URI类型的NDEF_DISCOVERED然后是TECH_DISCOVERED最后才是所有标签通吃的TAG_DISCOVERED。理解这条分发链调试自动运行才会有的放矢。1.2 哪些业务适合用NFC自动运行一开始接触NFC程序设计时我误以为“自动运行”就是用来做投放广告、扫一下就打开营销页面的。实际做下来发现价值更大的场景恰恰是那些讲究“快速、离线、不打扰”的线下触点设备配网与绑定手机贴着路由器、智能音箱上的标签自动打开App对应配置页免去手动找菜单。巡更巡检安保人员拿着手机沿路贴一下各点位标签自动记录当前时间、人员、位置不用开App做任何操作。会议签到与访客登记贴一下桌面标签自动唤起签到页面体验比扫码更顺。门店导购与售后入口商品标签关联在线说明书、保修登记页客户贴着就能进。防伪溯源与信息查询标签里写入加密认证信息App识别后自动跳转验证结果页。这些场景的共同特点是操作对象是线下实体操作动作是做减法。NFC自动运行刚好把“打开App、找入口、扫码”这些步骤压缩成“贴一下”。明白这点再看后面的技术选型就会更清楚。2. 自动启动方案选型三种路线怎么选2.1 Tag Dispatch系统级intent-filter拉起最简单、也最常用的一种方式是在AndroidManifest.xml里给Activity声明NFC相关的intent-filter让系统在读到标签后直接拉起应用。这个机制叫Tag Dispatch它对用户来说完全是透明的——没有弹窗、没有确认系统自动完成匹配和跳转。实际操作中你需要在Manifest里加权限和设备特性声明uses-permission android:nameandroid.permission.NFC / uses-feature android:nameandroid.hardware.nfc android:requiredtrue /然后在Activity里声明NDEF_DISCOVERED过滤器。如果标签里存的是MIME类型记录可以这样写intent-filter action android:nameandroid.nfc.action.NDEF_DISCOVERED / data android:mimeTypeapplication/com.example.myapp / /intent-filter如果标签里存的是URL也可以按URI来匹配intent-filter action android:nameandroid.nfc.action.NDEF_DISCOVERED / data android:schemehttps android:hostexample.com / /intent-filter注意这个方案的优点是无侵入、实现快但有个天然短板它依赖系统自动识别来分发。如果手机里装了多个能匹配这个Intent的应用系统会弹一个“选择打开方式”的列表自动运行就变成了两选一。所以它更适合作为兜底方案保证最基础的拉起能力。2.2 Foreground Dispatch前台应用优先抢单还有一种情况是应用本身已经在前台比如已经打开了一个扫码页面用户这时又贴了一枚标签。系统默认会优先把标签事件交给处于前台的Activity如果你不用前台调度这个事件会被系统分发走结果就是App还在当前页面但背后新开了另一个Activity体验很割裂。Foreground Dispatch就是对这个问题的解法。核心代码如下NfcAdapter nfcAdapter NfcAdapter.getDefaultAdapter(this); PendingIntent pendingIntent PendingIntent.getActivity( this, 0, new Intent(this, getClass()).addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP), PendingIntent.FLAG_UPDATE_CURRENT ); IntentFilter ndefFilter new IntentFilter(NfcAdapter.ACTION_NDEF_DISCOVERED); try { ndefFilter.addDataType(*/*); // 按实际需求收紧MIME类型 } catch (IntentFilter.MalformedMimeTypeException e) { e.printStackTrace(); } IntentFilter[] filters { ndefFilter }; String[][] techLists { { Ndef.class.getName() } }; // onResume中启用 nfcAdapter.enableForegroundDispatch(this, pendingIntent, filters, techLists);同时在onPause里调用disableForegroundDispatch关闭生命周期一定要成对出现Override protected void onPause() { super.onPause(); if (nfcAdapter ! null) { nfcAdapter.disableForegroundDispatch(this); } }标签数据最终在onNewIntent里拿到。因为Activity设了SingleTop模式贴标签时不会新建实例只回调新IntentOverride protected void onNewIntent(Intent intent) { super.onNewIntent(intent); setIntent(intent); parseNfcTag(intent); }这个方案适合“App已经开着等待用户贴标签”的主动操作场景比如巡更软件进入巡检模式后等待操作员逐点贴卡。它不解决App没启动时的拉起问题所以通常会和Tag Dispatch组合使用。2.3 AAR记录把启动权写死在标签里AAR的全称是Android Application Record翻译过来就是“Android应用记录”。它的作用是明确告诉系统“这枚标签只能由某个包名的App处理”系统读到AAR后会直接按照包名去拉起应用如果这个应用没安装系统还会跳转到应用市场搜索页。AAR记录本质上也是NDEF消息里的一条Record包名放在payload里。一条NDEF消息可以包含多条记录最常见的组合是“URI记录 AAR记录”URI负责告诉App用户要去哪个页面AAR负责把App强制拉起来。这个组合也是目前设备厂商、智能海报用得最多的做法。和Tag Dispatch相比AAR的“强制性”最明显的优势是避免多应用冲突弹窗。你在活动海报前贴了含AAR的标签不管用户手机里装没装你的App系统都会按你指定的包名去处理不会跳出“用哪个应用打开”的选择列表。2.4 方案对比和选择建议为了方便对照我把三种方式的使用场景整理成了一张表方案触发前提是否强制指定应用适合场景主要缺点Tag DispatchApp已安装否可能弹选择列表通用兜底、低成本拉起多应用时体验不确定Foreground DispatchApp已在前台是当前前台优先巡检、签到等主动贴卡场景App不在前台时不生效AAR记录App已安装未装则跳商店是智能海报、设备配网、强制拉起标签写入需要额外构造记录我的建议是项目里优先保证Tag Dispatch能兜底前台主动交互的场景再叠加Foreground Dispatch对外投放的标签内容一律用“URI AAR”组合。这三者不是互斥关系而是不同层级下的配合想清楚触发链路是哪个阶段代码就不会写成一团浆糊。3. 动手实操从NDEF构造到标签写入3.1 准备阶段标签、手机和工具先说明一下硬件选型这部分踩过不少坑。NFC标签建议选NTAG213或NTAG215原因有两个一是通讯协议稳定手机兼容性好二是官方支持NDEF格式化写入后不需要额外处理扇区。容量上NTAG213是180字节NTAG215是540字节写几条记录绰绰有余。如果你手边只有Mifare Classic也就是常说的M1卡也不是不能用但要注意两点一是M1卡需要先格式化出NDEF区域很多非NFC论坛标准的卡写入后安卓不认二是有扇区加密问题后面排查部分会细说。手机方面没有太高门槛近几年的安卓手机基本都支持NFCiOS设备从iPhone XS之后也支持后台标签读取但这里以Android为例做代码实现。电脑端写标签工具我用得比较多的是NFC Tools简单方便手机就能直接写。需要批量写卡或者做扇区级调试时再用电脑端的NFC Reader Tool配合PC读卡器操作注意NDEF格式的标签用标准工具页写就行不需要深入扇区。如果只是想验证标签内容和扇区结构用NXP官方的TagInfo看看最直观。3.2 手工构造NDEF消息URI记录AAR记录很多教程会直接给你现成的NFC Tools操作截图但我觉得搞开发的人还是要搞清楚NDEF消息的二进制结构否则标签写错了都不知道错在哪里。一条NDEF记录的开头是几个关键字节第一个字节是flags比如0xD1表示“这是一条短记录、消息开始、消息结束、MB/ME都置1”第二个字节是类型长度第三个字节是载荷长度后面跟着类型和载荷内容。拿最常用的URI Record举例它的十六进制长这样D1 01 0F 55 03 68 74 74 70 3A 2F 2F 65 78 61 6D 70 6C 65 2E 63 6F 6D逐字节拆开看D1短记录标志、消息开始和结束01类型长度是1个字节类型就是后面的55即字母“U”0F载荷长度15字节注意这里不含类型长度55记录类型是URI03是URI前缀标识03代表“http://”04代表“https://”后面从68 74 74 70开始就是“http://example.com”去掉前缀后的剩余部分AAR记录的格式更固定以包名com.example.myapp为例D1 02 0B 61 6E 64 72 6F 69 64 2E 63 6F 6D 3A 63 6F 6D 2E 65 78 61 6D 70 6C 65 2E 6D 79 61 70 70拆开看D1同短记录标志02类型长度2字节0B载荷长度11字节指的是包名那部分长度61 6E 64 72 6F 69 64 2E 63 6F 6DASCII码的android.com3A冒号包名本身如果你不想自己拼字节也可以直接用现成的库。安卓官方在后台解析时用的是NdefMessage包构造时可以这样写NdefMessage createNdefMessage() { NdefRecord uriRecord NdefRecord.createUri(https://example.com/nfc); // AAR需要自己构造或者用NdefRecord.createApplicationRecord NdefRecord aarRecord NdefRecord.createApplicationRecord(com.example.myapp); return new NdefMessage(new NdefRecord[] { uriRecord, aarRecord }); }注意细节AAR记录在NdefMessage里的位置可以放在开头或者结尾但多条记录交换时建议按“业务记录在前、AAR在后”的顺序部分老版本系统对AAR记录位置比较挑剔后放更稳妥。3.3 把消息写进NFC标签这里给一个手机上用NFC Tools写入NDEF消息的操作路径清理标签数据确认标签显示为“已格式化”选择“添加记录”先添加URL记录或文本记录再添加“应用程序包名”记录对应AAR确认记录顺序后执行写入写入成功后会提示校验通过。如果用电脑端工具批量写建议准备一个支持NFC的USB读卡器比如ACR122U。批量前先拿一两张标签做小批量测试把“空标签”“半格式化标签”“容量不足标签”这三种情况都验证一遍再上机全量写能避免一坏坏一批。写入完成后立刻验证这一点容易被忽略。验证分两层第一层是拿NFC Tools重新读回标签看NDEF消息是否完整、记录类型是否与你写入的一致第二层是换一台手机实测贴一下确认真的能拉起App。能读出来不代表能忽悠系统正确分发第二层验证必不可少。3.4 Android端配置与代码实现标签写好了App这边也要配套否则就算标签能读也没人能处理。除了之前展示过的Manifest配置还有一个细节容易被忽略处理NFC的Activity最好不做进程常驻或手势解锁限制。有些项目里App本身有启动页、登录页标签一旦拉起来用户看到的是启动页而不是具体页面体验会打折。实际项目中我习惯单独做一个NfcDispatchActivity它只负责解析Intent里的NDEF消息把数据路由到具体业务页面然后立刻finish掉自己。这样做的好处是避免把业务逻辑直接耦合在入口Activity里后期维护、配置调整都不用动主流程。Activity接收Intent后核心代码如下NdefMessage getNdefMessage(Intent intent) { if (NfcAdapter.ACTION_NDEF_DISCOVERED.equals(intent.getAction())) { Parcelable[] rawMessages intent.getParcelableArrayExtra(NfcAdapter.EXTRA_NDEF_MESSAGES); if (rawMessages ! null rawMessages.length 0) { return (NdefMessage) rawMessages[0]; } } return null; }拿到NdefMessage之后遍历NdefRecord根据类型判断是URI、文本还是AAR。需要注意Android系统在拉起App前已经把AAR“消费”掉了业务侧拿到的时候AAR可能不在记录列表里所以不要依赖业务代码读取AARAAR的作用是系统分发的“靶心”URI记录才是业务数据载体。4. 踩坑实录调试中的常见问题4.1 贴标签没反应检查哪里这是被问得最多的问题没有之一。按我自己的排查顺序整理成了一张速查表现象可能原因解决办法标签贴上去毫无反应手机NFC开关没开打开NFC开关部分机型还要开启“读卡器模式”有提示“不支持NFC”手机硬件不支持或系统版本过旧换测试机或下放支持方案能读出标签但App不弹Manifest里intent-filter类型和标签记录类型不匹配用TagInfo看标签实际记录类型再对齐代码能读到但弹窗让你选择App没有AAR记录且装了多个能匹配的App标签里补一条AAR记录App启动后闪退NdefMessage解析异常或页面路由出错加日志看Intent内容单独调试解析模块标签写不进数据标签528字节满或标签被写保护换容量更大的标签或做去保护操作有一个细节值得单独提醒就是“标签格式”问题。有的标签出厂带的是URL记录结果你在TagInfo里看它是text记录于是App只写了文本解析逻辑怎么也触发不了。这类问题通常不是代码错而是数据错先读标签再下结论。4.2 多应用抢弹窗没有AAR的时候Android系统会弹出一个选择器列出所有能处理这条NDEF消息的App。我在调试时为了方便装了好几个NFC工具类软件结果每次测试都被弹窗打断还以为是代码坏了。后来明确两点一是生产环境标签务必写AAR二是几个NFC工具软件尽量从测试机卸载只保留一个NFC Tools做写入、一个TagInfo做检查避免干扰判断。另外部分浏览器也会注册NDEF处理能力尤其是URL记录。如果标签里的URL是http/https开头系统可能会弹出“是否用浏览器打开”——这也是AAR能压住的行为。使用AAR后系统会优先把它作为启动指定应用规避浏览器接管。4.3 NFC标签的兼容性与容量坑标签老化、天线尺寸、贴纸材质都会影响读取这一点做过线下投放的人应该深有感触。金属表面的标签天线会严重衰减信号金属货架上的标签要选铁氧体抗金属标签玻璃、亚克力表面相对容易识别但标签要贴在平整面上弯折会破坏天线谐振频率。容量方面很多人会忽略AAR记录占据的空间。别看它只是几十字节的载荷但每一条NDEF记录都有头部开销写入时NFC Tools会显示已用字节一定要留出安全余量。之前遇到过标签刚好写满换个设备读出来的记录被截断的情况这类问题数据层面根本没报错排查起来特别费力。还有一点是NFC芯片类型差异。Mifare ClassicM1卡和NTAG的NDEF实现有区别M1卡不是原生NDEF标签需要工具软件先把卡的某个扇区映射成NDEF容器再用Android Ndef类读写。如果你在用TagInfo看M1卡时发现看不到NDEF先确认扇区是否做了映射别急着怀疑读卡器坏了。4.4 安全红线中继与伪标签风险提醒自动运行给用户带来了便利也意味着任何人靠近你手机几厘米内都可能触发一次分发。前两年行业内讨论比较多的“NFC中继攻击”利用的是NFC信号可以被转发、标签内容可以被仿制的特点。比如有人把恶意URL写入仿制标签张贴在公共场所用户一贴就被引导到钓鱼页面。这类风险必须在项目设计阶段就考虑进去。我的建议是做到三条第一标签内容不存敏感参数只存业务ID或跳转标识真正的数据在校验后从服务端拉取第二涉及支付、门禁、权益核销这类高价值场景App内必须二次校验签名不能只依赖URI跳转第三对用户侧做好提示不要建议用户去贴不明来源的标签尤其是陌生人张贴、无品牌标识的卡片。顺便提醒一下NFC标签本身不具备防克隆的硬件级保护普通NTAG和M1卡都很容易被复制内容所以“标签里写着XX就代表XX可信”这种思路是危险的。真正要防仿冒得靠服务端密钥体系而不是标签本身。这不是NFC程序设计能单独解决的安全问题但架构上必须给业务侧留好校验接口。最后再多说一句实操心得自动运行的难点往往不在写代码而在把标签数据、分发机制、业务路由这三件事对齐。标签里写什么、系统怎么分发、App怎么接每一条链路都要自己亲手捋一遍才踏实。我每次交付项目都会亲手用三台不同品牌的手机实测贴标签一台通过不算数至少覆盖主流机型之后才敢说自动运行功能真的能交付。本文还有配套的精品资源点击获取
