Sunday, March 8, 2015

First steps with NFC in Android - Android NFC App tutorial

 Develop an Android app that read NFC tags or add NFC capabilities to your app 

Topics covered

NFC

NDEF

NFC Foreground dispatch

NFC payload

NFC filter

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 web site where you can buy NFC with a few euro.
NFC can be used in 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



NFC Filter

When we use 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-filter>
<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 word when a 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 foreground. If our app is running in foreground, it won't be notified, if move our smart phone near a 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 smart phone. 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 smart phone 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 read different NDEF types and how to extract information from the tag.
Don't forget to read how to handle more complex NFC tag as Poster tag, Text tag.



First steps with NFC in Android - Android NFC App tutorial Rating: 4.5 Diposkan Oleh: Unknown

0 comments:

Post a Comment