Since December I'm a happy owner of a Galaxy Nexus :)
NFC seemed like an interesting thing, so I started to integrate NFC support into PAW.
First thing I did was to order some Mifare Classic 1K tags from
tagsfordroid.com.
They arrived fairly quickly and delivery was free of charge.
 |
| NFC Tags |
To try things out I installed a lot of NFC reader and writer apps. To my dismay none of them seemed to work.
They could read the tags but could not write them. Having no idea how NFC worked, I was fairly disappointed :(
Searching the web I found out that this seems to be a bug in ICS:
http://code.google.com/p/android/issues/detail?id=22258
Googles sais that there will be a fix provided, but when, no one can tell.
So I tried to get it working myself...
If you would like to test the things below, install the
latest PAW version (0.80) from the Android Market.
Disclaimer:
This solution is only working for Mifare Classic 1K tags!
If you try as described you do it at your own risk!
It's not my fault if your tags do not work afterwards!
Read the updates at the end of the post first!
This solution is no longer necessary and will most likely damage your tag(s), so do not use it!
The Problem
The problem (as reported in the bug report) seems to be that the tech reported by the tag do not contain
android.nfc.tech.Ndef which is necessary to write NDEF messages.
You can try this with the following code that you can insert into the BenShell Console of the PAW web application:
import de.fun2code.android.pawserver.AndroidInterface;
import android.nfc.NfcAdapter;
intent = AndroidInterface.getNfcIntent(5); // 5 secs timeout
if(intent != null) {
tag = intent.getParcelableExtra(NfcAdapter.EXTRA_TAG);
print(tag);
}
else {
print("No Tag found!");
}
If the result is
TAG: Tech [android.nfc.tech.MifareClassic, android.nfc.tech.NfcA] writing NDEF messages will not work!
The Possible Fix
As mentioned above I have no expirience with NFC, so I tried to find a solution that worked without having to know NFC or the Mifare tags in detail.
I searched the web and found some Mifare Classic 1K dumps at the
nfc-tools site.
After downloading a dump I tried to write it to the tag. Interesting enough it seemd to work :)
After writing the dump, the above script reported:
TAG: Tech [android.nfc.tech.MifareClassic, android.nfc.tech.NfcA, android.nfc.tech.Ndef]
So here are the step by step instructions:
- Download the dump file from the nfc-tools site: mfc_1k__url_nfc-tools.mfd
- Save the dump file to the /sdcard of your android device.
- Start PAW and open the BeanShell console.
- Copy/paste the following script into the console:
/*
Mifare Classic - Write dump
*/
import de.fun2code.android.pawserver.AndroidInterface;
import android.nfc.NfcAdapter;
import android.nfc.NdefRecord;
import android.nfc.NdefMessage;
import android.nfc.tech.*;
import android.os.Bundle;
intent = AndroidInterface.getNfcIntent(5); // 5 secs timeout
print(intent);
if(intent != null) {
tag = intent.getParcelableExtra(NfcAdapter.EXTRA_TAG);
print(tag);
if(tag != null) {
nfc = MifareClassic.get(tag);
nfc.connect();
print("Is connected: " + nfc.isConnected());
fis = new FileInputStream("/sdcard/mfc_1k__url_nfc-tools.mfd");
b = new byte[16];
errors = 0;
sectors = nfc.getSectorCount();
blocksPerSector = nfc.getBlockCountInSector(0);
for(sector=0; sector<sectors; sector++) {
print("Sector " + sector);
for(block=0; block < blocksPerSector; block++) {
logicBlock = nfc.sectorToBlock(sector) + block;
$$.print(" Block: " + block + " ... ");
fis.read(b);
if(sector == 0 && block == 0) {
print("Manufacturer block ... skipped");
continue;
}
try {
nfc.authenticateSectorWithKeyA(sector, MifareClassic.KEY_DEFAULT);
nfc.writeBlock(logicBlock, b);
print("ok");
}
catch(e) {
print("error");
errors++;
}
}
}
fis.close();
nfc.close();
print("--------------------------------------------------------------------------");
print("Errors: " + errors);
print("Dump written!");
}
else {
print("Tag not supported!");
}
}
else {
print("No Tag found!");
}
- Start the script and as soon as the PAW app is in foreground, place the tag at the back of the phone and leaf it there until the script is finished.
After that the tag is hopefully working.
Good luck and happy hacking :)
Update:
Ndef.getMaxSize() returns only 92 bytes that can be written to a NDEF message. I don't think that's normal :(
You can check this yourself with the following code:
import de.fun2code.android.pawserver.AndroidInterface;
import android.nfc.NfcAdapter;
import android.nfc.tech.Ndef;
intent = AndroidInterface.getNfcIntent(5); // 5 secs timeout
if(intent != null) {
tag = intent.getParcelableExtra(NfcAdapter.EXTRA_TAG);
print("Max NDEF message size: " + Ndef.get(tag).getMaxSize() + " bytes");
}
else {
print("No Tag found!");
}
Update 2:
The latest
NFC TagWriter by NXP is able to format unformatted tags and fixes the problem.
Here is the Android Market link:
NFC TagWriter by NXP