A Complete Guide To Implementing NFC in Android Application
Ever wondered what NFC is and how to utilize its features in an Android application? In this article, we’ll go over the basics of NFC technology, meet the Android Beam feature and write a simple app to understand how two Android devices can interact via NFC. Here we go!
What is NFC?
NFC stands for Near Field Communication — its a set of protocols to provide short range communication to wirelessly exchange data either between two mobile devices or between a device and so-called NFC tag. The tag is usually represented by a sort of a passive device like a plastic card, sticker or even a huge advertisement stand embedded with a chip that is able to store and transfer data.
As for the NFC device itself, it basically does nothing since it’s not powered. It needs an active NFC device, like a smartphone, to generate a magnetic field and in this way trigger data exchange.
Advantages of NFC
The main advantage of this technology is versatility. NFC can be integrated into many types of businesses. It allows for such cool and modern things as on-the-fly payments, ticket scanning, raw data transfer, media exchange, identity verification, online wallets management, etc.
NDEF — NFC Data Exchange Format
NFC technology standards are maintained by the NFC Forum, a non-commercial organization that promotes NFC usage in household appliances, mobile devices and desktop PCs. The NFC Forum has defined a common data format used to store and exchange data between NFC devices and tags — NDEF.
Android Beam is a related NFC-powered technology that allows two Android devices to establish a short-range communication. The Android Beam feature allows a device to push an Ndef Message onto another device by physically tapping the devices together. This interaction provides an easier way to send data than other wireless technologies like Bluetooth, because with NFC, no manual device discovery or pairing is required. In this article we’re going to do exactly this.
The that we’re going to build will have 2 simple activities — a Sender and a Receiver. Data will be sent from the Sender activity of one device, and then received by a Receiver on another device.
Before we proceed, make sure you have:
- Android Studio 3.0
- Two Android devices with NFC and Android Beam support.
We are going to send and receive data in the form of the aforementioned NDEF messages. Reading NDEF data from an NFC tag is handled with the tag dispatch system, which analyzes all the 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.
In a well-formed NDEF message, the first NdefRecord contains the following fields:
- 3-bit TNF (Type Name Format). Indicates how to interpret the variable length type field.
- Variable length type. Describes the type of the record.
- Variable length ID. A unique identifier for the record.
- Variable length payload. The actual data payload that you want to read or write. An NDEF message can contain multiple NDEF records, so don’t assume the full payload is in the first NDEF record of the NDEF message.
If you would like to to delve into more details on this, please refer to Android Developers documentation, as describing all the details is out of the scope of this article:
NFC Basics | Android Developers
How NFC tags are dispatched to Applications
After scanning the NFC tag the Tag Dispatch System creates an intent that encapsulates the NFC tag itself and information it contains. This intent is then sent to an application that has registered for this intent (via Manifest).
As you may know, Android intent filterings works in such a way that if more than a single app on your device is registered for a specific intent than an application chooser will be displayed to the user to pick an app that will be launched to handle this intent. Three types of intents are defined by the Tag dispatch system, they are listed in order of higher priority:
ACTION_NDEF_DISCOVERED: This intent is used to start an Activity when a tag that contains an NDEF payload is scanned and is of a recognized type. This is the highest priority intent, and the tag dispatch system tries to start an Activity with this intent before any other intent, whenever possible.
ACTION_TECH_DISCOVERED: If no activities register to handle the ACTION_NDEF_DISCOVERED intent, the tag dispatch system tries to start an application with this intent. This intent is also directly started (without starting ACTION_NDEF_DISCOVERED first) if the tag that is scanned contains NDEF data that cannot be mapped to a MIME type or URI, or if the tag does not contain NDEF data but is of a known tag technology.
ACTION_TAG_DISCOVERED: This intent is started if no activities handle the ACTION_NDEF_DISCOVERED or ACTION_TECH_DISCOVERED intents.
If possible, you should aim at the ACTION_NDEF_DISCOVERED, since it’s the most specific intent. The best practice is to avoid displaying an application chooser to the user, because they will most likely be forced to move their device from the tag, thus, interrupting the NFC connection. The application has to anticipate incoming intents as precise as possible to provide a seamless experience.
This is the basic schema of how NDEF intents work:
Add NFC Support in an App
Firstly we need to specify that the app supports NFC feature in the AndroidManifest.xml.
Ask for permission:
Specify restrictions. In case the device doesn’t support NFC, the app won’t be available for download on Google Play (not even listed):
Implementing Sender Activity
Layout is pretty simple, just an EditText to enter your message you want to push, Button to set it and a TextView to display what you’re going to send:
To begin with, we check that the device supports the NFC feature (as we didn’t install it from Google Play). We do it in onCreate() method:
In case NfcAdapter comes null device does not support NFC, so we just display an appropriate message and finish the activity:
Then check if NFC is enabled on the device, if not then we suggest that user should turn it on:
In order not to keep the NFC-related logic in the activity, we create a separate class to encapsulate this logic:
This class will be responsible for creating NDEF message from the input we provided in the EditText in the SenderActivity. It implements two interfaces:
- NfcAdapter.CreateNdefMessageCallback — responsible for dynamically creating and sending the message the very moment our device comes into range of another NFC device.
- NfcAdapter.OnNdefPushCompleteCallback — signals when the message is successfully pushed to another device
Communication between OutcomingNfcManager and SenderActivity is done through an interface the SenderActivity implements:
After we’ve done preliminary NFC checks, in the same onCreate() method let’s set the OutcomingNfcManager as a callback that will handle the creation of a message that we want to push to another device:
That’s all for the SenderActivity. Let’s get to ReceiverActivity.
For the activity to be able to receive NDEF messages from another device we specify intent filter in the AndroidManifest file:
There are some key methods ReceiverActivity needs to override. First of all:
onNewIntent() will be called whenever ReceiverActivity is launched with some Intent. This is the case for receiving a new message and replacing the previous one if ReceiverActivity is already launched. Here we check the intent the activity was launched with:
We should extract the action from the intent and expect it to be ACTION_NDEF_DISCOVERED.
In case it is really so we proceed with parsing and displaying the message to the user.
We also register the activity for the so-called foreground dispatch. This is done to give to the app the highest priority for incoming NDEF messages so that no any other application filtering ACTION_NDEF_DISCOVERED on the device could not intercept the message we push:
We construct and configure an intent with filters we want to handle when the app is in the foreground and set MIME-type of the data we expect.
Then register it in onResume():
And also unregistering:
As you’ve notice we call receiveMessageFromDevice() here as well. This is done to be able to get an intent if ReceiverActivity was not in the foreground at the moment of establishing NFC communication. When app reaches the resumed state, it is guaranteed that it’s in the foreground, so we register for foreground dispatch and can safely parse the received NDEF message if any.
Unregister before the app goes into the background state:
That’s all folks, the sample app is finished. Now you know how to send and receive data from one device to another, how to setup appropriate intent filters, register for foreground dispatch and how to construct and parse NDEF messages.
You can check out the full code in this GitHub project:
We also know that not all of our readers are coders. So if you’d like to implement a mobile NFC-based application, but you’re not very familiar with Java, Swift, or coding in general, feel free to contact us at [email protected] and we’ll help you turn your idea into reality!
Also, If you liked the article, please support it with claps and by hitting the subscribe button below!
How to Implement NFC in Android Application: A Complete Guide was originally published in JetRuby on Medium, where people are continuing the conversation by highlighting and responding to this story.
This post first appeared on JetRuby Agency - Featured Technical Stories Based In Our Experience, please read the originial post: here