Things I have learnt about NFC on Android

Cheers!

Some months ago I started one of those projects you start, you hold, you retake, you forgot’em, you go back to… those projects that when you retake them you meet your past self, that self you are ashamed of because you see a technology newbie. You still appreciate him, but you’d have a chat about… “fancy a fifa party?”.

This outstanding project with a thousand breaks has been named NFCar, and it started as a test to begin in the NFC for Android world. The idea was to create a mechanism which would mod the phone to a specially designed desk for the car, from which to have better access to those apps you might use while driving, besides than showing your car’s logo. This is one of those projects you do it for yourself, and gets published at Market just because, without aiming it to get really used. If you got curious: http://kcy.me/90yj

With this post I’m looking to share with you all I’ve learnt about NFC besides of reminding it to the future Roc, just in case something following is forgotten:

  • In Android 4.0 NCF chips cannot be formatted in NDEF, which is a quite cool standard to write in NFC. This has some important meanings: if you haven’t bought the NDEF pre-formatted tags, forgot about it. And if you hand write a single byte in a NDEF formatted tag, avoiding the standard, you’ll have broke the NDEF format permanently. #congratsson
  • Android apps cannot be proactive and ask if there is a NFC near. Tag connection is acquired via Intent, and you are responsible of saving the provided instance in order to use it further. That is to say, if the phone has sent you a signal telling you’ve got an NFC nearly, and you missed it, is lost. The NFC tag keeps near, and you know it, but you cannot access it. #congratsson
  • If you want to keep a connection with an NFC tag (because you know it will be nearly for a while), you cannot. I mean, you can’t set a listener “enDesconexióDeNfc” “onNfcDisconnected”. You can create yourself a method if needed to keep calling nfc.isConnected() periodically. This will work perfectly at home, with the phone USB connected to the computer… also when you test it with the phone disconnected… But, when the battery is low, quite far from your test results, it is possible to lose the connection with the NFC even with the device touching the phone. So, with the battery lower than 100%, your onNfcDisconnected listener will work for a while… 5 seconds… 30 seconds… even a minute. But there will come a time it will return false, and you won’t understand the reason. It’s simply because your battery isn’t fully charged. And this is not documented anywhere. And I am testing it with the galaxy Nexus, the Google’s beauty. #congratsson
  • The Android Developers Manual explains how to start the Activity through the Intent thrown when you bring the phone closer to a NFC tag. This is rather good, and when your app grows you will see that your main Activity is absolutely docked with the business is run over the NFC. This means that my main Activity where I like to have only view and user interaction, I have a lot of docked code managing the NFC control. Alright Google, the way of implementing NFC detection is sending me an Intent which launches one of my activities… but don’t try to convince me that this is good. Now that the project is finished I see it wouldn’t have been a bad idea to manage all the NFC connections through a see-through Activity which would forward an Intent to my man Activity depending on the case. So, summarizing: Google proposes a… doubtful arquitectre. #congratsson
  • Every NFC chip is written its own way. I don’t mind to write the bytes in 64bit packs to improve efficiency when able, or maybe to write using lines when the tag requires it… but I don’t relish to be obliged to learn how to work with every single new chip appearing. A “writeString” and a “readString”. That’s it. I’m not asking that much, am I? If the String is too long for that NFC tag, a TooLongMEssageException could be thrown. And that’s all. #congratsson
  • The mobile phone makes a sound every time an NFC is reached. The mobile phone turns off the NFC scan when the screen is switched off. The mobile phone triggers the NFC scan when the screen is switched on. These 3 elements which alone are not a mistake, altogether they are a patience attack when we work with my idea: phone near the NFC all the car trip along. Nothing happens when the screen turns off. But when you switch it on again… the sound again. The phone considers the NFC is new, just appeared there. And there is no way from your app to decide if it is new or not. The phone sounds definitively, and you cannot disable this audible notification anyway. Actually, not even user can. #congratsson

 

Despite these points: good enough. Actually, Android 4.0 has brought a very sexy detail: writing an NFC with an own Android Standard, so you can write there your app’s package. When the phone comes near this NFC no Intent is sent to any application, but the application is launched if installed. Otherwise it goes alone to the Market for it to be downloaded. Pretty good! This functionality brings a bunch of possibilities. Fetch your phone near the Bicing station and download the official app. Or don’t.

When I’ll have a while I’ll upload the code to Google Code for you to see what I’ve written. I hope it to be very useful, and specially to avoid you from failing as I’ve failed. Stay tuned to this post! :·)

Special thanks to Saúl Prior for translating this article to english! :·)

Coses que he après sobre l’NFC a Android

Bones!

Fa uns mesos vaig començar un d’aquells projectes que els comences, els talles, els segueixes, els oblides, hi tornes a treballar… d’aquells projectes que qual els reprens, coneixes al teu jo del passat. Aquell jo del que te n’arrepenteixes, que es nota que estava descobrint una nova tecnologia. Que te l’estimes, però li dires un parell de paraules ben dites. O tres… “fem un fifa?”.

Aquest flamant projecte mil vegades interrumput s’ha anomenat NFCar, i va començar com una prova per a conéixer el món de l’NFC sobre Android. L’idea era la de tenir un mecanisme on, a l’apropar el telèfon al cotxe, s’actives un escriptori especialment dissenyat per al cotxe, des d’on tenir un millor accès a les aplicacions que s’utilitzen mentre condueixes, i a més, afegint al layout el logotip del teu cotxe. És un d’aquells projectes que els fas per tu mateix, i que es publiquen al Market perquè si, sense moltes ganes de que es converteixi en una aplicació gaire utilitzada. Si us fa curiositat: http://kcy.me/90yj

Amb aquest post el que busco és compartir amb vosaltres tot el que he après d’NFC, i a més, recordar-li-ho a en Roc del futur, per si alguna vegada no se’n recorda d’algun d’aquests punts:

  • En Android 4.0 els tags NFC no es poden formatejar en NDEF, que és un standard molt chulo per a escriure en NFC. Això té algunes implicacions molt importants: Si no has comprat els tags pre-formatejats en NDEF, oblida’t d’escriure en format NDEF. I si en un tag formatat en NDEF hi escrius algun byte a ma, sense utilitzar l’standard, et carregaras el format NDEF i mai més el recuperaras. #etfelicitofill
  • Les aplicacions no poden ser proactives i preguntar si hi ha un NFC aprop. La connexió amb el tag es reb via Intent, i tu mateix has de guardar l’instància que se’t proporciona per a poder utilitzar-la en un futur. És a dir, si el mobil t’ha enviat una senyal de que tens un NFC aprop, i no te l’has guardat, ja ho has perdut. El tag NFC segueix aprop, i ho saps. Però no hi pots accedir. #etfelicitofill
  • Si vols mantenir una connexió amb un tag NFC (perquè saps que el tindras molt aprop durant molt de temps), no ho pots fer. És a dir, no pots posar un listener “onNfcDisconnected”. Si vols, pots crear-te tu mateix un mètode que vagi cridant a nfc.isConnected() periòdicament. És un mètode que funciona molt bé a casa, amb el mobil connectat via USB amb el teu ordenador… també quan fas proves amb el mobil desconnectat… Però quan la bateria baixa, molt i molt lluny del teu banc de proves, pot ser que la connexió amb l’NFC es perdi, tot i tenir el NFC enganxat al mobil. És a dir, si la bateria no està al 100%, el listener onNfcDisconnected que tu mateix t’has programat funcionarà una estona… 5 segons… 30 segons… potser un minut. Però arribarà un moment en que tornarà false, i no entendras per què. Doncs és perquè no tens la bateria al màxim. I això no està documentat enlloc. I ho estic provant amb el Galaxy Nexus, el nen bonic de Google. #etfelicitofill
  • El manual d’Android Developers t’explica com iniciar l’Activity a traves de l’Intent que es llença quan apropes el teu mobil a un tag NFC. Això està molt bé, i quan la teva aplicació creix, veus que la teva Activity principal està totalment acoplada amb el negoci que es fa sobre l’NFC. És a dir, que en la meva Activity principal, on m’agrada que tan sols es parli de Vista i interacció amb l’usuari, hi tinc un munt de codi acoplat que gestiona el control sobre l’NFC. Entesos, Google, la manera d’implementar la detecció d’un NFC és enviant-me un Intent que obre una de les meves Activities… però no m’animis a fer-me veure que això és bo. Ara que ja tinc el projecte acabat, veig que no hauria estat pas malament que tota la gestió de l’NFC fos en una Activity d’aquelles que no ensenyen res de res, i que depenguent del cas, em llences un Intent cap a la meva Activitat principal. Doncs bé, resumint: Google ens planteja una arquitectura… dubtosa. #etfelicitofill
  • Cada model de tag NFC s’escriu d’una manera. No em sembla malament poder escrirue els bytes en blocs de 64 bits per a millorar l’eficiència quan es pot, o poser-ho fer per linies quan aquell tag NFC en concret ho requereix… però no m’agrada estar obligat a empapar-me com s’escriure en cada un dels xips que van apareixent. Vull un “writeString” i un “readString”. I ja està. No demano tant. Si l’String és massa llarg per aquell tag NFC, que em llençi una TooLongMessageException. I ja està. #etfelicitofill
  • El mobil fa un soroll cada vegada que troba un NFC. El mobil desactiva l’scan d’NFC quan s’apaga la pantalla. El mobil torna a activar l’scan d’NFC quan s’encèn la pantalla. Aquests 3 elements que per separat no són pas dolents, junts són un atac a la paciència quan treballem amb la meva idea: mobil aprop de l’NFC durant tot el teu trajecte en cotxe. Quan s’apaga la pantalla, no passa res. Quan tornes a encendre la pantalla… s’emet de nou un soroll. Es considera que aquell NFC és nou, que te l’acaben de posar allà. I no forma part de la teva aplicació decidir si és nou o no. El mobil sona, si o si, i no pots apagar aquesta notificació sonora de cap manera. De fet, ni tan sols l’usuari pot. #etfelicitofill

 

A part d’això: molt bé. De fet, Android 4.0 s’ha inventat una cosa molt sexy: Escriure un NFC amb un standard propi d’Android, de manera que s’hi escriu el package de la teva aplicació. Aleshores, quan s’apropa el mobil a aquest NFC no es llença un Intent cap a cap aplicació, sino que o et llança l’aplicació definida pel package si la tens instal·lada, o et porta cap al Market per a que te la descarreguis. Molt bé! Amb aquesta funcionalitat s’obre un món de possibilitats. Apropa el teu mobil a aquesta estació de Bicing i baixa’t l’aplicació oficial. O no.

Quan tingui un moment, pujaré el codi de l’app a Google Code per a que podeu veure el que he escrit. Espero que us sigui molt últil, i sobretot, que no patiu els fracassos que jo he patit. Stay tuned to this post! :·)