Writing tags with Nexus S
Posted on Jan 14, 2011 - By Gustavo D. GonzalezAs said by Google CEO Eric Schmidt two month ago, the operating system Android 2.3 includes support for near field communication. But, at least in terms of the API and the sample code they supply, this version only includes tag reading capability. However, the PN544 NFC chip inside the Nexus S supports read and write operations so, at the hardware level, all the functionality you need to support a full range of NFC services is in the handset. At the software level, there will be updates to the SDK rolled out on a phased basis that will enable developers to write NFC applications for mobile payments, p2p and other applications on Android Gingerbread devices.
We’ve been analyzing the Android kernel source code and we found a lot of “@hide” tags in the NFC java classes. These are in:
frameworks/base/core/java/android/nfc
frameworks/base/core/java/com/android/internal/nfc
packages/apps/Nfc (the android service running in the background)
packages/apps/Tag (the application used to read and store tags)
And the hardware abstraction layer from NXP is in:
external/libnfc-nxp
Let’s see an example, the publised API for the class NCFAdapter has only two public methods:
getDefaultAdapter(): Get a handle to the default NFC Adapter on this Android device.
isEnabled(): Return true if this NFC Adapter has any features enabled.
But also has this public methods with the @hide tag:
enable(): Enable NFC hardware.
disable(): Disable NFC hardware.
createRawTagConnection(): Create a raw tag connection to the default Target.
createNdefTagConnection(): Create an NDEF tag connection to the default Target .
Interesting, isn’t it?
The “@hide” tag is used to mark public APIs that are not to be exported in the SDK. This is used by the Android team to have APIs accessible across packages without having them available to applications. APIs marked with @hide are considered private to the Android platform and can change at any time, so you cannot rely on them. So, with this in mind, we can confirm that there is some extended NFC functionality hidden in Android 2.3 that can be accessed, i.e. with reflection techniques. Let’s see how we can do this.
To write tags we’ll use the write() method from the INfcTag interface, so lets dive from NfcAdapter to the INfcTag. First we need a handle to the NFC adapter within the Nexus S:
NfcAdapter nfcAdapter = NfcAdapter.getDefaultAdapter();
Then we need a handle to the actually detected tag, this is done by getting the the data within the intent received when tag was discovered:
Parcelable nfcTag = intent.getParcelableExtra("android.nfc.extra.TAG");
Field f = nfcTag.getClass().getDeclaredField("mServiceHandle");
f.setAccessible(true);
Object mServiceHandle = f.get(nfcTag);
Now, we can create a raw connection to the tag, this is a low-level connection to a tag target. We’ll use this object to get later a handle to the INfcTag
Class tag = Class.forName("android.nfc.Tag");
Method createRawTagConnection = nfcAdapter.getClass().getMethod("createRawTagConnection", tag);
Object rawTagConnection = createRawTagConnection.invoke(nfcAdapter, nfcTag);
Now we can get the handle to the INfcTag interface (mTagService).
Field f = rawTagConnection.getClass().getDeclaredField("mTagService");
f.setAccessible(true);
Object mTagService = f.get(rawTagConnection);
Before we can write to the tag we connect our interface to it.
Method connect = mTagService.getClass().getMethod("connect", Integer.TYPE);
connect.invoke(mTagService, mServiceHandle.intValue());
Finally, we create the NdefTagRecord, this could be a smart poster, an uri, simple text or whatever record we want to write into the tag. This record will be encapsulated into an NdefMessage, so when we invoke the write() method we use this ndefMessage as parameter:
Method write = mTagService.getClass().getMethod("write", Integer.TYPE, NdefMessage.class);
write.invoke(mTagService, mServiceHandle, ndefMessage);
… and that’s it!
The write() method will work as long as you use a tag pre-formatted with any NFC Forum type tag with default public keys.
We developed an application using this code to write tags. Below you can see a demo of this app writing an URI type tag:
Tagged Android 2.3, Nexus S, NFC, Tag.
53 Comments
Trackbacks and Pingbacks
-
[…] tags in the NFC java classes,” says the firm’s Gustavo Gonzalez in a blog post detailing the discovery. “The @hide tag is used to mark public APIs that are not to be exported in the SDK. This is […]
-
[…] – Gibraltar […]
-
[…] Gibraltar (una compagnia argentina che si occupa di software) ha scoperto il codice, che abilita questa nuova funzionalità, “taggato” col tag @hide che permette alle funzioni di essere accessibili ma non disponibili alle applicazioni, oltre che essere ovviamente non documentate. […]
-
[…] As shipped, Android 2.3 Gingerbread only allows tag reading. This means that the Nexus S, the first Gingerbread handset, can only so far retrieve information from pre-programmed near field communication tags. But Google has promised that write functionality is on the way soon with some upcoming extensions to the SDK. An NFC development house in Argentina, Gibraltar, has unearthed the write tags. […]
-
[…] As shipped, Android 2.3 Gingerbread only allows tag reading. This means that the Nexus S, the first Gingerbread handset, can only so far retrieve information from pre-programmed near field communication tags. But Google has promised that write functionality is on the way soon with some upcoming extensions to the SDK. An NFC development house in Argentina, Gibraltar, has unearthed the write tags. […]
-
[…] group in Argentina by the name of Gibraltar Software Factory has been picking their way through the Nexus S, through its Android 2.3 Gingerbread innards, and […]
-
[…] compagnia Gibraltar Software Factory, società argentina che, come il nome suggerisce, si occupa di sviluppo software, è riuscita a […]
-
[…] group in Argentina by the name of Gibraltar Software Factory has been picking their way through the Nexus S, through its Android 2.3 Gingerbread innards, and […]
-
[…] group in Argentina by the name of Gibraltar Software Factory has been picking their way through the Nexus S, through its Android 2.3 Gingerbread innards, and […]
-
[…] group in Argentina by the name of Gibraltar Software Factory has been picking their way through the Nexus S, through its Android 2.3 Gingerbread innards, and […]
-
[…] – Gibraltar […]
-
[…] bien, un desarrollador ha descubierto dentro del código fuente de Android, en la clase java NFC, métodos para la […]
-
[…] group in Argentina by the name of Gibraltar Software Factory has been picking their way through the Nexus S, through its Android 2.3 Gingerbread innards, and […]
-
[…] Nexus S ganhou o poder de escrever tags NFC – não oficialmente, mas […]
-
[…] get it done, but we expect the hack to become more widely available soon.(thanks to IntoMobile and Gibraltar) Join the forum discussion on this […]
-
[…] Pending Review Matt Wakeman some users have started to uncover hidden (private APIs) – http://gibraltarsf.com/blog/?p=13 – This will soon lead to apps where you can, for example – Clone you oyster card or door entry […]
-
[…] supports ISO-14443 based protocols which run at 13.56MHz.1 Comment • Insert a dynamic date herehttp://gibraltarsf.com/blog/?p=13 – Tags can also be written…. via Private APIsMatt Wakeman • Insert a dynamic date hereView 1 […]
-
[…] har några argentinska utvecklare letat i koden för Android 2.3 och hittat dolda funktioner för att skriva information till NFC-kretsar, något som hårdvaran i Nexus S också har stöd […]
-
[…] few weeks ago, the guys at the Gibraltar Software Factory demonstrated how the Nexus S can write NFC tags using hidden code in Gingerbread. We’ve duplicated their […]
-
[…] As shipped, Android 2.3 Gingerbread only allows tag reading. This means that the Nexus S, the first Gingerbread handset, can only so far retrieve information from pre-programmed near field communication tags. But Google has promised that write functionality is on the way soon with some upcoming extensions to the SDK. An NFC development house in Argentina, Gibraltar, has unearthed the write tags. […]
-
[…] very limited access to the NFC hardware; providing a public API limited to reading tags. Undocumented APIs have been discovered to allow writing tags too, but interacting with the secure element (essential for the more […]
-
[…] programmers very limited access to the NFC hardware; providing a public API limited to reading tags.Undocumented APIs have been discovered to allow writing tags too, but interacting with the secure element (essential for the more […]
-
[…] the necessary APIs by loading them using Java's reflection capabilities and making them public.http://gibraltarsf.com/blog/?p=13Insert a dynamic date hereView All 0 CommentsCannot add comment at this time. Add […]
-
[…] reader/writers. Use one of them (or the Nexus S itself)Here's an example of using the Nexus S http://gibraltarsf.com/blog/?p=13Insert a dynamic date hereView All 0 CommentsCannot add comment at this time. Add […]
-
[…] As shipped, Android 2.3 Gingerbread only allows tag reading. This means that the Nexus S, the first Gingerbread handset, can only so far retrieve information from pre-programmed near field communication tags. But Google has promised that write functionality is on the way soon with some upcoming extensions to the SDK. An NFC development house in Argentina, Gibraltar, has unearthed the write tags. […]
-
[…] As shipped, Android 2.3 Gingerbread only allows tag reading. This means that the Nexus S, the first Gingerbread handset, can only so far retrieve information from pre-programmed near field communication tags. But Google has promised that write functionality is on the way soon with some upcoming extensions to the SDK. An NFC development house in Argentina, Gibraltar, has unearthed the write tags. […]
-
[…] and we found a lot of '@hide' tags in the NFC java classes," says the firm's Gustavo Gonzalez in a blog post detailing the discovery. "The @hide tag is used to mark public APIs that are not to be exported in the SDK. This is used by […]
-
[…] presente su questo smartphone ma la funzione non poteva essere abilitata, ma grazie al team della Gibraltar Software Factory, un’azienda che si occupa di sviluppo software, ora può essere attivato, dato che hanno […]
That’s a nice piece of work! We’ve written about it in NFC World:
http://www.nearfieldcommunicationsworld.com/2011/01/25/35758/
Mike 🙂
Can you post a link to the app for testing purposes or at least to the complete source code?
Thanks!
Great Work!
I would love to be able to download the app you have in your demo to test it on my phone too.
(With or without the source code.)
Gab
just to clear up my understanding in this space – the android doesnt use a “published” NFC standard right? so the iPhone tags wont be read by nexus phones or vice versa right?
Hi, Dean. Android actually USE the published NFC standards about NDEF messages and records (uri/text/smart poster) to read tags. The one that we used in the demo was a mifare classic with NFC Forum standard info stored inside it. So, as long as the iPhone tags complain these standards Nexus will read them.
Hi
Thats a great development for the Nexus s and we would be very interested to know you be releasing your app to purchase through google Market?
Dear Gustavo,
that’s great news indeed! I’m working on the new visitor information system for the Capitoline Museums based on NFC tags (5230 phones and MIFAR tags). A Nexus S will soon be available to me, too, and I would surely be interested in the app.
Been trying this with a MiFare 4k card, and the write command is always returning an unknown error. Can you post some simple code to show how you’ve created the NdefMessage so I can compare it against my code? Thx.
Nice work guys. You may already have discovered this with your work, but we learned from some of our U.S. customers about some strange problems reading our NFC enabled products (including the card type you are using in your demo) with the Nexus phone.
http://www.personalrosettastone.com/
It didn’t take long to discover that the OS aborts the read if the URL is too long. In fact if your product or tag, such as ours, has a detail section, name or title to go along with the URL then the ability of the Nexus S to read the NFC is very unlikely. This is a pretty significant problem for this phone. Even if you don’t use any title field at all, which is NDEF, then the URI still has some limiting length requirements which users will stumble on as ‘not readable’.
This is equivalent to your web browser only being able to open web pages that have really short names if the page has a header title, name or supporting detail. If the header is too long you get a 404 error but works fine if you use another browser (i.e. Nokia 6212, etc)
The Nexus S does have the ability to read the detail section / title as well as the URI field out of the box but we found this limitation in size (total bytes) as quite a surprise, but we suspect they thought NFC was only going to be for payments back when the hardware was designed.
Let’s keep our fingers crossed that Google discovers this easy fix before consumers start coding tags with tools such as yours. If not it might users shaking their heads about this technology I’m afraid.
AZCoder,
Objecs Technical support.
PersonalRosettaStone.com
“The write() method will work as long as you use a tag pre-formatted with any NFC Forum type tag with default public keys.”
Where can I get cards? Do MiFare cards come pre-formatted.
Hi, I tried the code an got the next error:
01-31 10:45:49.238: WARN/System.err(2003): java.lang.NoSuchFieldException: mServiceHandle
On the obvious line:
Field f = nfcTag.getClass().getDeclaredField(“mServiceHandle”);
However, I can see this attribute when debugging the variable nfcTag.
Any idea why this doesn’t work?
Thanks by advance!
Can you please publish / send by email a sample application or an executable that works for 2.3.3?
I just want to buy several empty tags to play with.
Thanks!
To Alexandre Gherschon,
Remember to get the intent when the tag was discovered:
Intent intent = getIntent();
Managed to get this working with Mifare Classic 1k label tag…very basic but does the job of writing any url placed in the text box to the tag. Doing NFC for my honours project at uni and it comes in very handy to be able to write to the tags using my Nexus S so thanks.
I refer you to a page created by Adam Rocker, this is not mine and I take no credit.
http://translate.google.co.uk/translate?hl=en&sl=ja&u=http://www.adamrocker.com/&ei=OEVITfYCxcuEB4T_kIEF&sa=X&oi=translate&ct=result&resnum=2&ved=0CCQQ7gEwAQ&prev=/search%3Fq%3Dadamrocker%2B/blog/%26hl%3Den%26prmd%3Divns
There is a very useful Zip file on there (SOURCE CODE!) which implements tag writing on the Nexus S.
Gustavo
Intent intent = getIntent();
This line means that we will have to have an intent originated by discovery of an NFC tag. But what if we don’t want discovery of an NFC tag rather we just want to start an activity from the Launcher and then we want to write the tag by clicking on a button from within that activity.
Also for NdefMessage I will put a fake tag as they are available inside MockNdefMessages class of the NFCDemo available in the Android SDK.
Regards,
Asif
Asif,
Even if you start an activiy from the launcher to click a button and write a tag, you’ll need the tag in the antenna’s field, so your app will be able to write the ndefmessage. At that moment the NFCService running in the background will discover the tag and broadcast the TAG_DISCOVERED intent anyway.
Regards
We have tested the nexus s to read 16 blocks of data (256 bytes), not quite a full Mifare1k tag (45 addressable blocks) but plenty of data for URL or messages. We have found that the smart poster record however is very particular and it took allot of testing to figure out how it was implemented in Android 2.3. Because there are many variations of the smart poster configurations (which is just a number of other NDEF records packed into a single message) we find that implementations are not always as flexible as NFC Forum would have liked them to be so you have to follow some more common practices with your smart poster rather than using the NFC Forum specification as written.
Anyone looking for tags, NFC reader/writer, and application to write NDEF messages you can get it here: http://mobifyer.com
We put together an Android developers kit to help people test their applications and get setup for real world deployments.
I used the method to access an ISO 14443 smart card.
It works as long as the APDUs are not too long.
It really looks like there’s either a length or time limit for requests or responses.
Has anyone looked into this?
Hi,
Anybody managed establish a P2P connection between Nexus S and ACR122U Tag Reader ?
Help is much appreciated.
Thanks,
Praveen
No..
NFCAdapter.getDeafultAdapter(this) returns null on my Nexux S
This is valid for android 2.3.1.