ARTICLE DETAIL

资讯详情

深耕网站视觉设计与运营推广的一线实战洞察。

HarmonyOS 6.0 NFC标签读写与碰一碰连接——物联网应用的近场入口

HarmonyOS 6.0 NFC标签读写与碰一碰连接——物联网应用的近场入口 手机碰一碰 NFC 标签就弹出配置页、碰一碰配网 WiFi、碰一碰开门禁——NFC 是智能家居和 IoT 场景的关键入口。HarmonyOS NEXT 提供了完整的 NFC API标签识别、NDEF 读写、前台分发优先注册。这篇把 NFC 近场通信的核心用法讲清楚。NFC 通信概览NFC近场通信的核心概念Tag标签——NFC 贴纸、NFC 卡片等被动设备NDEF——NFC 数据交换格式标准化的数据组织方式前台分发——APP 在前台时优先接收 NFC 意图AAR——Android Application Record碰一碰自动打开指定 APPimport{tag}fromkit.ConnectivityKitimport{ndef}fromkit.ConnectivityKit权限配置{ requestPermissions: [ { name: ohos.permission.NFC_TAG }, { name: ohos.permission.NFC_ADAPTER } ] }标签检测标签靠近手机时系统通过 Ability 的 onNewWant 分发 NFC 意图。// EntryAbility.etsonNewWant(want:Want,launchParam:AbilityConstant.LaunchParam):void{lettagInfo:tag.TagInfo|nullnulltry{tagInfotag.getTagInfo(want)}catch(e){return}if(tagInfonull)return// 判断标签类型if(tag.isNdef(tagInfo)){letndefTag:ndef.NdefTagndef.getNdefTag(tagInfo)// 读取 NDEF 内容}}要点getTagInfo 从 want 中提取标签信息isNdef 判断是否为 NDEF 格式标签。非 NDEF 标签如 MifareClassic用对应的 getXXXTag 方法。NDEF 读写NDEF 是最常用的 NFC 数据格式——类似JSON for NFC。读取 NDEFletndefTag:ndef.NdefTagndef.getNdefTag(tagInfo)letndefMessage:ndef.NdefMessagendefTag.getNdefMessage()letrecords:ndef.NdefRecord[]ndefMessage.getRecords()for(leti:number0;irecords.length;i){letrecord:ndef.NdefRecordrecords[i]letpayload:stringrecord.payloadasstringletrecordType:stringrecord.recordTypeasstring// URI 类型: recordType U// 文本类型: recordType T}写入 NDEF// 创建 NDEF 消息leturiRecord:ndef.NdefRecordndef.createUriRecord(https://harmonyos.com)letndefMsg:ndef.NdefMessagendef.createNdefMessage([uriRecord])// 写入标签ndefTag.writeNdef(ndefMsg)创建不同类型的 NDEF Record// URI 记录leturi:ndef.NdefRecordndef.createUriRecord(https://example.com)// 文本记录lettext:ndef.NdefRecordndef.createTextRecord(zh,你好HarmonyOS)// MIME 记录letmime:ndef.NdefRecordndef.createMimeRecord(application/json,{key:value})// AAR 记录碰一碰打开APPletaar:ndef.NdefRecordndef.createAarRecord(com.example.myapp)要点AAR 记录让手机碰标签时自动打开指定包名的 APP实现碰一碰直连。前台分发当多个 APP 都能处理 NFC 标签时前台分发让当前 APP 优先接收。import{tag}fromkit.ConnectivityKit// 注册前台分发letelementName:ElementName{bundleName:com.example.myapp,abilityName:EntryAbility}lettechList:string[][][[ndef,ndef-formatable]]tag.registerForegroundDispatch(elementName,techList)// 取消前台分发tag.unregisterForegroundDispatch(elementName)要点registerForegroundDispatch 在 Ability 的 onForeground 注册onBackground 取消。techList 指定感兴趣的标签技术类型。NFC 碰一碰场景模拟 Demo由于 NFC 需要真机 NFC 标签这里用模拟方式展示完整交互流程。interfaceNfcRecord{id:stringtype:stringcontent:stringtime:string}EntryComponentstruct NfcSimDemo{StatenfcRecords:NfcRecord[][]StatetagDetected:booleanfalseStatecurrentTagType:stringStatendefContent:stringStatewriteInput:stringhttps://harmonyos.comStatestatusMsg:string将NFC标签靠近手机...build(){Column({space:16}){Text(NFC 碰一碰模拟).fontSize(22).fontWeight(FontWeight.Bold).width(100%)Column(){Column().width(100).height(100).borderRadius(50).backgroundColor(this.tagDetected?#E8F5E9:#F5F5F5).border({width:3,color:this.tagDetected?#4CAF50:#E0E0E0,style:BorderStyle.Dashed})Text(this.tagDetected?标签已检测:等待NFC标签).fontSize(14).fontColor(this.tagDetected?#4CAF50:#999999).margin({top:8})}.width(100%).alignItems(HorizontalAlign.Center).padding(16)Row({space:8}){Button(模拟标签靠近).onClick((){this.tagDetectedtruethis.currentTagTypeNDEFthis.ndefContenthttps://harmonyos.comthis.addRecord(检测,发现NDEF标签)this.statusMsg标签已检测到模拟})Button(模拟标签移开).onClick((){this.tagDetectedfalsethis.ndefContentthis.statusMsg标签已移开this.addRecord(移开,标签离开)})}if(this.tagDetected){Column({space:8}){Text(标签信息).fontSize(16).fontWeight(FontWeight.Bold).width(100%)Row(){Text(类型:).fontSize(14).fontColor(#666666).width(60)Text(this.currentTagType).fontSize(14).fontWeight(FontWeight.Medium)}Row(){Text(NDEF:).fontSize(14).fontColor(#666666).width(60)Text(this.ndefContent||(空)).fontSize(14).fontColor(#1a73e8)}TextInput({text:this.writeInput,placeholder:写入内容}).onChange((value:string){this.writeInputvalue})Row({space:8}){Button(写入NDEF).onClick((){this.ndefContentthis.writeInputthis.addRecord(写入,this.writeInput)})Button(读取NDEF).onClick((){this.addRecord(读取,this.ndefContent||(空))})Button(清空).onClick((){this.ndefContentthis.addRecord(清空,NDEF已清除)})}}.width(100%).padding(16).borderRadius(12).backgroundColor(#FFFFFF)}// 操作记录if(this.nfcRecords.length0){Text(操作记录:).fontSize(16).fontWeight(FontWeight.Bold).width(100%)ForEach(this.nfcRecords.slice().reverse(),(record:NfcRecord){Row({space:8}){Text(record.time).fontSize(11).fontColor(#999999).width(60)Text(record.type).fontSize(12).fontWeight(FontWeight.Medium).fontColor(#1a73e8).width(50)Text(record.content).fontSize(12).fontColor(#333333).layoutWeight(1)}.padding(4)},(record:NfcRecord)record.id)}Text(this.statusMsg).fontSize(12).fontColor(#999999)}.width(100%).padding(20)}privateaddRecord(type:string,content:string):void{this.nfcRecords.push({id:Date.now().toString(),type:type,content:content,time:newDate().toLocaleTimeString()})}}碰一碰配网实战最常见的 IoT 场景——手机碰一碰设备上的 NFC 标签自动跳转配网页面输入 WiFi 密码后下发给设备。// NDEF 标签中写入的内容// URI: https://myapp.com/setup?deviceABC123// AAR: com.example.iotapp// APP 收到 NFC 意图后解析onNewWant(want:Want,launchParam:AbilityConstant.LaunchParam):void{lettagInfo:tag.TagInfo|nulltag.getTagInfo(want)if(tagInfonull)returnif(tag.isNdef(tagInfo)){letndefTag:ndef.NdefTagndef.getNdefTag(tagInfo)letmsg:ndef.NdefMessagendefTag.getNdefMessage()letrecords:ndef.NdefRecord[]msg.getRecords()// 解析 URI 中的设备 ID// 跳转到配网页面leturi:stringrecords[0].payloadasstringletdeviceId:stringthis.parseDeviceId(uri)router.pushUrl({url:pages/WifiSetup,params:{deviceId:deviceId}})}}标签类型判断不同标签支持不同的技术标签类型判断方法适用场景NDEFtag.isNdef()通用数据读写MifareClassictag.isMifareClassic()门禁卡、公交卡MifareUltralighttag.isMifareUltralight()NFC 贴纸NfcAtag.isNfcA()ISO 14443-3ANfcBtag.isNfcB()ISO 14443-3BNfcFtag.isNfcF()FeliCaNfcVtag.isNfcV()ISO 15693要点先判断标签类型再用对应的 API 操作。NDEF 是最通用的格式优先使用。踩坑清单问题原因解决getTagInfo 返回 nullwant 不是 NFC 意图检查 intent 来源isNdef 返回 false标签不是 NDEF 格式空白标签先格式化writeNdef 报错标签只读或容量不足检查标签是否可写前台分发不生效未在 onForeground 注册onForeground 注册、onBackground 取消碰标签打开别的 APP未注册前台分发注册前台分发 AAR 记录NDEF 解析乱码编码处理不对URI 类型用 UTF-8文本注意语言码readNdef 返回空标签无 NDEF 消息先检查 NDEF 消息是否存在标签检测延迟系统轮询间隔前台分发 注册 techList多标签干扰同时靠近多个标签一次只靠近一个标签createUriRecord 格式错URI 不完整必须含协议前缀 https://
返回列表