1# NFC Tag Read/Write Development 2 3## Introduction 4Near Field Communication (NFC) is a high-frequency radio technology that enables communication between devices over a distance less than 10 cm. NFC operates at 13.56 MHz. With NFC technologies, electronic devices can read and write NFC tags. 5NFC tags support one or more communications technologies listed as follows: 6- NFC-A (also known as ISO 14443-3A) 7- NFC-B (also known as ISO 14443-3B) 8- NFC-F (also known as JIS 6319-4) 9- NFC-V (also known as ISO 15693) 10- ISO-DEP 11- NDEF 12- MIFARE Classic 13- MIFARE Ultralight 14 15## When to Use 16An electronic device touches an NFC tag via the NFC antenna to read and write the NFC tag data. NFC tags can be read and written by a started application (foreground mode) on a device or without starting an application (background mode). 17- Reading/Writing an NFC tag by a started application<br> 18An application started on a device reads or writes the NFC tag. That is, the user starts the application to read and write the NFC tag. The user starts the application, opens the application page, and taps the device on the NFC tag. In this case, the tag data read can be distributed only to the foreground application. 19- Reading/Writing an NFC tag without starting an application<br> 20The user taps the device on an NFC tag without starting any application. Then, the device selects an application based on the type of the NFC tag technology. If multiple applications are matched, an application selector will be displayed, listing all the available applications for the user to choose. After the user selects an application, the NFC tag read/write page of the application is automatically displayed. 21- Constraints<br> 22No matter whether the foreground mode or background mode is used, the NFC tag can be discovered by the device only when the device screen is unlocked and illuminated. 23 24## Available APIs 25 26For details about the JS APIs and sample code, see [Standard NFC Tags](../../reference/apis-connectivity-kit/js-apis-nfcTag.md). 27 28The following table describes the APIs for obtaining objects of the tags that use different NFC tag technologies. The objects obtained are used to read and write NFC tags. 29 30| API | Description | 31| ---------------------------------- | ------------------------------------------------------------------------------ | 32| getNfcA(tagInfo: TagInfo): NfcATag | Obtains an **NfcATag** object, which allows access to the tags that use the NFC-A technology. | 33| getNfcB(tagInfo: TagInfo): NfcBTag | Obtains an **NfcBTag** object, which allows access to the tags that use the NFC-B technology. | 34| getNfcF(tagInfo: TagInfo): NfcFTag | Obtains an **NfcFTag** object, which allows access to the tags that use the NFC-F technology. | 35| getNfcV(tagInfo: TagInfo): NfcVTag | Obtains an **NfcVTag** object, which allows access to the tags that use the NFC-V technology. | 36| getIsoDep(tagInfo: TagInfo): IsoDepTag | Obtains an **IsoDepTag** object, which allows access to the tags that use the ISO-DEP technology. | 37| getNdef(tagInfo: TagInfo): NdefTag | Obtains an **NdefTag** object, which allows access to the tags that use the NDEF technology. | 38| getMifareClassic(tagInfo: TagInfo): MifareClassicTag | Obtains a **MifareClassicTag** object, which allows access to the tags that use the MIFARE Classic technology. | 39| getMifareUltralight(tagInfo: TagInfo): MifareUltralightTag | Obtains a **MifareUltralightTag** object, which allows access to the tags that use the MIFARE Ultralight technology. | 40 41## How to Develop 42 43### Accessing an NFC Tag by a Started Application 441. Declare the permission required for NFC tag operations and the action for filtering the application in the **module.json5** file. 452. Import modules. 463. Check whether the device supports the NFC feature. 474. Register a listener for the NFC tag read event so that the tag can be preferentially dispatched to a foreground application. 485. Obtain an NFC tag object of the specific technology type. 496. Read and write the tag data. 507. Exit the foreground mode when the application exits the NFC tag page. 51 52```ts 53 "abilities": [ 54 { 55 "name": "EntryAbility", 56 "srcEntry": "./ets/entryability/EntryAbility.ts", 57 "description": "$string:EntryAbility_desc", 58 "icon": "$media:icon", 59 "label": "$string:EntryAbility_label", 60 "startWindowIcon": "$media:icon", 61 "startWindowBackground": "$color:start_window_background", 62 "exported": true, 63 "skills": [ 64 { 65 "entities": [ 66 "entity.system.home" 67 ], 68 "actions": [ 69 "action.system.home", 70 71 // Add the NFC tag action to match this application. 72 "ohos.nfc.tag.action.TAG_FOUND" 73 ] 74 } 75 ] 76 } 77 ], 78 "requestPermissions": [ 79 { 80 // Add the permission required for NFC tag operations. 81 "name": "ohos.permission.NFC_TAG", 82 "reason": "$string:app_name", 83 } 84 ] 85``` 86 87```ts 88import { tag } from '@kit.ConnectivityKit'; 89import { BusinessError } from '@kit.BasicServicesKit'; 90import { hilog } from '@kit.PerformanceAnalysisKit'; 91import { AbilityConstant, UIAbility, Want, bundleManager } from '@kit.AbilityKit'; 92 93let nfcTagElementName: bundleManager.ElementName; 94let foregroundRegister: boolean; 95 96async function readerModeCb(error : BusinessError, tagInfo : tag.TagInfo) { 97 if (!error) { 98 // Obtain an NFC tag object of the specific technology type. 99 if (tagInfo == null || tagInfo == undefined) { 100 hilog.error(0x0000, 'testTag', 'readerModeCb tagInfo is invalid'); 101 return; 102 } 103 if (tagInfo.uid == null || tagInfo.uid == undefined) { 104 hilog.error(0x0000, 'testTag', 'readerModeCb uid is invalid'); 105 return; 106 } 107 if (tagInfo.technology == null || tagInfo.technology == undefined || tagInfo.technology.length == 0) { 108 hilog.error(0x0000, 'testTag', 'readerModeCb technology is invalid'); 109 return; 110 } 111 112 // Read and write the tag data. 113 // Use ISO-DEP to access this NFC tag. 114 let isoDep : tag.IsoDepTag | null = null; 115 for (let i = 0; i < tagInfo.technology.length; i++) { 116 if (tagInfo.technology[i] == tag.ISO_DEP) { 117 try { 118 isoDep = tag.getIsoDep(tagInfo); 119 } catch (error) { 120 hilog.error(0x0000, 'testTag', 'readerModeCb getIsoDep error = %{public}s', JSON.stringify(error)); 121 return; 122 } 123 } 124 // use other technology to access this nfc tag if necessary. 125 } 126 if (isoDep == undefined) { 127 hilog.error(0x0000, 'testTag', 'readerModeCb getIsoDep is invalid'); 128 return; 129 } 130 131 // Connect to this NFC tag using ISO-DEP. 132 try { 133 isoDep.connect(); 134 } catch (error) { 135 hilog.error(0x0000, 'testTag', 'readerModeCb isoDep.connect() error = %{public}s', JSON.stringify(error)); 136 return; 137 } 138 if (!isoDep.isConnected()) { 139 hilog.error(0x0000, 'testTag', 'readerModeCb isoDep.isConnected() false.'); 140 return; 141 } 142 143 // Transmit data to the connected tag. 144 let cmdData = [0x01, 0x02, 0x03, 0x04]; // please change the raw data to be correct. 145 try { 146 isoDep.transmit(cmdData).then((response : number[]) => { 147 hilog.info(0x0000, 'testTag', 'readerModeCb isoDep.transmit() response = %{public}s.', JSON.stringify(response)); 148 }).catch((err : BusinessError)=> { 149 hilog.error(0x0000, 'testTag', 'readerModeCb isoDep.transmit() err = %{public}s.', JSON.stringify(err)); 150 return; 151 }); 152 } catch (businessError) { 153 hilog.error(0x0000, 'testTag', 'readerModeCb isoDep.transmit() businessError = %{public}s.', JSON.stringify(businessError)); 154 return; 155 } 156 } else { 157 hilog.info(0x0000, 'testTag', 'readerModeCb readerModeCb error %{public}s', JSON.stringify(error)); 158 } 159} 160 161export default class EntryAbility extends UIAbility { 162 onCreate(want: Want, launchParam: AbilityConstant.LaunchParam) { 163 hilog.info(0x0000, 'testTag', '%{public}s', 'Ability onCreate'); 164 165 // Check whether the device supports the NFC feature. 166 if (!canIUse("SystemCapability.Communication.NFC.Core")) { 167 hilog.error(0x0000, 'testTag', 'nfc unavailable.'); 168 return; 169 } 170 171 nfcTagElementName = { 172 bundleName: want.bundleName ?? '', 173 abilityName: want.abilityName ?? '', 174 moduleName: want.moduleName, 175 } 176 } 177 178 onForeground() { 179 // Ability is brought to foreground. 180 hilog.info(0x0000, 'testTag', '%{public}s', 'Ability onForeground'); 181 if (nfcTagElementName != undefined) { 182 // Register a listener for the NFC tag read event so that the tag can be preferentially dispatched to a foreground application. 183 let techList : number[] = [tag.NFC_A, tag.NFC_B, tag.NFC_F, tag.NFC_V]; 184 try { 185 tag.on('readerMode', nfcTagElementName, techList, readerModeCb); 186 foregroundRegister = true; 187 } catch (error) { 188 hilog.error(0x0000, 'testTag', 'on readerMode error = %{public}s', JSON.stringify(error)); 189 } 190 } 191 } 192 193 onBackground() { 194 // Ability is back to background. 195 hilog.info(0x0000, 'testTag', '%{public}s', 'Ability onBackground'); 196 // When exiting the NFC tag page of the application, call the tag module API to exit the foreground mode. 197 if (foregroundRegister) { 198 foregroundRegister = false; 199 try { 200 tag.off('readerMode', nfcTagElementName); 201 } catch (error) { 202 hilog.error(0x0000, 'testTag', 'off readerMode error = %{public}s', JSON.stringify(error)); 203 } 204 } 205 } 206} 207``` 208 209### Accessing an NFC Tag Without Starting an Application 2101. Declare the permission required for NFC tag operations, the NFC tag action, and the NFC tag technologies used to match the applications in the **module.json5** file. 2112. Import modules. 2123. Obtain an NFC tag object of the specific technology type. 2134. Read and write the tag data. 214 215```ts 216 "abilities": [ 217 { 218 "name": "EntryAbility", 219 "srcEntry": "./ets/entryability/EntryAbility.ts", 220 "description": "$string:EntryAbility_desc", 221 "icon": "$media:icon", 222 "label": "$string:EntryAbility_label", 223 "startWindowIcon": "$media:icon", 224 "startWindowBackground": "$color:start_window_background", 225 "exported": true, 226 "skills": [ 227 { 228 "entities": [ 229 "entity.system.home" 230 ], 231 "actions": [ 232 "action.system.home", 233 234 // Add the NFC tag action to match this application. 235 "ohos.nfc.tag.action.TAG_FOUND" 236 ], 237 "uris": [ 238 { 239 "type":"tag-tech/NfcA" 240 }, 241 { 242 "type":"tag-tech/IsoDep" 243 } 244 // Add other technologies if necessary, 245 // such as: NfcB/NfcF/NfcV/Ndef/MifareClassic/MifareUL/NdefFormatable 246 ] 247 } 248 ] 249 } 250 ], 251 "requestPermissions": [ 252 { 253 // Add the permission required for NFC tag operations. 254 "name": "ohos.permission.NFC_TAG", 255 "reason": "$string:app_name", 256 } 257 ] 258``` 259 260```ts 261import { tag } from '@kit.ConnectivityKit'; 262import { BusinessError } from '@kit.BasicServicesKit'; 263import { hilog } from '@kit.PerformanceAnalysisKit'; 264import { AbilityConstant, UIAbility, Want } from '@kit.AbilityKit'; 265 266export default class EntryAbility extends UIAbility { 267 onCreate(want: Want, launchParam: AbilityConstant.LaunchParam) { 268 hilog.info(0x0000, 'testTag', '%{public}s', 'Ability onCreate'); 269 270 // Obtain an NFC tag object of the specific technology type. 271 let tagInfo : tag.TagInfo; 272 try { 273 tagInfo = tag.getTagInfo(want); 274 } catch (error) { 275 hilog.error(0x0000, 'testTag', 'getTagInfo error = %{public}s', JSON.stringify(error)); 276 return; 277 } 278 279 if (tagInfo == null || tagInfo == undefined) { 280 hilog.error(0x0000, 'testTag', 'tagInfo is invalid'); 281 return; 282 } 283 if (tagInfo.uid == null || tagInfo.uid == undefined) { 284 hilog.error(0x0000, 'testTag', 'uid is invalid'); 285 return; 286 } 287 if (tagInfo.technology == null || tagInfo.technology == undefined || tagInfo.technology.length == 0) { 288 hilog.error(0x0000, 'testTag', 'technology is invalid'); 289 return; 290 } 291 292 // Read and write the tag data. 293 // Use ISO-DEP to access this NFC tag. 294 let isoDep : tag.IsoDepTag | null = null; 295 for (let i = 0; i < tagInfo.technology.length; i++) { 296 if (tagInfo.technology[i] == tag.ISO_DEP) { 297 try { 298 isoDep = tag.getIsoDep(tagInfo); 299 } catch (error) { 300 hilog.error(0x0000, 'testTag', 'getIsoDep error = %{public}s', JSON.stringify(error)); 301 return; 302 } 303 } 304 // use other technology to access this nfc tag if necessary. 305 } 306 if (isoDep == undefined) { 307 hilog.error(0x0000, 'testTag', 'getIsoDep is invalid'); 308 return; 309 } 310 311 // Connect to this NFC tag using ISO-DEP. 312 try { 313 isoDep.connect(); 314 } catch (error) { 315 hilog.error(0x0000, 'testTag', 'isoDep.connect() error = %{public}s', JSON.stringify(error)); 316 return; 317 } 318 if (!isoDep.isConnected()) { 319 hilog.error(0x0000, 'testTag', 'isoDep.isConnected() false.'); 320 return; 321 } 322 323 // Transmit data to the connected tag. 324 let cmdData = [0x01, 0x02, 0x03, 0x04]; // please change the raw data to be correct. 325 try { 326 isoDep.transmit(cmdData).then((response : number[]) => { 327 hilog.info(0x0000, 'testTag', 'isoDep.transmit() response = %{public}s.', JSON.stringify(response)); 328 }).catch((err : BusinessError)=> { 329 hilog.error(0x0000, 'testTag', 'isoDep.transmit() err = %{public}s.', JSON.stringify(err)); 330 return; 331 }); 332 } catch (businessError) { 333 hilog.error(0x0000, 'testTag', 'isoDep.transmit() businessError = %{public}s.', JSON.stringify(businessError)); 334 return; 335 } 336 } 337} 338``` 339