Skip to content

NDEF

NFC Data Exchange Format (NDEF) tags are very common in the industry, also the integration is pretty straightforward.

Before starting, we recommend you to read the NFC basics.

Setup

The first thing is to declare the NFC permission in your AndroidManifest.xml:

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

Following this, make sure NFC support is checked on installation with a simple line in AndroidManifest.xml:

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

Then, declare an intent filter for an Activity with the appropriate MIME types:

<intent-filter>
    <action android:name="android.nfc.action.NDEF_DISCOVERED"/>
    <category android:name="android.intent.category.DEFAULT"/>
    <data android:mimeType="text/plain" />
</intent-filter>

For more details, you can read here to understand how NFC tags are mapped to MIME types and URIs.

Finally, you need to override onNewIntent() method in your Activity:

@Override
protected void onNewIntent(Intent intent) {
    super.onNewIntent(intent);

    if (NfcAdapter.ACTION_NDEF_DISCOVERED.equals(intent.getAction())) {
        // Either read or write an NDEF tag here
    }
}

Reading an NDEF tag

The following code shows how to extract the messages from a NDEF tag:

final Parcelable[] rawMessages =
        intent.getParcelableArrayExtra(NfcAdapter.EXTRA_NDEF_MESSAGES);
if (rawMessages != null) {
    final NdefMessage[] messages = new NdefMessage[rawMessages.length];
    // NDEF data is encapsulated inside an NdefMessage that contains
    // one or more NdefRecord
    for (int i = 0; i < rawMessages.length; i++) {
        messages[i] = (NdefMessage) rawMessages[i];
        for (NdefRecord ndefRecord : messages[i].getRecords()) {
            final String message =
                    new String(ndefRecord.getPayload(), StandardCharsets.UTF_8);
            Toast.makeText(this, "Tag: " + message, Toast.LENGTH_SHORT).show();
        }
    }
}

Writing an NDEF tag

To write an NDEF message, you can use the following code as an example:

private void writeNdef(Intent intent, String payload) {
    final NdefMessage ndefMessage = new NdefMessage(
            NdefRecord.createTextRecord(Locale.ENGLISH.getLanguage(), payload));

    final Ndef ndef = Ndef.get((Tag) intent.getParcelableExtra(NfcAdapter.EXTRA_TAG));
    try {
        ndef.connect();

        if (!ndef.isWritable()) {
            Toast.makeText(this, "Tag is read-only", Toast.LENGTH_SHORT).show();
            return;
        }
        if (ndef.getMaxSize() < ndefMessage.getByteArrayLength()) {
            Toast.makeText(this,
                "Message is too long to be written on this tag", Toast.LENGTH_SHORT).show();
            return;
        }

        ndef.writeNdefMessage(ndefMessage);
        ndef.close();

        Toast.makeText(this, "Tag successfully written", Toast.LENGTH_SHORT).show();
    } catch (IOException | FormatException e) {
        Log.e(TAG, e.getMessage(), e);
    }
}