How to write data into NFC tags in Android?

H

NFC stands for “Near Field Communication” and, as the name implies, it enables short range communication between compatible devices. This requires at least one transmitting device, and another to receive the signal.  NFC allows you to share small payloads of data between an NFC tag and an Android-powered device, or between two Android-powered devices.

I was developing an application in which I had to accept the data from a spinner and two edit text fields, combine the data and write it into NFC tag.

I followed  these simple steps to write the data into NFC tag:

1)      Declare an Intent Filter to announce to the system that it’s enabled to work on NFC.

2)      Have a method that Android will call when NFC is detected.

3)      Create a method to build a NDEF message.

4)      Create a method to write the NDEF message.

________________________________________________________________________________________________________

Manifest :

<uses-feature

android:name=“android.hardware.nfc”

android:required=“false” />

<uses-permission android:name=“android.permission.NFC” />

________________________________________________________________________________________________________

package com.nanostuffs.nfc.activity;

 

import java.io.IOException;

import java.io.UnsupportedEncodingException;

 

import android.app.Activity;

import android.app.AlertDialog;

import android.app.PendingIntent;

import android.content.Context;

import android.content.DialogInterface;

import android.content.Intent;

import android.content.IntentFilter;

import android.nfc.FormatException;

import android.nfc.NdefMessage;

import android.nfc.NdefRecord;

import android.nfc.NfcAdapter;

import android.nfc.Tag;

import android.nfc.tech.Ndef;

import android.os.Bundle;

import android.provider.Settings;

import android.util.Log;

import android.view.View;

import android.widget.Button;

import android.widget.EditText;

import android.widget.Spinner;

import android.widget.Toast;

 

import com.nanostuffs.nfc.R;

 

public class WriteActivity extends Activity {

private NfcAdapter adapter;

private PendingIntent pendingIntent;

private IntentFilter writeTagFilters[];

private Tag mytag;

private Context ctx;

private Button write;

private String writeTag;

private Spinner selectFarmer;

private EditText noOfBags;

private EditText fuel;

 

@Override

protected void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);

setContentView(R.layout.write);

initializeComponents();

}

 

private void initializeComponents() {

selectFarmer = (Spinner) findViewById(R.id.sel_farmer_spinner);

noOfBags = (EditText) findViewById(R.id.no_of_bags_edit);

fuel = (EditText) findViewById(R.id.fuel_litres_edit);

write = (Button) findViewById(R.id.write);

ctx = this;

adapter = NfcAdapter.getDefaultAdapter(this);

pendingIntent = PendingIntent.getActivity(this, 0, new Intent(this,

getClass()).addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP), 0);

IntentFilter tagDetected = new IntentFilter(

NfcAdapter.ACTION_TAG_DISCOVERED);

tagDetected.addCategory(Intent.CATEGORY_DEFAULT);

writeTagFilters = new IntentFilter[] { tagDetected };

}

________________________________________________________________________________________________________

With last 5 rows we create a IntentFilter, so we tell Android that our application is enabled to work on nfc tag (NfcAdapter.ACTION_TAG_DISCOVERED). We could register our app directly with a intentFilter in the Manifest. In this way we couldn’t lunch our Activity like a simple program, but Android will boot it when it detects a tag. In both ways, after detecting and deciding which app has to work on with the tag, Android will call the method onNewIntent and pass the object tag to the activity:

________________________________________________________________________________________________________

@Override

protected void onNewIntent(Intent intent) {

if (NfcAdapter.ACTION_TAG_DISCOVERED.equals(intent.getAction())) {

mytag = intent.getParcelableExtra(NfcAdapter.EXTRA_TAG);

Toast.makeText(this,

this.getString(R.string.ok_detection) + mytag.toString(),

Toast.LENGTH_SHORT).show();

}

}

________________________________________________________________________________________________________

So now we have the object tag and we have to build the function to create the NDEF message and to write it into the NFC tag.

________________________________________________________________________________________________________

private NdefRecord createRecord(String text)

throws UnsupportedEncodingException {

String lang = “en”;

byte[] textBytes = text.getBytes();

byte[] langBytes = lang.getBytes(“US-ASCII”);

int langLength = langBytes.length;

int textLength = textBytes.length;

byte[] payload = new byte[1 + langLength + textLength];

// set status byte (see NDEF spec for actual bits)

payload[0] = (byte) langLength;

// copy langbytes and textbytes into payload

System.arraycopy(langBytes, 0, payload, 1, langLength);

System.arraycopy(textBytes, 0, payload, 1 + langLength, textLength);

NdefRecord recordNFC = new NdefRecord(NdefRecord.TNF_WELL_KNOWN,

NdefRecord.RTD_TEXT, new byte[0], payload);

return recordNFC;

}

private void write(String text, Tag tag) throws IOException,

FormatException {

NdefRecord[] records = { createRecord(text) };

NdefMessage message = new NdefMessage(records);

// Get an instance of Ndef for the tag.

Ndef ndef = Ndef.get(tag);

// Enable I/O

ndef.connect();

// Write the message

ndef.writeNdefMessage(message);

// Close the connection

ndef.close();

}

________________________________________________________________________________________________________

Now we have to check if the device supports the NFC feature and if it is enabled.If so ,write the data.

________________________________________________________________________________________________________

@Override

public void onResume() {

super.onResume();

writeModeOn();

}

private void writeModeOn() {

if (adapter != null) {

adapter.enableForegroundDispatch(this, pendingIntent,

writeTagFilters, null);

write.setOnClickListener(new View.OnClickListener() {

@Override

public void onClick(View v) {

writeTag = selectFarmer.getSelectedItemId()+1005 + “~”

+ noOfBags.getText() + “~” + fuel.getText();

try {

if (mytag == null) {

Toast.makeText(ctx,

ctx.getString(R.string.error_detected),

Toast.LENGTH_LONG).show();

} else {

write(writeTag, mytag);

Toast.makeText(ctx,

ctx.getString(R.string.ok_writing),

Toast.LENGTH_LONG).show();

}

} catch (IOException e) {

Toast.makeText(ctx,

ctx.getString(R.string.error_writing),

Toast.LENGTH_LONG).show();

e.printStackTrace();

} catch (FormatException e) {

Toast.makeText(ctx,

ctx.getString(R.string.error_writing),

Toast.LENGTH_LONG).show();

e.printStackTrace();

}

}

});

if (!adapter.isEnabled()) {

new AlertDialog.Builder(this)

.setPositiveButton(“Update Settings”,

new DialogInterface.OnClickListener() {

 

public void onClick(DialogInterface arg0,int arg1) {

Intent setnfc = new Intent(Settings.ACTION_WIRELESS_SETTINGS);

startActivity(setnfc);

}

})

.setOnCancelListener(

new DialogInterface.OnCancelListener() {

public void onCancel(DialogInterface dialog) {

finish();

}

}).create().show();

}

} else {

Toast.makeText(getApplicationContext(),

“Sorry, No NFC Adapter found.”, Toast.LENGTH_SHORT).show();

}

 

}

________________________________________________________________________________________________________

If the user exits the application disable the NFC adapter.

________________________________________________________________________________________________________

@Override

public void onPause() {

super.onPause();

writeModeOff();

}

private void writeModeOff() {

if (adapter != null) {

adapter.disableForegroundDispatch(this);

 

}

}

}

About the author

rakshita.hegde
By rakshita.hegde

Category