Android & NFC howto
When a NFC tag is discovered, the system checks if the foreground application has registered to such an Intent with a call to enableForegroundDispatch(). If not, it checks whether any other applications has registered for the NDEF_DISCOVERED intent. If an application want to register for events related to a tag of a specific technology (e.g. classic MiFare tags) then it should register to the TECH_DISCOVERED intent.The following diagram explains in details how an event related to reading a tag is handled:
Read NFC tag in Android
Declare in the manifest a specific Activity to receive an Intent when a NFC tag is read by the device:<activity android:name=".NfcReaderActivity" android:label="NfcReaderActivity">
<intent-filter>
<action android:name="android.nfc.action.TAG_DISCOVERED"/>
<category android:name="android.intent.category.DEFAULT"/>
</intent-filter>
</activity>
To register the foreground Activity for tag reading events, add following lines to onResume() method:
@Override
protected onResume() {
PendingIntent pendingIntent = PendingIntent.getActivity(this, 0, new Intent(this, this.getClass()).addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP), 0);
mAdapter.enableForegroundDispatch(this, pendingIntent, null, null);
}
In the onNewIntent(Intent)to read the tag after receiving a ACTION_TAG_DISCOVERED intent :
protected void onNewIntent(Intent intent) {
String action = intent.getAction();
if (NfcAdapter.ACTION_TAG_DISCOVERED.equals(action)){
Parcelable[] rawMsgs = intent.getParcelableArrayExtra(NfcAdapter.EXTRA_NDEF_MESSAGES);
NdefMessage[] messages;
if (rawMsgs != null) {
messages = new NdefMessage[rawMsgs.length];
for (int i = 0; i < rawMsgs.length; i++) {
messages[i] = (NdefMessage) rawMsgs[i];
// To get a NdefRecord and its different properties from a NdefMesssage
NdefRecord record = messages[i].getRecords()[i];
byte[] id = record.getId();
short tnf = record.getTnf();
byte[] type = record.getType();
String message = getTextData(record.getPayload());
}
}
}
}
This is how to read the content tag of type text RTD_TEXT:
// Decoding a payload containing text
private String getTextData(byte[] payload) {
if(payload == null)
return null;
try {
String encoding = ((payload[0] & 0200) == 0) ? "UTF-8" : "UTF-16";
int langageCodeLength = payload[0] & 0077;
return new String(payload, langageCodeLength + 1, payload.length - langageCodeLength - 1, encoding);
} catch(Exception e) {
e.printStackTrace();
}
return null;
}
Write NFC tag in Android
In the manifest:<uses-permission android:name="android.permission.NFC" /> <uses-feature android:name="android.hardware.nfc" android:required="true" />in onCreate() get the NfcAdapter:
NfcAdapter nfcAdapter = NfcAdapter.getDefaultAdapter(this);The data part of a TAG is a NdefMessage of multiple NdefRecord this is how to encode a text into a payload:
// Encoding a text into a tag payload
NdefRecord createRecord(String message) {
byte[] langBytes = Locale.ENGLISH.getLanguage().getBytes(Charset.forName("US-ASCII"));
byte[] textBytes = message.getBytes(Charset.forName("UTF-8"));
char status = (char) (langBytes.length);
byte[] data = new byte[1 + langBytes.length + textBytes.length];
data[0] = (byte) status;
System.arraycopy(langBytes, 0, data, 1, langBytes.length);
System.arraycopy(textBytes, 0, data, 1 + langBytes.length, textBytes.length);
return new NdefRecord(NdefRecord.TNF_WELL_KNOWN, NdefRecord.RTD_TEXT, new byte[0], data);
}
// Create a message from a record
NdefMessage createMessage(NdefRecord record) {
NdefRecord[] records = new NdefRecord[1];
records[0] = record;
NdefMessage message = new NdefMessage(records);
return message;
}
To enable/disable sending a message each time a tag is read
@Override
protected void onPause() {
super.onPause();
nfcAdapter.disableForegroundNdefPush(this);
}
@Override
protected void onResume() {
super.onResume();
NdefRecord record = creerRecord("this is a message");
NdefMessage message = creerMessage(record);
nfcAdapter.enableForegroundNdefPush(this, message);
}
If there is no tag, we can simulate a tag been read by sending the corresponding intent, this is how:
final Intent intent = new Intent(NfcAdapter.ACTION_TAG_DISCOVERED);
NdefMessage[] messages = new NdefMessage[1];
messages[0] = createMessage(createRecord("Simulating a tag reception"));
intent.putExtra(NfcAdapter.EXTRA_NDEF_MESSAGES, messages);
startActivity(intent);
Reference Programming Android, chapter 16: Sensors, NFC, Speech, Gestures, and Accessibility.

I actually enjoyed reading through this posting.Many thanks.Good article! We are linking to this great article on our site. Keep up the good writing.
RépondreSupprimerwebsite design