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