• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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.<br>
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 (also known as ISO 14443-4)
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 or 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 retrieved tag data can be distributed only to the foreground application.
19- Reading or 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## Preparations
42
43### Reading/Writing NFC Tags in the Foreground or Background
44NFC tag application developers can choose to read/write NFC tags in the foreground or background based on service requirements. These two methods differ in their code implementations.
45- Reading or writing an NFC tag by a started application<br>
461. In the **module.json5** configuration file, you do not need to statically declare the technology type of the target NFC tag. Instead, dynamically register the technology type by using [tag.registerForegroundDispatch](../../reference/apis-connectivity-kit/js-apis-nfcTag.md#tagregisterforegrounddispatch10) or [tag.on](../../reference/apis-connectivity-kit/js-apis-nfcTag.md#tagon11).
472. During dynamic registration via **registerForegroundDispatch** or **tag.on**, specify the technology type of the target NFC tags in the input parameters.
483. If **registerForegroundDispatch** is used for registration: When the application runs in the foreground and enters the card swiping page, the NFC card emulation function is enabled, allowing card swiping to be performed simultaneously. If **tag.on** is used for registration: When the application runs in the foreground and enters the card swiping page, the NFC card emulation function is disabled, making simultaneous card swiping unavailable.
494. When the app page switches to the background, explicitly call [tag.unregisterForegroundDispatch](../../reference/apis-connectivity-kit/js-apis-nfcTag.md#tagunregisterforegrounddispatch10) or [tag.off](../../reference/apis-connectivity-kit/js-apis-nfcTag.md#tagoff11) to unregister technology type and exit the foreground dispatch mode.
50- Reading or writing an NFC tag without starting an application<br>
511. In the **module.json5** configuration file, statically declare the technology type of the target NFC tag. You must define at least one technology type based on service requirements. **tag-tech/** is the prefix, followed by the technology type description.
522. The technology type description is case-sensitive and must exactly match the actual technology type.
53
54> **NOTE**
55> - Starting from API version 9, application development supports the Stage model, which is recommended for long-term evolution.
56> - All the sample code in this document is based on the Stage model.
57
58## How to Develop
59
60### Accessing an NFC Tag by a Started Application
611. Declare the permission required for NFC tag operations and the action for filtering the application in the **module.json5** file.
622. Import related modules.
633. Check whether the device supports the NFC feature.
644. Register a listener for the NFC tag read event so that the tag can be preferentially dispatched to a foreground application.
655. Obtain an NFC tag object of the specific technology type.
666. Read and write the tag data.
677. Exit the foreground dispatch mode when the application exits the NFC tag page.
68
69```ts
70    "abilities": [
71      {
72        "name": "EntryAbility",
73        "srcEntry": "./ets/entryability/EntryAbility.ts",
74        "description": "$string:EntryAbility_desc",
75        "icon": "$media:icon",
76        "label": "$string:EntryAbility_label",
77        "startWindowIcon": "$media:icon",
78        "startWindowBackground": "$color:start_window_background",
79        "exported": true,
80        "skills": [
81          {
82            "entities": [
83              "entity.system.home"
84            ],
85            "actions": [
86              "ohos.want.action.home",
87
88              // The actions field must contain ohos.nfc.tag.action.TAG_FOUND.
89              "ohos.nfc.tag.action.TAG_FOUND"
90            ]
91          }
92        ]
93      }
94    ],
95    "requestPermissions": [
96      {
97        // Add the NFC tag operation permission.
98        "name": "ohos.permission.NFC_TAG",
99        "reason": "$string:app_name",
100      }
101    ]
102```
103
104```ts
105import { tag } from '@kit.ConnectivityKit';
106import { BusinessError } from '@kit.BasicServicesKit';
107import { hilog } from '@kit.PerformanceAnalysisKit';
108import { AbilityConstant, UIAbility, Want, bundleManager } from '@kit.AbilityKit';
109
110let nfcTagElementName: bundleManager.ElementName;
111let foregroundRegister: boolean;
112
113async function readerModeCb(error : BusinessError, tagInfo : tag.TagInfo) {
114  if (!error) {
115    // Obtain an NFC tag object of the specific technology type.
116    if (tagInfo == null || tagInfo == undefined) {
117      hilog.error(0x0000, 'testTag', 'readerModeCb tagInfo is invalid');
118      return;
119    }
120    if (tagInfo.uid == null || tagInfo.uid == undefined) {
121      hilog.error(0x0000, 'testTag', 'readerModeCb uid is invalid');
122      return;
123    }
124    if (tagInfo.technology == null || tagInfo.technology == undefined || tagInfo.technology.length == 0) {
125      hilog.error(0x0000, 'testTag', 'readerModeCb technology is invalid');
126      return;
127    }
128
129    // The NFC tag may support multiple technology types. Select a specific technology type to read or write tag data.
130    // The following sample code is based on the IsoDep technology.
131    let isoDep : tag.IsoDepTag | null = null;
132    for (let i = 0; i < tagInfo.technology.length; i++) {
133      if (tagInfo.technology[i] == tag.ISO_DEP) {
134        try {
135          isoDep = tag.getIsoDep(tagInfo);
136        } catch (error) {
137          hilog.error(0x0000, 'testTag', 'readerModeCb getIsoDep error = %{public}s', JSON.stringify(error));
138          return;
139        }
140      }
141      // You can also use other technology types as required.
142    }
143    if (isoDep == undefined) {
144      hilog.error(0x0000, 'testTag', 'readerModeCb getIsoDep is invalid');
145      return;
146    }
147
148    // Connect to the NFC tag via IsoDep.
149    try {
150        isoDep.connect();
151    } catch (error) {
152        hilog.error(0x0000, 'testTag', 'readerModeCb isoDep.connect() error = %{public}s', JSON.stringify(error));
153        return;
154    }
155    if (!isoDep.isConnected()) {
156      hilog.error(0x0000, 'testTag', 'readerModeCb isoDep.isConnected() false.');
157      return;
158    }
159
160    // Send a command to the connected NFC tag to obtain the response data.
161    let cmdData = [0x01, 0x02, 0x03, 0x04]; // Modify the command data as required.
162    try {
163      isoDep.transmit(cmdData).then((response : number[]) => {
164        hilog.info(0x0000, 'testTag', 'readerModeCb isoDep.transmit() response = %{public}s.', JSON.stringify(response));
165      }).catch((err : BusinessError)=> {
166        hilog.error(0x0000, 'testTag', 'readerModeCb isoDep.transmit() err = %{public}s.', JSON.stringify(err));
167        return;
168      });
169    } catch (businessError) {
170      hilog.error(0x0000, 'testTag', 'readerModeCb isoDep.transmit() businessError = %{public}s.', JSON.stringify(businessError));
171      return;
172    }
173  } else {
174    hilog.info(0x0000, 'testTag', 'readerModeCb readerModeCb error %{public}s', JSON.stringify(error));
175  }
176}
177
178export default class EntryAbility extends UIAbility {
179  onCreate(want: Want, launchParam: AbilityConstant.LaunchParam) {
180    hilog.info(0x0000, 'testTag', '%{public}s', 'Ability onCreate');
181
182    // Check whether the device supports the NFC feature.
183    if (!canIUse("SystemCapability.Communication.NFC.Core")) {
184      hilog.error(0x0000, 'testTag', 'nfc unavailable.');
185      return;
186    }
187
188    // Initialize element names of the NFC tag based on the application information.
189    nfcTagElementName = {
190      bundleName: want.bundleName ?? '',
191      abilityName: want.abilityName ?? '',
192      moduleName: want.moduleName,
193    }
194  }
195
196  onForeground() {
197    // Switch the application to the foreground and call the foreground dispatch API to enable the foreground application to preferentially process the discovered NFC tag.
198    hilog.info(0x0000, 'testTag', '%{public}s', 'Ability onForeground');
199    if (nfcTagElementName != undefined) {
200      // Select an appropriate technology type based on service requirements.
201      let techList : number[] = [tag.NFC_A, tag.NFC_B, tag.NFC_F, tag.NFC_V];
202      try {
203        tag.on('readerMode', nfcTagElementName, techList, readerModeCb);
204        foregroundRegister = true;
205      } catch (error) {
206        hilog.error(0x0000, 'testTag', 'on readerMode error = %{public}s', JSON.stringify(error));
207      }
208    }
209  }
210
211  onBackground() {
212    hilog.info(0x0000, 'testTag', '%{public}s', 'Ability onBackground');
213    // When exiting the NFC tag page, call the tag.off API to exit the foreground dispatch mode.
214    if (foregroundRegister) {
215      foregroundRegister = false;
216      try {
217        tag.off('readerMode', nfcTagElementName);
218      } catch (error) {
219        hilog.error(0x0000, 'testTag', 'off readerMode error = %{public}s', JSON.stringify(error));
220      }
221    }
222  }
223}
224```
225
226### Accessing an NFC Tag Without Starting an Application
2271. In the **module.json5** configuration file, declare the NFC tag operation permission, the NFC tag action, and the technology type.
2282. Import related modules.
2293. Obtain an NFC tag object of the specific technology type.
2304. Read and write the tag data.
231
232```ts
233    "abilities": [
234      {
235        "name": "EntryAbility",
236        "srcEntry": "./ets/entryability/EntryAbility.ts",
237        "description": "$string:EntryAbility_desc",
238        "icon": "$media:icon",
239        "label": "$string:EntryAbility_label",
240        "startWindowIcon": "$media:icon",
241        "startWindowBackground": "$color:start_window_background",
242        "exported": true,
243        "skills": [
244          {
245            "entities": [
246              "entity.system.home"
247            ],
248            "actions": [
249              "ohos.want.action.home",
250
251              // The actions field must contain ohos.nfc.tag.action.TAG_FOUND.
252              "ohos.nfc.tag.action.TAG_FOUND"
253            ],
254
255            // You must define at least one technology type based on service requirements. **tag-tech/** is the prefix, followed by the technology type description.
256            "uris": [
257              {
258                  "type":"tag-tech/NfcA"
259              },
260              {
261                  "type":"tag-tech/IsoDep"
262              }
263              //  Add other technology types if necessary.
264              // Example: NfcB/NfcF/NfcV/Ndef/MifareClassic/MifareUL/NdefFormatable
265            ]
266          }
267        ]
268      }
269    ],
270    "requestPermissions": [
271      {
272        // Add the NFC tag operation permission.
273        "name": "ohos.permission.NFC_TAG",
274        "reason": "$string:app_name",
275      }
276    ]
277```
278
279```ts
280import { tag } from '@kit.ConnectivityKit';
281import { BusinessError } from '@kit.BasicServicesKit';
282import { hilog } from '@kit.PerformanceAnalysisKit';
283import { AbilityConstant, UIAbility, Want } from '@kit.AbilityKit';
284
285export default class EntryAbility extends UIAbility {
286  onCreate(want: Want, launchParam: AbilityConstant.LaunchParam) {
287    hilog.info(0x0000, 'testTag', '%{public}s', 'Ability onCreate');
288
289    // Obtain an NFC tag object of the specific technology type.
290    let tagInfo : tag.TagInfo;
291    try {
292      tagInfo = tag.getTagInfo(want);
293    } catch (error) {
294      hilog.error(0x0000, 'testTag', 'getTagInfo error = %{public}s', JSON.stringify(error));
295      return;
296    }
297
298    if (tagInfo == null || tagInfo == undefined) {
299      hilog.error(0x0000, 'testTag', 'tagInfo is invalid');
300      return;
301    }
302    if (tagInfo.uid == null || tagInfo.uid == undefined) {
303      hilog.error(0x0000, 'testTag', 'uid is invalid');
304      return;
305    }
306    if (tagInfo.technology == null || tagInfo.technology == undefined || tagInfo.technology.length == 0) {
307      hilog.error(0x0000, 'testTag', 'technology is invalid');
308      return;
309    }
310
311    // The NFC tag may support multiple technology types. Select a specific technology type to read or write tag data.
312    // The following sample code is based on the IsoDep technology.
313    let isoDep : tag.IsoDepTag | null = null;
314    for (let i = 0; i < tagInfo.technology.length; i++) {
315      if (tagInfo.technology[i] == tag.ISO_DEP) {
316        try {
317          isoDep = tag.getIsoDep(tagInfo);
318        } catch (error) {
319          hilog.error(0x0000, 'testTag', 'getIsoDep error = %{public}s', JSON.stringify(error));
320          return;
321        }
322      }
323      // You can also use other technology types as required.
324    }
325    if (isoDep == undefined) {
326      hilog.error(0x0000, 'testTag', 'getIsoDep is invalid');
327      return;
328    }
329
330    // Connect to the NFC tag via IsoDep.
331    try {
332        isoDep.connect();
333    } catch (error) {
334        hilog.error(0x0000, 'testTag', 'isoDep.connect() error = %{public}s', JSON.stringify(error));
335        return;
336    }
337    if (!isoDep.isConnected()) {
338      hilog.error(0x0000, 'testTag', 'isoDep.isConnected() false.');
339      return;
340    }
341
342    // Send a command to the connected NFC tag to obtain the response data.
343    let cmdData = [0x01, 0x02, 0x03, 0x04]; // Modify the command data as required.
344    try {
345      isoDep.transmit(cmdData).then((response : number[]) => {
346        hilog.info(0x0000, 'testTag', 'isoDep.transmit() response = %{public}s.', JSON.stringify(response));
347      }).catch((err : BusinessError)=> {
348        hilog.error(0x0000, 'testTag', 'isoDep.transmit() err = %{public}s.', JSON.stringify(err));
349        return;
350      });
351    } catch (businessError) {
352      hilog.error(0x0000, 'testTag', 'isoDep.transmit() businessError = %{public}s.', JSON.stringify(businessError));
353      return;
354    }
355  }
356}
357```
358