Develop an Android app that read NFC tags or add NFC capabilities to your app
NFC
NDEF
NFC Foreground dispatch
NFC payload
NFC filter
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.
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):@OverrideNow we have to register our filter, and we do it in
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();
}
}
onResume
method, in this way: protected void onResume() {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.
super.onResume();
nfcAdpt.enableForegroundDispatch(
this,
nfcPendingIntent,
intentFiltersArray,
null);
handleIntent(getIntent());
}
@Overridewhere nfcAdpt is the NFC Adapter.
protected void onPause() {
super.onPause();
nfcAdpt.disableForegroundDispatch(this);
}
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.
0 comments:
Post a Comment