nfc_tag_reader 0.1.0 copy "nfc_tag_reader: ^0.1.0" to clipboard
nfc_tag_reader: ^0.1.0 copied to clipboard

PlatformAndroid

Hand-written Android NFC tag reader for Flutter. Streams scanned tags with decoded NDEF text, URI and raw records over platform channels.

nfc_tag_reader #

pub package license: MIT

A small, hand-written Flutter plugin that reads NFC tags on Android. No off-the-shelf NFC package is used — the bridge is a Kotlin implementation on top of NfcAdapter.enableReaderMode, wired to Dart through a MethodChannel and an EventChannel.

It decodes multiple NDEF record types (plain text, URI, MIME, external, empty) and always exposes the raw payload bytes, so it is useful for real work (contactless cards, tags, ID) rather than a single-tag toy.

Why this exists #

I hit a native-only problem in an app (reading contactless NFC tags), solved it with a hand-written Flutter ↔ Kotlin channel, then extracted the bridge into this reusable plugin. NFC read maps directly to fintech use cases: contactless cards, tags and ID.

Features #

  • isAvailable() — is NFC present and switched on?
  • startSession() / stopSession() — reader-mode lifecycle, tied correctly to the Android Activity lifecycle (no leaks, survives rotation).
  • Stream<NfcTag> tags — one structured event per tap.
  • Typed models — NfcTag, NdefRecord, NdefRecordType, NfcException. No dynamic leaks to consumers.
  • Graceful handling of "no NFC hardware" and "NFC turned off".

Supported record types #

Record NdefRecordType Decoded field
Well-known text (RTD_TEXT) text text, languageCode
Well-known URI (RTD_URI) uri uri
Absolute URI uri uri
MIME media mime mimeType (+ raw payload)
External type external mimeType (+ raw payload)
Empty empty
Anything else unknown raw payload

Install #

dependencies:
  nfc_tag_reader: ^0.1.0

Then:

flutter pub get

Android setup #

The plugin's manifest already contributes the NFC permission, so it is merged into your app automatically:

<uses-permission android:name="android.permission.NFC" />

If you want the Play Store to hide your app on devices without NFC hardware, add the feature declaration to your app's AndroidManifest.xml (the plugin intentionally does not force this):

<uses-feature android:name="android.hardware.nfc" android:required="true" />

minSdkVersion must be 19 or higher (enableReaderMode requirement). The plugin targets minSdk 24.

Usage #

import 'package:nfc_tag_reader/nfc_tag_reader.dart';

final nfc = NfcTagReader();

Future<void> scanOnce() async {
  if (!await nfc.isAvailable()) return; // no NFC, or it is turned off

  final sub = nfc.tags.listen(
    (tag) {
      for (final record in tag.records) {
        print(record.describe()); // e.g. "URI: https://example.com"
      }
    },
    onError: (Object e) {
      if (e is NfcException && e.reason == NfcErrorReason.disabled) {
        // prompt the user to enable NFC
      }
    },
  );

  try {
    await nfc.startSession();
  } on NfcException catch (e) {
    // e.reason: notSupported / disabled / noActivity
  }

  // ... when done:
  await nfc.stopSession();
  await sub.cancel();
}

A complete, fintech-styled example lives in example/.

Architecture #

Dart side

NfcTagReader
    └─▶ NfcTagReaderPlatform   (interface — leaves the iOS seam)
            └─▶ MethodChannelNfcTagReader
                    ├─ MethodChannel  com.abdurrahmanjun/nfc_tag_reader/methods
                    └─ EventChannel   com.abdurrahmanjun/nfc_tag_reader/tags

Kotlin side

NfcTagReaderPlugin
    ├─▶ NfcAdapter.enableReaderMode   (reader-mode lifecycle)
    └─▶ NdefParser                    (Tag → structured map)

The two channels bridge the sides: method calls (startSession / stopSession / isAvailable) flow over the MethodChannel, and each scanned tag is pushed back to Dart as one event over the EventChannel.

Limitations #

  • Read-only. Writing NDEF messages is not implemented.
  • Android only today. The federated NfcTagReaderPlatform interface leaves a clean seam for an iOS Core NFC implementation.
  • Uses the tag's cached NDEF message (no blocking IO on the reader thread), so it does not currently read non-NDEF proprietary card data.

Roadmap #

  • ❌ iOS support via Core NFC (NFCTagReaderSession).
  • ❌ NDEF write support.
  • ❌ Opt-in deep read for specific tech types (IsoDep, MifareClassic).

License #

MIT


Built by Abdurrahman Jundullah M — mobile engineer (Flutter + native Android), 8+ years, fintech/banking background.

1
likes
160
points
9
downloads

Documentation

API reference

Publisher

unverified uploader

Weekly Downloads

Hand-written Android NFC tag reader for Flutter. Streams scanned tags with decoded NDEF text, URI and raw records over platform channels.

Repository (GitHub)
View/report issues

Topics

#nfc #ndef #android #contactless #hardware

License

MIT (license)

Dependencies

flutter, plugin_platform_interface

More

Packages that depend on nfc_tag_reader

Packages that implement nfc_tag_reader