Skip to content
Language: EN

Which technology class should Android code open for a given tag?

The highest level that does the job. Ndef reads and writes content on any NFC Forum type, NdefFormatable prepares a blank tag, IsoDep carries APDUs, and NfcA or NfcV send raw commands when content is not enough. Check getTechList first: three classes are optional and never appear on some phones.

What getTechList reports

Every discovered tag comes with a Tag object, and its getTechList() names the classes your code may open on it. A tag usually reports several at once: the MifareUltralight reference notes that NfcA is enumerated alongside it in every case, since each such tag is also an NFC-A tag.

The technology classes, and whether a phone must provide them
ClassWhat it gives your codeRequired on every phone
NdefNDEF read and write on NFC Forum types 1 to 4Yes
NdefFormatableFormatting a blank tag and writing a first messageOnly for tags the phone can format
NfcA, NfcB, NfcF, NfcVRaw commands at the radio level of each technologyYes
IsoDepAPDUs over ISO/IEC 14443-4Yes
MifareClassicSector access after key authenticationNo
MifareUltralightPage reads and writesNo
NfcBarcodeTags that hold only a barcodeNo

The list is fixed at discovery. The TagTechnology reference divides every class into cached getters, which describe the tag as it was when it entered the field and never update, and I/O operations, which talk to the tag and may block.

The highest level that does the job

Ndef hides the differences between tag types: the same calls read and write a Type 2 sticker and a Type 4 card. Code written against it keeps working when the supplier changes chips.

The raw classes remove that protection. NfcA.transceive() sends your bytes as they are, the controller adding only the CRC, so the command set and the memory map become your problem, and both differ from one chip to the next. They are defined in each chip's datasheet, which this site leaves to wakdev.com.

IsoDep sits between the two. It carries APDUs to cards and to Type 4 tags, and the IsoDep reference says it fragments and reassembles long exchanges itself, so your code sends whole commands.

NdefFormatable is for one moment in a tag's life. Its reference concedes that the procedures to format a tag are not specified by the NFC Forum and not generally known, which is why the class appears only on tags a given phone knows how to format.

One connection at a time

A tag accepts one open class at a time. The reference says so plainly, and a second connect() fails with IOException, so code that opens Ndef to read and then NfcA to query the chip has to close the first before opening the second.

Every call that touches the radio blocks and must stay off the main thread. close() is the way out of a blocked call: made from another thread, it cancels the pending operation with IOException.

A Tag object is also tied to one appearance. The Tag reference says a new object is created each time the tag comes into range, even for the same physical tag, and only the most recent can open a class. Using an older one after its tag has left raises SecurityException.

Classes a phone may not offer

Three classes are optional, and their absence is silent. A phone that does not implement MifareClassic never lists it, so the same card reports the class on one phone and not on another, and code that assumed it fails only in the field.

Ndef itself is guaranteed only on NFC Forum types 1 to 4. The Ndef reference treats vendor formats, NDEF stored on MIFARE Classic included, as best effort, and recommends the NFC Forum types for new deployments for that reason.

So test for the class, not for the phone model. The list reported by the tag in hand is the only answer that still holds on the next phone.

Frequently asked questions

Can I open Ndef and NfcA on the same tag at once?

No. Only one class can be connected to a tag at a time, so close the first before connecting the second.

Why is NdefFormatable missing on a blank tag?

The phone does not know how to format that tag. The reference says the class is enumerated only for tags the device can format, and no set of tags is mandatory.

Why does getCachedNdefMessage still show the old content after a write?

It returns the message read when the tag entered the field and never updates. Read the current content with getNdefMessage, which talks to the tag.

Should new code use MifareClassic?

Only to read existing MIFARE Classic cards, and with a fallback for phones that lack it. The class is optional, and the Ndef reference recommends NFC Forum types for new deployments.