NFC Library for Android

NFC Library for Android demo example
Delphi and C++ Builder NFC library for Android.
  • uses Android NFC API
  • provides reading, writing and formatting NFC tags
  • supports Android Beam data transfer
  • supports foreground dispatch and reader mode
  • supports host-based card emulation
  • supports ISO-DEP, NDEF, NFC-A, NFC-B, NFC-F, NFC-V, MIFARE Classic and MIFARE Ultralight tags
  • available for Delphi/C++ Builder 10 - 10.3
  • source code included in registered version
  • royalty free distribution in applications

Library API

type
  TNfcAdapterState = (asOff, asOn, asTurningOff, asTurningOn);
  TNfcDeactivationReason = (drDeselected, drLinkLoss);
  TNfcMode = (moReader, moForegroundDispatch, moBeam, moCardEmulation);

  TReaderFlag = (reNfcA, reNfcB, reNfcF, reNfcV, reNfcBarcode, reNoNdefCheck, reNoSound);
  TReaderFlags = set of TReaderFlag;

  TAdapterStateChangedEvent = procedure(Sender: TObject; AdapterState: TNfcAdapterState) of object;
  TBeamCompleteEvent = procedure(Sender: TObject) of object;
  TDeactivatedEvent = procedure(Sender: TObject; Reason: TNfcDeactivationReason) of object;
  TProcessCommandEvent = procedure(Sender: TObject; Command: TArray<Byte>; var Response: TArray<Byte>) of object;
  TTagDiscoveredEvent = procedure(Sender: TObject; Tag: TNfcTag) of object;

  ENfcError = class(Exception);

  TNfc = class
    constructor Create(Mode: TNfcMode = moReader);

    function Beam(NdefMessage: TNdefMessage): Boolean;
    function Beam(const Uri: Jnet_Uri): Boolean;
    function Beam(const Uris: TArray<Jnet_Uri>): Boolean;
    function Beam(const FileName: string): Boolean;
    function Beam(const FileNames: TArray<string>): Boolean;

    procedure Disable;
    procedure Enable(Flags: TReaderFlags = [reNfcA, reNfcB, reNfcF, reNfcV, reNfcBarcode]; PresenceCheckDelay: Integer = -1);

    procedure ShowBeamSettings;
    procedure ShowSettings;

    property Adapter: JNfcAdapter read;
    property AdapterEnabled: Boolean read;
    property BeamEnabled: Boolean read;
    property Mode: TNfcMode read;

    property OnAdapterStateChanged: TAdapterStateChangedEvent read write;
    property OnBeamComplete: TBeamCompleteEvent read write;
    property OnDeactivated: TDeactivatedEvent read write;
    property OnProcessCommand: TProcessCommandEvent read write;
    property OnTagDiscovered: TTagDiscoveredEvent read write;
  end;

  TNfcTag = class
    property Id: TArray<Byte> read;
    property IsoDep: TIsoDep read;
    property MifareClassic: TMifareClassic read;
    property MifareUltralight: TMifareUltralight read;
    property Ndef: TNdef read;
    property NdefFormatable: TNdefFormatable read;
    property NfcA: TNfcA read;
    property NfcB: TNfcB read;
    property NfcF: TNfcF read;
    property NfcV: TNfcV read;
    property Tag: JTag read;
    property TechList: TArray<string> read;
  end;

  TIsoDep = class
    function Transceive(Data: TArray<Byte>): TArray<Byte>;

    property ExtendedLengthApduSupported: Boolean read;
    property HigherLayerResponse: TArray<Byte> read;
    property HistoricalBytes: TArray<Byte> read;
    property IsoDep: JIsoDep read;
    property MaxTransceiveLength: Integer read;
    property Tag: JTag read;
    property Timeout: Integer read write;
  end;

  TNfcA = class
    function Transceive(Data: TArray<Byte>): TArray<Byte>;

    property Atqa: TArray<Byte> read;
    property MaxTransceiveLength: Integer read;
    property NfcA: JNfcA read;
    property Sak: SmallInt read;
    property Tag: JTag read;
    property Timeout: Integer read write;
  end;

  TNfcB = class
    function Transceive(Data: TArray<Byte>): TArray<Byte>;

    property MaxTransceiveLength: Integer read;
    property NfcB: JNfcB read;
    property Tag: JTag read;
  end;

  TNfcF = class
    function Transceive(Data: TArray<Byte>): TArray<Byte>;

    property MaxTransceiveLength: Integer read;
    property NfcF: JNfcF read;
    property Tag: JTag read;
    property Timeout: Integer read write;
  end;

  TNfcV = class
    function EasAlarm: TArray<Byte>;
    function GetSecurity(Block, Count: Byte): TArray<Byte>;
    function LockAfi: TArray<Byte>;
    function LockBlock(Block: Byte): TArray<Byte>;
    function LockDsfid: TArray<Byte>;
    function LockEas: TArray<Byte>;
    function ReadBlock(Block: Byte): TArray<Byte>;
    function ReadBlocks(Block, Count: Byte): TArray<Byte>;
    function ResetEas: TArray<Byte>;
    function ResetToReady: TArray<Byte>;
    function SetEas: TArray<Byte>;
    function Transceive(Data: TArray<Byte>): TArray<Byte>;
    function WriteAfi(AFI: Byte): TArray<Byte>;
    function WriteBlock(Block: Byte; Data: TArray<Byte>): TArray<Byte>;
    function WriteBlocks(Block, Count: Byte; Data: TArray<Byte>): TArray<Byte>;
    function WriteDsfid(DSFID: Byte): TArray<Byte>;

    property BlockCount: Integer read;
    property BlockSize: Integer read;
    property DsfId: Byte read;
    property Ic: Integer read;
    property Inventory: TArray<Byte> read;
    property MaxTransceiveLength: Integer read;
    property NfcV: JNfcV read;
    property ResponseFlags: Byte read;
    property SystemInformation: TArray<Byte> read;
    property Tag: JTag read;
  end;

  TNdef = class
    function MakeReadOnly: Boolean;
    function Write(NdefRecord: TNdefRecord): Boolean;
    function Write(NdefRecords: TArray<TNdefRecord>): Boolean;
    function Write(NdefRecords: array of TNdefRecord): Boolean;

    property CanMakeReadOnly: Boolean read;
    property IsWritable: Boolean read;
    property MaxSize: Integer read;
    property Ndef: JNdef read;
    property Records: TArray<TNdefRecord> read;
    property Tag: JTag read;
    property &Type: string read;
  end;

  TNdefFormatable = class
    function Format: Boolean;
    function FormatReadOnly: Boolean;

    property NdefFormatable: JNdefFormatable read;
    property Tag: JTag read;
  end;

  TMifareUltralightNTag = (muUnknown, mu203, mu210, mu212, mu213, mu215, mu216);

  TMifareUltralight = class
    function PageCount(NTag: TMifareUltralightNTag = muUnknown): Integer;
    // MIFARE Ultralight protocol always reads 4 subsequent pages
    function Read4Pages(Page: Integer): TArray<Byte>; // 4 pages are returned
    function Read4Pages(Page, Count: Integer): TArray<TArray<Byte>>; // Count * 4 pages are returned
    function Read4Pages(Pages: TArray<Integer>): TArray<TArray<Byte>>; // Length(Pages) * 4 pages are returned
    function WritePage(Page: Integer; Data: Cardinal): Boolean;
    function WritePage(Page: Integer; Data: TArray<Byte>): Boolean;
    function WritePages(Page: Integer; Data: TArray<Cardinal>): Boolean;
    function WritePages(Page: Integer; Data: TArray<TArray<Byte>>): Boolean;
    function WritePages(Pages: TArray<Integer>; Data: TArray<Cardinal>): Boolean;
    function WritePages(Pages: TArray<Integer>; Data: TArray<TArray<Byte>>): Boolean;
    function Transceive(Data: TArray<Byte>): TArray<Byte>;

    // NTAG commmands
    function Authenticate(Password: Cardinal): Word;
    function GetVersion: TArray<Byte>;
    function FastRead(StartPage, EndPage: Byte): TArray<Byte>;
    function Read(Page: Byte): TArray<Byte>;
    function ReadCounter: TArray<Byte>;
    function ReadSignature: TArray<Byte>;
    procedure Write(Page: Byte; Data: Cardinal);

    property MaxTransceiveLength: Integer read;
    property MifareUltralight: JMifareUltralight read;
    property Tag: JTag read;
    property Timeout: Integer read write;
    property &Type: Integer read;
    property TypeDescription: string read;
  end;

  TMifareClassic = class
    function ReadBlock(Block: Integer; KeyA, KeyB: TArray<Byte> = nil): TArray<Byte>;
    function ReadBlocks(Block, Count: Integer; KeyA, KeyB: TArray<Byte> = nil): TArray<TArray<Byte>>;
    function ReadBlocks(Blocks: TArray<Integer>; KeyA, KeyB: TArray<Byte> = nil): TArray<TArray<Byte>>;

    function WriteBlock(Block: Integer; Data: TArray<Byte>; KeyA, KeyB: TArray<Byte> = nil): Boolean;
    function WriteBlocks(Block: Integer; Data: TArray<TArray<Byte>>; KeyA, KeyB: TArray<Byte> = nil): Boolean;
    function WriteBlocks(Blocks: TArray<Integer>; Data: TArray<TArray<Byte>>; KeyA, KeyB: TArray<Byte> = nil): Boolean;

    property BlockCount: Integer read;
    property BlockSize: Integer read;
    property MifareClassic: JMifareClassic read;
    property MaxTransceiveLength: Integer read;
    property SectorCount: Integer read;
    property Size: Integer read;
    property Tag: JTag read;
    property Timeout: Integer read write;
    property &Type: Integer read;
    property TypeDescription: string read;
  end;

  TNdefRecord = class
    class function CreateExternalRecord(const Domain, &Type: string; const Data: TArray<Byte>): TNdefRecord;
    class function CreateApplicationRecord(const PackageName: string): TNdefRecord;
    class function CreateMimeRecord(const MimeType: string; const MimeData: TArray<Byte>): TNdefRecord;
    class function CreateTextRecord(const Text: string; const LanguageCode: string = 'en'): TNdefRecord;
    class function CreateUriRecord(const Uri: string): TNdefRecord;

    property ExternalText: string read;
    property IsAbsoluteUri: Boolean read;
    property IsEmpty: Boolean read;
    property IsExternalType: Boolean read;
    property IsMimeMedia: Boolean read;
    property IsText: Boolean read;
    property IsUnchanged: Boolean read;
    property IsUnknown: Boolean read;
    property IsUri: Boolean read;
    property IsWellKnown: Boolean read;
    property NdefRecord: JNdefRecord read;
    property Payload: TArray<Byte> read;
    property PayloadUtf8: string read;
    property Text: string read;
    property TextLanguageCode: string read;
    property TnfDescription: string read;
    property Uri: string read;
  end;

  TNdefMessage = class
    constructor Create(NdefRecord: TNdefRecord);
    constructor Create(NdefRecords: TArray<TNdefRecord>);

    property Records: TArray<TNdefRecord> read;
    property NdefMessage: JNdefMessage read;
  end;

// utilities

function BytesToHex(Bytes: TJavaArray<Byte>; Separator: Char = ':'): string;
function BytesToHex(const Bytes: TArray<Byte>; Separator: Char = ':'): string;
function BytesToHex(const Bytes: TArray<Byte>; From, Count: Integer; Separator: Char = ':'): string;

function BytesToHexReverse(Bytes: TJavaArray<Byte>; Separator: Char = ':'): string;
function BytesToHexReverse(const Bytes: TArray<Byte>; Separator: Char = ':'): string;
function BytesToHexReverse(const Bytes: TArray<Byte>; From, Count: Integer; Separator: Char = ':'): string;
								

Download and order

Related links