### Android MainActivity Setup for Tag Stream Source: https://context7.com/nfcim/flutter_nfc_kit/llms.txt Configures the Android MainActivity to enable foreground dispatch for NFC tags, allowing the FlutterNfcKit tagStream to receive events without explicit polling. ```kotlin import android.app.PendingIntent import android.content.Intent import android.nfc.NfcAdapter import android.nfc.Tag import io.flutter.embedding.android.FlutterActivity import im.nfc.flutter_nfc_kit.FlutterNfcKitPlugin class MainActivity : FlutterActivity() { override fun onResume() { super.onResume() val adapter = NfcAdapter.getDefaultAdapter(this) val intent = PendingIntent.getActivity( this, 0, Intent(this, javaClass).addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP), PendingIntent.FLAG_MUTABLE ) adapter?.enableForegroundDispatch(this, intent, null, null) } override fun onPause() { super.onPause() NfcAdapter.getDefaultAdapter(this)?.disableForegroundDispatch(this) } override fun onNewIntent(intent: Intent) { val tag: Tag? = intent.getParcelableExtra(NfcAdapter.EXTRA_TAG) tag?.apply(FlutterNfcKitPlugin::handleTag) } } ``` -------------------------------- ### Build ISO 15693 Request Flags Source: https://context7.com/nfcim/flutter_nfc_kit/llms.txt Use Iso15693RequestFlags to build the 8-bit request flags byte for ISO 15693 operations. Call .encode() to get the integer representation or use .fromRaw() to decode from a byte. ```dart import "package:flutter_nfc_kit/flutter_nfc_kit.dart"; // Build flags for a high-data-rate addressed single-block read Iso15693RequestFlags flags = Iso15693RequestFlags( highDataRate: true, // bit 2 address: true, // bit 6 — use UID addressing option: false, ); print(flags.encode()); // e.g. 0x22 // Decode from a raw byte Iso15693RequestFlags decoded = Iso15693RequestFlags.fromRaw(0x22); print(decoded.highDataRate); // true print(decoded.address); // true // Use with readBlock on iOS Uint8List data = await FlutterNfcKit.readBlock( 0, iso15693Flags: flags, iso15693ExtendedMode: false, ); ``` -------------------------------- ### FlutterNfcKit.poll() Source: https://context7.com/nfcim/flutter_nfc_kit/llms.txt Polls for an NFC tag and returns an NFCTag object upon detection. This method starts an NFC session and supports various configuration options for different platforms and tag types. ```APIDOC ## FlutterNfcKit.poll() ### Description Polls for an NFC tag and returns an NFCTag object upon detection. This method starts an NFC session and supports various configuration options for different platforms and tag types. ### Method POST ### Endpoint `FlutterNfcKit.poll()` ### Parameters #### Query Parameters - **timeout** (Duration) - Optional - Timeout for polling (Android and Web only). - **iosAlertMessage** (String) - Optional - Message displayed to the user on iOS when polling. - **iosMultipleTagMessage** (String) - Optional - Message displayed on iOS when multiple tags are detected. - **androidPlatformSound** (bool) - Optional - Whether to play a system sound on Android when a tag is detected. - **androidCheckNDEF** (bool) - Optional - Whether to automatically check for NDEF support on Android. - **readIso14443A** (bool) - Optional - Whether to attempt reading ISO 14443-A tags (default true). - **readIso14443B** (bool) - Optional - Whether to attempt reading ISO 14443-B tags (default true). - **readIso18092** (bool) - Optional - Whether to attempt reading ISO 18092 tags (default false). - **readIso15693** (bool) - Optional - Whether to attempt reading ISO 15693 tags (default true). - **androidReaderModeFlags** (int) - Optional - Bitmask for Android reader mode flags. ### Response #### Success Response (200) - **NFCTag** (object) - An object containing the tag's metadata including ID, standard, NDEF availability, and MIFARE information. ### Request Example ```dart import 'dart:convert'; import 'package:flutter_nfc_kit/flutter_nfc_kit.dart'; Future pollTag() async { try { NFCTag tag = await FlutterNfcKit.poll( timeout: Duration(seconds: 15), iosAlertMessage: "Hold your device near the NFC tag", iosMultipleTagMessage: "Multiple tags detected — keep only one.", androidPlatformSound: true, androidCheckNDEF: true, readIso14443A: true, readIso14443B: true, readIso18092: false, // disabled by default due to iOS CoreNFC bug readIso15693: true, // Android: skip NDEF auto-check (~500ms faster) and silence system beep androidReaderModeFlags: 0x80 | 0x100, ); // Print full tag metadata as JSON print(jsonEncode(tag)); // Example output: // {"type":"iso7816","standard":"ISO 14443-4 (Type A)","id":"04A2B3C4D5E6F7", // "atqa":"0004","sak":"28","historicalBytes":"","ndefAvailable":true, // "ndefType":"org.nfcforum.ndef.type4","ndefCapacity":2048,"ndefWritable":true, // "ndefCanMakeReadOnly":true,"mifareInfo":null} print('Tag type: ${tag.type}'); print('Tag ID: ${tag.id}'); print('Standard: ${tag.standard}'); print('NDEF available: ${tag.ndefAvailable}'); print('NDEF writable: ${tag.ndefWritable}'); print('MIFARE info: ${tag.mifareInfo}'); } catch (e) { print('Poll error: $e'); } } ``` ``` -------------------------------- ### FlutterNfcKit.tagStream Source: https://context7.com/nfcim/flutter_nfc_kit/llms.txt A broadcast stream that emits NFC tag events on Android when tags are detected. This stream bypasses the need for explicit `poll()` calls and requires custom setup in `MainActivity` for Android's foreground dispatch mechanism. Do not call `finish()` when using this stream. It is always empty on iOS and Web. ```APIDOC ## FlutterNfcKit.tagStream ### Description Passive NFC tag event stream (Android only). A broadcast `Stream` that emits tag events when Android's foreground dispatch mechanism detects a tag — without requiring an explicit `poll()` call. Requires custom `MainActivity` setup with `NfcAdapter.enableForegroundDispatch`. Do **not** call `finish()` in stream mode. Always empty on iOS and Web. ### Method `tagStream` (Stream) ### Parameters None ### Response #### Success Response - **Stream** - A stream that emits `NFCTag` objects when tags are detected. ``` -------------------------------- ### FlutterNfcKit.transceive() Source: https://context7.com/nfcim/flutter_nfc_kit/llms.txt Sends a raw command or APDU to an NFC tag and returns the response. This method supports both hex string and Uint8List formats for commands and responses. ```APIDOC ## FlutterNfcKit.transceive() ### Description Sends a raw command or APDU to an NFC tag and returns the response. This method supports both hex string and Uint8List formats for commands and responses. ### Method POST ### Endpoint `FlutterNfcKit.transceive()` ### Parameters #### Request Body - **command** (String or Uint8List) - Required - The command to send, either as a hex string or a byte list. #### Query Parameters - **timeout** (Duration) - Optional - Timeout for the transceive operation (Android-only). ### Response #### Success Response (200) - **response** (String or Uint8List) - The response from the NFC tag, in the same format as the command. ### Request Example ```dart import 'dart:typed_data'; import 'package:flutter_nfc_kit/flutter_nfc_kit.dart'; Future transceiveExample(NFCTag tag) async { if (tag.type == NFCTagType.iso7816) { // Send as hex string, receive hex string String response = await FlutterNfcKit.transceive( "00A4040009A00000000386980701", // SELECT application APDU timeout: Duration(seconds: 5), ); print('Response (hex): $response'); // e.g. "9000" // Or use Uint8List for binary Uint8List cmdBytes = Uint8List.fromList([0x00, 0xB0, 0x95, 0x00, 0x00]); Uint8List respBytes = await FlutterNfcKit.transceive(cmdBytes); print('Response bytes: $respBytes'); } else if (tag.type == NFCTagType.iso18092) { // FeliCa layer-3 raw command String result = await FlutterNfcKit.transceive("060080080100"); print('FeliCa response: $result'); } } ``` ``` -------------------------------- ### Iso15693RequestFlags - ISO 15693 request flag builder Source: https://context7.com/nfcim/flutter_nfc_kit/llms.txt The Iso15693RequestFlags class allows building the 8-bit request flags byte for ISO 15693 operations like `readBlock` and `writeBlock`. Flags can be set using named boolean parameters, and the integer representation is obtained by calling `.encode()`. Flags can also be decoded from a raw byte. ```APIDOC ## Iso15693RequestFlags ### Description Encodes the 8-bit request flags byte for ISO 15693 operations (`readBlock` / `writeBlock`) as per ISO 15693-3. Create with named boolean parameters; call `.encode()` to get the integer representation. ### Methods - **Iso15693RequestFlags({bool highDataRate, bool address, bool option})**: Constructor to create flags with specified options. - **static Iso15693RequestFlags fromRaw(int rawFlags)**: Decodes flags from a raw integer byte. - **int encode()**: Encodes the current flag settings into an integer byte. ### Properties - **highDataRate** (bool) - Corresponds to bit 2 of the flags byte. - **address** (bool) - Corresponds to bit 6, indicating UID addressing. - **option** (bool) - Corresponds to other option bits. ### Example Usage ```dart import 'package:flutter_nfc_kit/flutter_nfc_kit.dart'; // Build flags for a high-data-rate addressed single-block read Iso15693RequestFlags flags = Iso15693RequestFlags( highDataRate: true, // bit 2 address: true, // bit 6 — use UID addressing option: false, ); print(flags.encode()); // e.g. 0x22 // Decode from a raw byte Iso15693RequestFlags decoded = Iso15693RequestFlags.fromRaw(0x22); print(decoded.highDataRate); // true print(decoded.address); // true // Use with readBlock on iOS // Uint8List data = await FlutterNfcKit.readBlock( // 0, // iso15693Flags: flags, // iso15693ExtendedMode: false, // ); ``` ``` -------------------------------- ### NFC Polling and Tag Interaction Source: https://github.com/nfcim/flutter_nfc_kit/blob/develop/example/example.md Demonstrates how to check NFC availability, poll for tags, and perform basic operations like transceiving data and reading/writing NDEF records. It also shows platform-specific alerts and finishing the NFC session. ```APIDOC ## NFC Polling and Tag Interaction ### Description This section covers the default operation mode for reading NFC tags, ensuring cross-platform consistency. It includes checking NFC availability, polling for tags with optional timeouts and platform-specific messages, transceiving data, and handling NDEF records. ### Method `FlutterNfcKit.poll()` ### Endpoint N/A (SDK Method) ### Parameters #### Polling Parameters - **timeout** (Duration) - Optional (Android-only) - Specifies the duration for polling. - **iosMultipleTagMessage** (String) - Optional (iOS-only) - Message to display when multiple tags are found. - **iosAlertMessage** (String) - Optional (iOS-only) - General alert message to display during scanning. #### Transceive Parameters - **data** (String) - Required - Hexadecimal string of data to transmit. - **timeout** (Duration) - Optional (Android-only) - Timeout for the transceive operation. #### NDEF Operations - **records** (List) - Required - List of NDEF records to write. #### Block/Page/Sector Operations - **index** (int) - Required - Index of the block/sector to read/write. - **data** (List) - Required - Data to write to the block. - **iso15693RequestFlag** (Iso15693RequestFlag) - Optional - Flags for ISO 15693 operations. - **iso15693ExtendedMode** (bool) - Optional - Use extended mode for ISO 15693. - **keyA/keyB** (String) - Optional - Authentication key for Mifare Classic sectors. ### Request Example ```dart import 'package:flutter_nfc_kit/flutter_nfc_kit.dart'; import 'package:ndef/ndef.dart' as ndef; var availability = await FlutterNfcKit.nfcAvailability; if (availability != NFCAvailability.available) { // Handle unavailability } var tag = await FlutterNfcKit.poll( timeout: Duration(seconds: 10), iosMultipleTagMessage: "Multiple tags found!", iosAlertMessage: "Scan your tag" ); if (tag.type == NFCTagType.iso7816) { var result = await FlutterNfcKit.transceive("00B0950000", Duration(seconds: 5)); print(result); } await FlutterNfcKit.setIosAlertMessage("hi there!"); if (tag.ndefAvailable) { for (var record in await FlutterNfcKit.readNDEFRecords(cached: false)) { print(record.toString()); } for (var record in await FlutterNfcKit.readNDEFRawRecords(cached: false)) { print(jsonEncode(record).toString()); } } if (tag.ndefWritable) { await FlutterNfcKit.writeNDEFRecords([new ndef.UriRecord.fromUriString("https://github.com/nfcim/flutter_nfc_kit")]); await FlutterNfcKit.writeNDEFRawRecords([new NDEFRawRecord("00", "0001", "0002", "0003", ndef.TypeNameFormat.unknown)]); } if (tag.type == NFCTagType.iso15693) { await FlutterNfcKit.writeBlock( 1, [0xde, 0xad, 0xbe, 0xff], iso15693RequestFlag: Iso15693RequestFlag(), iso15693ExtendedMode: false ); } if (tag.type == NFCType.mifare_classic) { await FlutterNfcKit.authenticateSector(0, keyA: "FFFFFFFFFFFF"); var data = await FlutterNfcKit.readSector(0); var data = await FlutterNfcKit.readBlock(0); } await FlutterNfcKit.finish(); await FlutterNfcKit.finish(iosAlertMessage: "Success"); await FlutterNfcKit.finish(iosErrorMessage: "Failed"); ``` ### Response #### Success Response - **tag** (NFCTag) - Information about the detected NFC tag. - **result** (String) - Result of the transceive operation (hex string). - **records** (List or Map) - Decoded or raw NDEF records. - **data** (List or String) - Data read from blocks or sectors. #### Response Example ```json { "type": "iso15693", "standard": "ISO15693", "id": "041234567890AB", "ndefAvailable": true, "ndefWritable": true } ``` ### Error Handling - **NFCAvailability.notAvailable**: NFC is not available on the device. - **NFCAvailability.restricted**: NFC is available but restricted. - **Exceptions**: Specific exceptions may be thrown for failed operations (e.g., timeout, authentication failure). ``` -------------------------------- ### FlutterNfcKit.authenticateSector() Source: https://context7.com/nfcim/flutter_nfc_kit/llms.txt Authenticates a sector on a MIFARE Classic tag with Key A or Key B before reading or writing that sector's blocks. This function is Android-only. It accepts the key as a hex String or Uint8List and returns true on success. ```APIDOC ## FlutterNfcKit.authenticateSector() ### Description Authenticates a sector on a MIFARE Classic tag with Key A or Key B before reading or writing that sector's blocks. Accepts key as a hex `String` or `Uint8List`. Android only. Returns `true` on success. ### Method ```dart Future authenticateSector(int sectorIndex, {String? keyA, String? keyB, Uint8List? keyABytes, Uint8List? keyBBytes}) ``` ### Parameters #### Path Parameters - **sectorIndex** (int) - Required - The index of the sector to authenticate (0-based). #### Query Parameters - **keyA** (String) - Optional - The Key A for authentication, provided as a hex string. - **keyB** (String) - Optional - The Key B for authentication, provided as a hex string. - **keyABytes** (Uint8List) - Optional - The Key A for authentication, provided as a Uint8List. - **keyBBytes** (Uint8List) - Optional - The Key B for authentication, provided as a Uint8List. ### Returns - `true` if the sector authentication was successful, `false` otherwise. ``` -------------------------------- ### Check NFC Hardware Availability Source: https://context7.com/nfcim/flutter_nfc_kit/llms.txt Before performing any NFC operations, check if the device supports NFC, if it's enabled, or if it's not supported. This function handles potential platform exceptions. ```dart import 'package:flutter_nfc_kit/flutter_nfc_kit.dart'; import 'package:flutter/services.dart'; Future checkNfc() async { NFCAvailability availability; try { availability = await FlutterNfcKit.nfcAvailability; } on PlatformException { availability = NFCAvailability.not_supported; } switch (availability) { case NFCAvailability.available: print('NFC is ready to use.'); break; case NFCAvailability.disabled: print('NFC is supported but turned off. Ask user to enable it.'); break; case NFCAvailability.not_supported: print('NFC is not supported on this device.'); break; } } ``` -------------------------------- ### Poll NFC Tags and Perform Operations Source: https://github.com/nfcim/flutter_nfc_kit/blob/develop/example/example.md Demonstrates polling for NFC tags, checking availability, and performing tag-specific operations like transceiving data, reading/writing NDEF records, and block-level access. Timeout parameters are platform-specific. ```dart import 'package:flutter_nfc_kit/flutter_nfc_kit.dart'; import 'package:ndef/ndef.dart' as ndef; var availability = await FlutterNfcKit.nfcAvailability; if (availability != NFCAvailability.available) { // oh-no } // timeout only works on Android, while the latter two messages are only for iOS var tag = await FlutterNfcKit.poll(timeout: Duration(seconds: 10), iosMultipleTagMessage: "Multiple tags found!", iosAlertMessage: "Scan your tag"); print(jsonEncode(tag)); if (tag.type == NFCTagType.iso7816) { var result = await FlutterNfcKit.transceive("00B0950000", Duration(seconds: 5)); // timeout is still Android-only, persist until next change print(result); } // iOS only: set alert message on-the-fly // this will persist until finish() await FlutterNfcKit.setIosAlertMessage("hi there!"); // read NDEF records if available if (tag.ndefAvailable) { /// decoded NDEF records (see [ndef.NDEFRecord] for details) /// `UriRecord: id=(empty) typeNameFormat=TypeNameFormat.nfcWellKnown type=U uri=https://github.com/nfcim/ndef` for (var record in await FlutterNfcKit.readNDEFRecords(cached: false)) { print(record.toString()); } /// raw NDEF records (data in hex string) /// `{identifier: "", payload: "00010203", type: "0001", typeNameFormat: "nfcWellKnown"}` for (var record in await FlutterNfcKit.readNDEFRawRecords(cached: false)) { print(jsonEncode(record).toString()); } } // write NDEF records if applicable if (tag.ndefWritable) { // decoded NDEF records await FlutterNfcKit.writeNDEFRecords([new ndef.UriRecord.fromUriString("https://github.com/nfcim/flutter_nfc_kit")]); // raw NDEF records await FlutterNfcKit.writeNDEFRawRecords([new NDEFRawRecord("00", "0001", "0002", "0003", ndef.TypeNameFormat.unknown)]); } // read / write block / page / sector level data // see documentation for platform-specific supportability if (tag.type == NFCTagType.iso15693) { await await FlutterNfcKit.writeBlock( 1, // index [0xde, 0xad, 0xbe, 0xff], // data iso15693RequestFlag: Iso15693RequestFlag(), // optional flags for ISO 15693 iso15693ExtendedMode: false // use extended mode for ISO 15693 ); } if (tag.type == NFCType.mifare_classic) { await FlutterNfcKit.authenticateSector(0, keyA: "FFFFFFFFFFFF"); var data = await FlutterNfcKit.readSector(0); // read one sector, or var data = await FlutterNfcKit.readBlock(0); // read one block } // Call finish() only once await FlutterNfcKit.finish(); // iOS only: show alert/error message on finish await FlutterNfcKit.finish(iosAlertMessage: "Success"); // or await FlutterNfcKit.finish(iosErrorMessage: "Failed"); ``` -------------------------------- ### Write Decoded NDEF Records with FlutterNfcKit Source: https://context7.com/nfcim/flutter_nfc_kit/llms.txt Writes a list of ndef.NDEFRecord objects to a writable NDEF tag. Internally converts them to raw records. Requires a valid active session and tag.ndefWritable == true. ```dart import 'package:flutter_nfc_kit/flutter_nfc_kit.dart'; import 'package:ndef/ndef.dart' as ndef; Future writeNdef(NFCTag tag) async { if (tag.ndefWritable ?? false) { try { await FlutterNfcKit.writeNDEFRecords([ ndef.UriRecord.fromUriString("https://github.com/nfcim/flutter_nfc_kit"), ndef.TextRecord(text: "Hello NFC", language: "en"), ]); print('NDEF records written successfully.'); } catch (e) { print('Write failed: $e'); } } } ``` -------------------------------- ### FlutterNfcKit.readSector() Source: https://context7.com/nfcim/flutter_nfc_kit/llms.txt Reads all blocks within a MIFARE Classic sector. The sector must be authenticated first. This method is available only on Android. It returns the sector data as a Uint8List. ```APIDOC ## FlutterNfcKit.readSector() ### Description Reads all blocks within one MIFARE Classic sector (typically 48 bytes for sectors 0–31 or 256 bytes for sectors 32–39). The sector must be authenticated first. Android only. Returns `Uint8List`. ### Method `readSector(int sector)` ### Parameters #### Path Parameters - **sector** (int) - Required - The sector number to read. ### Response #### Success Response - **Uint8List** - The data read from the sector. ``` -------------------------------- ### FlutterNfcKit.writeBlock() Source: https://context7.com/nfcim/flutter_nfc_kit/llms.txt Writes data to a block or page on an NFC tag. Supports MIFARE Classic, MIFARE Ultralight on Android, and ISO 15693 on iOS. Data can be provided as a hex String or Uint8List. ```APIDOC ## FlutterNfcKit.writeBlock() ### Description Writes one data unit to a MIFARE Classic block (16 bytes, Android), MIFARE Ultralight page (4 bytes, Android), or ISO 15693 block (4 bytes, iOS). Accepts hex `String` or `Uint8List`. ### Method ```dart Future writeBlock(int index, dynamic data, {Iso15693RequestFlags? iso15693Flags, bool? iso15693ExtendedMode}) ``` ### Parameters #### Path Parameters - **index** (int) - Required - The index of the block or page to write to. - **data** (dynamic) - Required - The data to write. Can be a hex `String` or `Uint8List`. #### Query Parameters - **iso15693Flags** (Iso15693RequestFlags) - Optional - Flags for ISO 15693 write requests (e.g., highDataRate). - **iso15693ExtendedMode** (bool) - Optional - Specifies if extended mode should be used for ISO 15693. ``` -------------------------------- ### FlutterNfcKit.readBlock() Source: https://context7.com/nfcim/flutter_nfc_kit/llms.txt Reads data from a specific block or page on an NFC tag. Supports MIFARE Classic, MIFARE Ultralight on Android, and ISO 15693 on iOS. Returns the data as a Uint8List. ```APIDOC ## FlutterNfcKit.readBlock() ### Description Reads one data unit from: - **MIFARE Classic** (Android): one 16-byte block (sector must be authenticated first) - **MIFARE Ultralight** (Android): four consecutive 4-byte pages starting at `index` - **ISO 15693** (iOS): one 4-byte block with optional request flags Returns data as `Uint8List`. ### Method ```dart Future readBlock(int index, {Iso15693RequestFlags? iso15693Flags, bool? iso15693ExtendedMode}) ``` ### Parameters #### Path Parameters - **index** (int) - Required - The index of the block or page to read. #### Query Parameters - **iso15693Flags** (Iso15693RequestFlags) - Optional - Flags for ISO 15693 read requests (e.g., highDataRate). - **iso15693ExtendedMode** (bool) - Optional - Specifies if extended mode should be used for ISO 15693. ### Returns - `Uint8List` containing the data read from the block or page. ``` -------------------------------- ### Android Activity for NFC Event Streaming Source: https://github.com/nfcim/flutter_nfc_kit/blob/develop/example/example.md Implement this custom Activity in your Android project to receive NFC tag events when the app is in the foreground. Ensure your AndroidManifest.xml uses this activity as the main entry point. ```kotlin package your.package.name import android.app.PendingIntent import android.content.Intent import android.nfc.NfcAdapter import android.nfc.Tag import io.flutter.embedding.android.FlutterActivity import im.nfc.flutter_nfc_kit.FlutterNfcKitPlugin class MainActivity : FlutterActivity() { override fun onResume() { super.onResume() val adapter: NfcAdapter? = NfcAdapter.getDefaultAdapter(this) val pendingIntent: PendingIntent = PendingIntent.getActivity( this, 0, Intent(this, javaClass).addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP), PendingIntent.FLAG_MUTABLE ) // See https://developer.android.com/reference/android/nfc/NfcAdapter#enableForegroundDispatch(android.app.Activity,%20android.app.PendingIntent,%20android.content.IntentFilter[],%20java.lang.String[][]) for details adapter?.enableForegroundDispatch(this, pendingIntent, null, null) } override fun onPause() { super.onPause() val adapter: NfcAdapter? = NfcAdapter.getDefaultAdapter(this) adapter?.disableForegroundDispatch(this) } override fun onNewIntent(intent: Intent) { val tag: Tag? = intent.getParcelableExtra(NfcAdapter.EXTRA_TAG) tag?.apply(FlutterNfcKitPlugin::handleTag) } } ``` -------------------------------- ### FlutterNfcKit.writeNDEFRecords() Source: https://context7.com/nfcim/flutter_nfc_kit/llms.txt Writes a list of ndef.NDEFRecord objects to a writable NDEF tag. Internally converts them to raw records. Requires a valid active session and tag.ndefWritable == true. ```APIDOC ## `FlutterNfcKit.writeNDEFRecords()` — Write decoded NDEF records ### Description Writes a list of `ndef.NDEFRecord` objects to a writable NDEF tag. Internally converts them to raw records. Requires a valid active session and `tag.ndefWritable == true`. ### Method ```dart Future writeNDEFRecords(List records) ``` ### Parameters #### Request Body - **records** (List) - Required - A list of NDEF records to write to the tag. ``` -------------------------------- ### Write Raw NDEF Records with FlutterNfcKit Source: https://context7.com/nfcim/flutter_nfc_kit/llms.txt Writes a list of NDEFRawRecord objects (hex-encoded fields) directly to the tag. Use this for precise control over TNF, type, and payload encoding. Requires a valid active session and tag.ndefWritable == true. ```dart import 'package:flutter_nfc_kit/flutter_nfc_kit.dart'; import 'package:ndef/ndef.dart' show TypeNameFormat; Future writeRawNdef(NFCTag tag) async { if (tag.ndefWritable ?? false) { await FlutterNfcKit.writeNDEFRawRecords([ NDEFRawRecord( "", // identifier (empty = no ID) "48656c6c6f", // payload hex = "Hello" "54", // type hex = "T" (Text record) TypeNameFormat.nfcWellKnown, ), ]); print('Raw NDEF record written.'); } } ``` -------------------------------- ### Read Raw NDEF Records with FlutterNfcKit Source: https://context7.com/nfcim/flutter_nfc_kit/llms.txt Reads NDEF records as NDEFRawRecord objects with fields in hex string format. Useful for low-level access to NDEF data without decoding. Requires an active session and tag.ndefAvailable == true. ```dart import 'dart:convert'; import 'package:flutter_nfc_kit/flutter_nfc_kit.dart'; Future readRawNdef(NFCTag tag) async { if (tag.ndefAvailable ?? false) { List rawRecords = await FlutterNfcKit.readNDEFRawRecords( cached: false, ); for (var record in rawRecords) { print(jsonEncode(record)); // {"identifier":"","payload":"00010203","type":"0001", // "typeNameFormat":"nfcWellKnown"} print('Payload hex: ${record.payload}'); print('Type: ${record.type}'); print('TNF: ${record.typeNameFormat}'); } } } ``` -------------------------------- ### Read NFC Tag Block/Page Source: https://context7.com/nfcim/flutter_nfc_kit/llms.txt Reads a data unit from various NFC tag types. For MIFARE Classic on Android, it reads a 16-byte block after authentication. For MIFARE Ultralight on Android, it reads four 4-byte pages. For ISO 15693 on iOS, it reads a 4-byte block with optional flags. Returns data as Uint8List. ```dart import 'package:flutter_nfc_kit/flutter_nfc_kit.dart'; Future readBlockExample(NFCTag tag) async { if (tag.type == NFCTagType.mifare_classic) { await FlutterNfcKit.authenticateSector(0, keyA: "FFFFFFFFFFFF"); Uint8List blockData = await FlutterNfcKit.readBlock(0); // block 0 print('Block 0 data: ${blockData.map((b) => b.toRadixString(16).padLeft(2, '0')).join(' ')}'); // e.g.: de ad be ef 00 01 02 03 04 05 06 07 08 09 0a 0b } else if (tag.type == NFCTagType.iso15693) { Uint8List blockData = await FlutterNfcKit.readBlock( 1, iso15693Flags: Iso15693RequestFlags(highDataRate: true), iso15693ExtendedMode: false, ); print('ISO 15693 block 1: $blockData'); } } ``` -------------------------------- ### FlutterNfcKit.writeNDEFRawRecords() Source: https://context7.com/nfcim/flutter_nfc_kit/llms.txt Writes a list of NDEFRawRecord objects (hex-encoded fields) directly to the tag. Use this when you need precise control over TNF, type, and payload encoding. ```APIDOC ## `FlutterNfcKit.writeNDEFRawRecords()` — Write raw NDEF records ### Description Writes a list of `NDEFRawRecord` objects (hex-encoded fields) directly to the tag. Use this when you need precise control over TNF, type, and payload encoding. ### Method ```dart Future writeNDEFRawRecords(List records) ``` ### Parameters #### Request Body - **records** (List) - Required - A list of raw NDEF records to write to the tag. ``` -------------------------------- ### NFCTag - Tag metadata object Source: https://context7.com/nfcim/flutter_nfc_kit/llms.txt The NFCTag object provides comprehensive metadata about a detected NFC tag. It includes core identification, type-specific information (Type-A, Type-B, FeliCa, ISO 15693), NDEF capabilities, MIFARE details, and platform-specific data. Unavailable fields are represented as null. The object can be serialized to JSON. ```APIDOC ## NFCTag ### Description Returned by `poll()` and `tagStream`, contains all available metadata about the detected tag. All multi-byte fields are hex strings; unavailable fields are `null`. ### Fields - **type** (NFCTagType) - The type of the NFC tag. - **standard** (string) - The NFC standard supported by the tag (e.g., "ISO 14443-4 (Type A)"). - **id** (string) - The unique identifier of the tag in hex format. - **atqa** (string) - Type-A specific Answer to Request field (Android only), hex string. - **sak** (string) - Type-A specific Select Acknowledge field (Android only), hex string. - **historicalBytes** (string) - Type-A specific historical bytes (Android only), hex string. - **protocolInfo** (string) - Type-B specific protocol information (Android only), hex string or null. - **applicationData** (string) - Type-B specific application data (Android only), hex string or null. - **hiLayerResponse** (string) - Type-B specific higher layer response (Android only), hex string or null. - **manufacturer** (string) - FeliCa (ISO 18092) manufacturer information, hex string or null. - **systemCode** (string) - FeliCa (ISO 18092) system code, hex string or null. - **dsfId** (string) - ISO 15693 Digital Storage Format Identifier (Android only), hex string or null. - **ndefAvailable** (bool) - Indicates if the tag supports NDEF (true/false/null). - **ndefWritable** (bool) - Indicates if the tag is writable for NDEF (true/false/null). - **ndefCanMakeReadOnly** (bool) - Indicates if the tag can be made read-only (true/false/null). - **ndefCapacity** (int) - The NDEF capacity of the tag in bytes or null. - **ndefType** (string) - The NDEF type of the tag (e.g., "org.nfcforum.ndef.type4") or null. - **mifareInfo** (MifareInfo) - MIFARE specific information, if applicable. - **type** (string) - MIFARE type (e.g., "MifareClassic"). - **size** (int) - Total size in bytes. - **blockSize** (int) - Size of a block in bytes. - **blockCount** (int) - Total number of blocks. - **sectorCount** (int) - Total number of sectors. - **webUSBCustomProbeData** (string) - Custom probe data for Web USB (hex string or null). ### Example Usage ```dart import 'dart:convert'; import 'package:flutter_nfc_kit/flutter_nfc_kit.dart'; void inspectTag(NFCTag tag) { print(tag.type); print(tag.standard); print(tag.id); print(tag.atqa); print(tag.sak); print(tag.historicalBytes); print(tag.protocolInfo); print(tag.applicationData); print(tag.hiLayerResponse); print(tag.manufacturer); print(tag.systemCode); print(tag.dsfId); print(tag.ndefAvailable); print(tag.ndefWritable); print(tag.ndefCanMakeReadOnly); print(tag.ndefCapacity); print(tag.ndefType); if (tag.mifareInfo != null) { print(tag.mifareInfo!.type); print(tag.mifareInfo!.size); print(tag.mifareInfo!.blockSize); print(tag.mifareInfo!.blockCount); print(tag.mifareInfo!.sectorCount); } print(tag.webUSBCustomProbeData); print(jsonEncode(tag)); } ``` ``` -------------------------------- ### Optimize NFC Detection with Android Reader Flags Source: https://github.com/nfcim/flutter_nfc_kit/blob/develop/README.md Use `androidReaderModeFlags` to skip NDEF discovery for faster detection and disable platform sounds for custom feedback. This is useful for applications requiring rapid tag reads or custom user experiences. ```dart // Skip automatic NDEF discovery for ~500ms faster detection // and disable platform sounds for custom feedback const flags = 0x80 | 0x100; // FLAG_READER_SKIP_NDEF_CHECK | FLAG_READER_NO_PLATFORM_SOUNDS final tag = await FlutterNfcKit.poll( androidReaderModeFlags: flags, ); ``` -------------------------------- ### Update iOS Alert Message Mid-Session Source: https://context7.com/nfcim/flutter_nfc_kit/llms.txt Use this to provide dynamic user guidance during an NFC session on iOS. It's a no-op on Android and Web. Ensure a session is active before calling. ```dart import 'package:flutter_nfc_kit/flutter_nfc_kit.dart'; Future multiStepIos() async { await FlutterNfcKit.poll(iosAlertMessage: "Tap your card to begin..."); await FlutterNfcKit.setIosAlertMessage("Reading data..."); String response = await FlutterNfcKit.transceive("00B0950000"); await FlutterNfcKit.setIosAlertMessage("Almost done!"); // ... more operations ... await FlutterNfcKit.finish(iosAlertMessage: "Done!"); } ``` -------------------------------- ### Read MIFARE Classic Sector with FlutterNfcKit Source: https://context7.com/nfcim/flutter_nfc_kit/llms.txt Reads all blocks within a MIFARE Classic sector after authentication. This is an Android-only feature. Ensure the sector is authenticated before calling. ```dart import 'package:flutter_nfc_kit/flutter_nfc_kit.dart'; Future readSectorExample(NFCTag tag) async { if (tag.type == NFCTagType.mifare_classic) { await FlutterNfcKit.authenticateSector(0, keyA: "FFFFFFFFFFFF"); Uint8List sectorData = await FlutterNfcKit.readSector(0); print('Sector 0 (${sectorData.length} bytes): ' '${sectorData.map((b) => b.toRadixString(16).padLeft(2, '0')).join(' ')}'); // Sector 0 (48 bytes): 00 01 02 03 ... ff } } ``` -------------------------------- ### Write to NFC Tag Block/Page Source: https://context7.com/nfcim/flutter_nfc_kit/llms.txt Writes data to a specific block or page on an NFC tag. Supports MIFARE Classic (16 bytes, Android), MIFARE Ultralight (4 bytes, Android), and ISO 15693 (4 bytes, iOS). Data can be provided as a hex string or Uint8List. MIFARE Classic requires prior sector authentication. ```dart import 'package:flutter_nfc_kit/flutter_nfc_kit.dart'; Future writeBlockExample(NFCTag tag) async { if (tag.type == NFCTagType.mifare_classic) { await FlutterNfcKit.authenticateSector(1, keyA: "FFFFFFFFFFFF"); // Write 16 bytes to block 4 (first block of sector 1) await FlutterNfcKit.writeBlock(4, "deadbeef0102030405060708090a0b0c"); print('Block 4 written.'); } else if (tag.type == NFCTagType.iso15693) { await FlutterNfcKit.writeBlock( 2, Uint8List.fromList([0xDE, 0xAD, 0xBE, 0xFF]), iso15693Flags: Iso15693RequestFlags(highDataRate: true), iso15693ExtendedMode: false, ); print('ISO 15693 block 2 written.'); } } ``` -------------------------------- ### FlutterNfcKit.readNDEFRawRecords() Source: https://context7.com/nfcim/flutter_nfc_kit/llms.txt Reads NDEF records as List with fields in hex string format (identifier, payload, type, typeNameFormat). Useful when you need low-level access to NDEF data without decoding. ```APIDOC ## `FlutterNfcKit.readNDEFRawRecords()` — Read raw NDEF records ### Description Reads NDEF records as `List` with fields in hex string format (identifier, payload, type, typeNameFormat). Useful when you need low-level access to NDEF data without decoding. ### Method ```dart Future> readNDEFRawRecords({ bool cached = false, }) ``` ### Parameters #### Query Parameters - **cached** (bool) - Optional - On Android, set to `true` for cached read. ``` -------------------------------- ### Send Raw Command / APDU Source: https://context7.com/nfcim/flutter_nfc_kit/llms.txt Transmit raw commands or APDUs to NFC tags. This function supports both hex string and `Uint8List` inputs and returns the response in the same format. The `timeout` parameter is specific to Android. ```dart import 'dart:typed_data'; import 'package:flutter_nfc_kit/flutter_nfc_kit.dart'; Future transceiveExample(NFCTag tag) async { if (tag.type == NFCTagType.iso7816) { // Send as hex string, receive hex string String response = await FlutterNfcKit.transceive( "00A4040009A00000000386980701", // SELECT application APDU timeout: Duration(seconds: 5), ); print('Response (hex): $response'); // e.g. "9000" // Or use Uint8List for binary Uint8List cmdBytes = Uint8List.fromList([0x00, 0xB0, 0x95, 0x00, 0x00]); Uint8List respBytes = await FlutterNfcKit.transceive(cmdBytes); print('Response bytes: $respBytes'); } else if (tag.type == NFCTagType.iso18092) { // FeliCa layer-3 raw command String result = await FlutterNfcKit.transceive("060080080100"); print('FeliCa response: $result'); } } ``` -------------------------------- ### FlutterNfcKit.finish() Source: https://context7.com/nfcim/flutter_nfc_kit/llms.txt Terminates the current NFC session. Must be called exactly once after each poll(). On iOS, provide iosAlertMessage for success or iosErrorMessage for failure feedback in the system UI. On Web, pass closeWebUSB: true to release the USB device so the user can select a different one next time. ```APIDOC ## `FlutterNfcKit.finish()` — End the NFC session ### Description Terminates the current NFC session. Must be called exactly once after each `poll()`. On iOS, provide `iosAlertMessage` for success or `iosErrorMessage` for failure feedback in the system UI. On Web, pass `closeWebUSB: true` to release the USB device so the user can select a different one next time. ### Method ```dart Future finish({ String? iosAlertMessage, String? iosErrorMessage, bool closeWebUSB = false, }) ``` ### Parameters #### Query Parameters - **iosAlertMessage** (String) - Optional - Message to display on iOS upon successful session termination. - **iosErrorMessage** (String) - Optional - Message to display on iOS upon failed session termination. - **closeWebUSB** (bool) - Optional - On Web, set to `true` to release the USB device. ```