Overview
NFC (Near Field Communication) is set of standards that enable smartphones and similar devices to establish a radio communication*( requires a distance of 4cm or less to initiate a connection) and allows to transfer data such as text or numbers between two NFC enabled devices.
In practice, NFC enables simple and safe two- way interactions among electronic devices within a close proximity
NFC standards are based on RFID (radio frequency identification) standards.
NFC |
Device should be NFC enabled to use this technology
Nfc Features
• Short range technology
– Connection established when devices or tag close enough (5-10 cm)
– Simple setup (instant configuration)
• 2-way communication
– Not only reading like in contactless smart cards, but data exchange
• Passive tags
– No need for external power
– Low-price
• Security
– Support secure element
– Close proximity use brings some basic security
What can we store in NFC tags?
We can store variety of data on NFC TAG. The actual amount of data varies depending on the type of NFC tag used - different tags have different memory capacities. A standard Ultralight nfc tag can store a URL of around 41 characters, while NTAG203 can store data around 132 characters.
Usually, this information is stored in a specific data format (NDEF - NFC data exchange format) so that it can be reliably read by most devices and mobile phones.
Nfc Modes
• Read and write tags
• Peer-to-peer
• Card emulation
Android Support
– Read and write (excellent support)
P2P (limited)
Requirements for using NFC enabled application
Most Important requirement for a device is that it should have required hardware to support NFC feature
here is the list of NFC enabled mobile devices
Minimum API required
API level 9 only supports limited tag dispatch via Action_Tag_Discovered and only gives access to NDEF messages via the EXTRA_NDEF_MESSAGE extra. No other tag properties or I/O operations are accessible. API level 10 includes comprehensive reader/writer support as well as foreground NDEF pushing, and API level 14 provides an easier way to push NDEF messages to other devices with Android Beam and extra convenience methods to create NDEF records.
Permissions required for Android application to use NFC
<uses-permission android:name="android.permission.NFC" />
<uses-sdk android:minSdkVersion="10"/>
<uses-feature android:name="android.hardware.nfc" android:required="true" />
Key Players
NfcManager is the high level manager, used to obtain this device's NfcAdapter.
NfcAdapter represents the device's NFC adapter, which is your entry-point to performing NFC operations
NdefMessage Represents NDEF data message, which is the standard format in which "records" carrying data are transmitted between devices and tags. Your application can receive these messages from ACTION_TAG_DISCOVERED ntent.
NdefRecord Represents a record, which is delivered in a NdefMessage and describes the type of data being shared and carries the data itself.
How NFC tags are read
Reading NDEF data from an NFC tag is handled with the tag dispatch system , which analyzes discovered NFC tags, appropriately categorizes the data, and starts an application that is interested in the categorized data. An application that wants to handle the scanned NFC tag can declare an intent filter and request to handle the data.
Enabling foreground
/**
* Enables foreground intent detection
*/
public void enableForeground() {
if(!foreground) {
IntentFilter tagDetected = new IntentFilter(NfcAdapter.ACTION_TAG_DISCOVERED);
IntentFilter ndefDetected = new IntentFilter(NfcAdapter.ACTION_NDEF_DISCOVERED);
writeTagFilters = new IntentFilter[] {tagDetected, ndefDetected};
nfcAdapter.enableForegroundDispatch(context, nfcPendingIntent, writeTagFilters, null);
foreground = true;
}
}
Now we create a IntentFilter, to tell Android that our application is enabled to work on nfc tag (NfcAdapter.ACTION_TAG_DISCOVERED). We register our app with an intentFilter in the Manifest.
<activity android:name="com.example.activity.NfcReaderActivity" >
<intent-filter>
<action android:name="android.nfc.action.TAG_DISCOVERED" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
</activity>
method to read nfc tag
/**
* Reads the ndef messages from the given intent
*
* @param intent
* @return true if messages were extracted
*/
public boolean read(Intent intent) {
Log.d(TAG, "Read intent");
Parcelable[] messages = intent
.getParcelableArrayExtra(NfcAdapter.EXTRA_NDEF_MESSAGES);
if (messages != null) {
NdefMessage[] ndefMessages = new NdefMessage[messages.length];
for (int i = 0; i < messages.length; i++) {
ndefMessages[i] = (NdefMessage) messages[i];
}
if (ndefMessages.length > 0) {
listener.readNdefMessages(ndefMessages);
return true;
} else {
listener.readNdefEmptyMessage();
}
} else {
listener.readNonNdefMessage();
}
return false;
}
Writing NFC tags
public boolean write(final NdefMessage message, Intent intent) {
final Tag extra = intent.getParcelableExtra(NfcAdapter.EXTRA_TAG);
Thread t = new Thread(new Runnable() {
Tag tag = extra;
@Override
public void run() {
NdefFormatable format = NdefFormatable.get(tag);
if (format != null) {
Log.d(TAG, "Write unformatted tag");
try {
format.connect();
format.format(message);
listener.wroteNdefUnformatted();
return;
} catch (Exception e) {
listener.writeNdefUnformattedFailed(e);
}
finally{
try {
format.close();
} catch (IOException e) {
Log.d(TAG, "Cannot close connection to the tag.");
}
}
Log.d(TAG, "Cannot write unformatted tag");
} else {
Ndef ndef = Ndef.get(tag);
if (ndef != null) {
try {
Log.d(TAG, "Write formatted tag");
ndef.connect();
if (!ndef.isWritable()) {
Log.d(TAG, "Tag is not writeable");
listener.writeNdefNotWritable();
return;
}
if (ndef.getMaxSize() < message.toByteArray().length) {
Log.d(TAG,
"Tag size is too small, have "
+ ndef.getMaxSize() + ", need "
+ message.toByteArray().length);
listener.writeNdefTooSmall(
message.toByteArray().length, ndef.getMaxSize());
return;
}
ndef.writeNdefMessage(message);
listener.wroteNdefFormatted();
return;
} catch (Exception e) {
listener.writeNdefFormattedFailed(e);
}
} else {
listener.writeNdefCannotWriteTech();
}
Log.d(TAG, "Cannot write formatted tag");
}
}
});
t.run();
return success;
}
download the nfctools.jar file from here