First steps with NFC in Android – Android NFC App tutorial

This post describes how to develop Android NFC app. The NFC technology stands for Near Field Communication and you can find the specification at NFC Forum. In this first post, we will analyse some basic aspects of NFC in Android, and we will describe how to implement a Android NFC app to read tags.
If you want to experiment NFC, there are several websites where you can buy NFC with a few euro.
NFC can be used in a different situation: we can use it to turn on our Wifi when we are at home or launch task actions and so on.
We will focus our attention on NDEF data that is a special type of NFC tag. There are some basic steps we have to follow before using the NFC.

getting started with nfc

Getting started with Android NFC App: NFC Filter

When we develop an Android NFC Tag, the first thing we want is our app is notified when we get near a NFC tag. To this purpose we use a intent filter. Android SDK provides three different filter that we can use with different level of priority:

  • ACTION_NDEF_DISCOVERED
  • ACTION_TECH_DISCOVERED
  • ACTION_TAG_DISCOVERED
We focus our attention on ACTION_NDEF_DISCOVERED, that has the highest level of priority. As said, our goal is being notified when the smart phone is near a NFC tag and, if we have only this app installed and capable to handle this NFC tag, we want that the app starts immediately. To do it, we register the filter in the Manifest.xml:
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
  package="com.survivingwithandroid.nfc" >
  ....
 <intent-filte>
  <action android:name="android.nfc.action.NDEF_DISCOVERED" />
  <category android:name="android.intent.category.DEFAULT" />
  <data android:mimeType="text/plain"/>
  </intent-filter>
<manifest>

At line 6 we register our app so that it can be notified with ACTION_NDEF_DISCOVERED.
We can use different types of filter, in this example (at line 8) we used mime type. In other words when an NFC tag NDEF is discovered and it has a mime type text/plain then our app will be started. We can filter using several mime types not only text/pain. We can, moreover, use other type of filters like android:scheme to filter using the protocol or using a string pattern.

Android NFC – Foreground Dispatch

Filtering with intents works if our app is not in a foreground. If our app is running in foreground, it won’t be notified, if move our smartphone near an NFC tag. In this case, we have to use a different technique called NFC Foreground dispatch.
The first step is defining in our code the intent filter (as we did in the manifest.xml):

 @Override
protected void onCreate(Bundle savedInstanceState) {
  ...
  Intent nfcIntent = new Intent(this, getClass());
  nfcIntent.addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP);

  nfcPendingIntent =
    PendingIntent.getActivity(this, 0, nfcIntent, 0);

  IntentFilter tagIntentFilter =
    new IntentFilter(NfcAdapter.ACTION_NDEF_DISCOVERED);
  try {
    tagIntentFilter.addDataType("text/plain");
    intentFiltersArray = new IntentFilter[]{tagIntentFilter};
  }
  catch (Throwable t) {
   t.printStackTrace();
  }
}

Now we have to register our filter, and we do it in onResume method, in this way:

 protected void onResume() {
  super.onResume();
  nfcAdpt.enableForegroundDispatch(
    this,
    nfcPendingIntent,
    intentFiltersArray,
    null);
    handleIntent(getIntent());
}

We should, also, remember to disable foreground dispatch as soon as the app gets in background and the best place to do it is in onPause method.

 @Override
protected void onPause() {
  super.onPause();
  nfcAdpt.disableForegroundDispatch(this);
}

where nfcAdpt is the NFC Adapter.

Handle NFC using NFCAdapter

Once we created our filters, we have to interact with the NFC component in our smartphone. For this purpose, we use NfcAdapter, provided by Android SDK. Using this class, we can check, for example, if the NFC is supported by our smartphone or if the NFC is turned on or off:

 @Override
protected void onCreate(Bundle savedInstanceState) {
  ...
  nfcAdpt = NfcAdapter.getDefaultAdapter(this);
  // Check if the smartphone has NFC
  if (nfcAdpt == null) {
   Toast.makeText(this, "NFC not supported", Toast.LENGTH_LONG).show();
   finish();
  }
  // Check if NFC is enabled
  if (!nfcAdpt.isEnabled()) {
   Toast.makeText(this, "Enable NFC before using the app", Toast.LENGTH_LONG).show();
  }
}

NFC Data: Payload

Once we know how to handle NFC tag, we want to read the tag content. There are several type of content defined in NFC specs:

  • NFC Forum well-known type
  • Media-type
  • Absolute URI
  • NFC Forum external type

Each type has it is own payload. Generally speaking, a NFC NDEF data is composed by a Message. A message can contain one or more records. Each record is made by an header and a payload (the real information).
By now, if we want to read the data inside a NFC NDEF tag we can use:

 @Override
public void onNewIntent(Intent intent) {
  Log.d("Nfc", "New intent");
  getTag(intent);
}

private void getTag(Intent i) {
  if (i == null)
   return ;

  String type = i.getType();
  String action = i.getAction();
  List<ndefdata>dataList = new ArrayList<ndefdata>();

  if (NfcAdapter.ACTION_NDEF_DISCOVERED.equals(action)) {
    Log.d("Nfc", "Action NDEF Found");
    Parcelable[] parcs = i.getParcelableArrayExtra(NfcAdapter.EXTRA_NDEF_MESSAGES);

    for (Parcelable p : parcs) {
     recNumberTxt.setText(String.valueOf(numRec));
     NdefRecord[] records = msg.getRecords();
     for (NdefRecord record: records) {
       short tnf = record.getTnf();
       // Here we handle the payload
     }
   }
 }
}

In the next post, we will describe how to develop an Android NFC Tag that reads different NDEF types. Moreover, you know how to extract information from the tag.
Don’t forget to read how to handle more complex NFC tag as Poster tag, Text tag.

  • Enrique Perez

    I created a similar application from you, but with more code, follow your tutorial to make my more compact and better app, thanks for sharing knowledge, now I only need to read the contents of my label Nfc and finish my project 🙂

    He creado una aplicacion similar a la de usted, pero con mas codigo, seguire su tutorial para hacer mi app mas compacta y mejor, gracias por compartir conocimiento, ahora solo me falta leer el contenido de mi etiqueta Nfc y terminare mi proyecto 🙂

    • Hola Enrique Perez, podrias compartir tu github ?
      Hi Enrique Perez, can you share with us your NFC github

  • Sherp Avert

    Hola Francesco,
    Muchas gracias para el tutorial, pero es mas fácil de hablar ingles …
    I need, after reading a NFC tag in the main activity, to start another one that need too to read tags to do others actions.
    Starting from your source on github, I have just created the second activity (cloning main) and the second activity is started from the Settings menu. Only the text color differentiates the 2 layouts. I have added the second activity in the manifest file (again, just cloning the lines from the main activity).
    But, when I read a tag from the second activity, the scheduled intent is always the main activity and I go back to this one …
    Any help would be really welcome !
    Muchas gracias si usted puede ayudar mi !!!

    • Sherp Avert

      In fact, as I advance in my development, i realize that probably a basic knowledge is missing …

      Being unable to get my second activity running, my ne idea was, reading the first tag, to change the layout but staying in my first activity (with some internal flags letting me know in which step I am when the second nfs read will arrive).
      But when i read my second tag, my program “restarts”, really in another process, execute onCreate and … switch back to the first layout, my internal flag being reinitialized ….
      Por favor, ayuda me en la comprensión …

    • Did you register your new activity to receive foreground notifications?