Writing NFC Apps
with Apache Cordova
ApacheCon North America - April 7, 2014
Presented by Don Coleman / @doncoleman
What is NFC?
Subset of RFID.
Wireless communications.
4 to 20 cm.
In practice, make contact with devices.
What can I do with NFC?
Mobile Payments
Sharing Data between Phones
Pair with Bluetooth Device
Mass Transit Card
Smart Poster
We can't do payments, since we don't have access to the secure elements. http://www.amazon.com/HomeSpot-NFC-enabled-Bluetooth-Receiver-System/dp/B009OBCAW2
Devices
TODO add pictures
phone
shield
usb dongle
Tags hold a tiny amount of data
Think bytes
not kilobytes, megabytes, or gigabytes
Even a 1K tag only holds 716 bytes of data
Each tag type
Stores data in different binary format
Has different security features
Has different ways to read and write
Common properties
UID
Type
Technology
Capacity
Is Read Only
Is Lockable
Type is like Mifare Classic or Type 2
Technology is like Mifare Ultralight C for a Type 2 tag
NDEF
NFC Data Exchange Format
NDEF is an abstraction that allows us to read and write data to tags without worrying about the underlying implementation
NDEF Message
Contains 1 or more NDEF Records
NDEF Record
Messages contains a payload (or data) and some meta data about that payload
NDEF Record
TNF (Type Name Format)
Type
Payload
Record Id
TNF - constants
Type - works with TNF to describe the payload
Ignore the Record ID for now. We don't need it.
Let's look at some examples to make this clearer
Payload
Data for the user application
Sructure is opaque. Just bytes on a tag.
TNF - Type Name Format
Indicates the structure of the value of the type field
TNF Constants
Empty 0x0
Well Known 0x1
Mime Media 0x2
External 0x4
Type
Identifier describing the type of the Payload
Must follow rules implied by TNF
Must follow structure, encoding and format implied by the TNF
e.g. Well Known has Record Type Definition Constants
There are lots of specs for all this stuff
Meta Data about the Payload
Text Record
hello, world
TNF = Well Known
Type = T
Payload = 2 + en + hello, world
There is a spec that defines how to encode the payload
The text is prefixed with the language code
The first byte of the tag has the length of the language code
URI Record
http://cordova.io
TNF = Well Known
Type = U
Payload = 0x3 + cordova.io
There's a spec for this too.
http:// is shortened to 0x3
if the full url is encoded, prefix is 0x0
Mime Media Record
{ "message": "hello, world" }
TNF = Mime Media
Type = application/json
Payload = { "message": "hello, world" }
Helper Methods
ndef.textRecord("hello, world");
ndef.uriRecord("http://cordova.io");
ndef.mimeMediaRecord("text/json", '{...}');
NDEF Message
One or more NDEF Records
NDEF Record
Contains a payload of data
Information describing the payload
$ cordova create nfc com.example.nfc NFC
$ cd nfc
$ cordova platform add android
$ cordova plugin add \
com.chariotsolutions.nfc.plugin
Add a Listener
nfc.addNdefListener(
eventListener,
success,
failure
);
mention history and why this differs from other Cordova plugins
Add a Listener
nfc.addNdefListener(
app.onNfc,
success,
failure
);
Handle the Event
onNfc: function(nfcEvent) {
var tag = nfcEvent.tag,
ndefMessage = tag.ndefMessage;
alert(JSON.stringify(ndefMessage));
}
Decode the Payload
util.isType(record, tnf, type);
if (util.isType(rec, TNF_WELL_KNOWN, RTD_URI)) {
value = ndef.uriHelper.decodePayload(payload);
} else if (util.isType(rec, TNF_WELL_KNOWN, RTD_TEXT)) {
value = ndef.textHelper.decodePayload(payload);
} else if // ...
Write Data
Must call write within an event handler
Write Data
var message = [
ndef.uriRecord("http://cordova.io")
];
ndef.write(message, success, failure);
Write Data
var message = [
ndef.uriRecord("http://cordova.io"),
ndef.textRecord("hello, world")
];
ndef.write(message, success, failure);
Peer to Peer - Share Data
var message = [
ndef.uriRecord("http://cordova.io")
];
ndef.share(message, success, failure);
Unfortunately you need to do "Touch To Beam". IMO this worked much better in Android 2.3.
Do NOT need to call from within event handler
Handover
Start with NFC, complete with WiFi or Bluetooth
Handover
takePicture: function() {
navigator.camera.getPicture(
app.onCameraSuccess, failure);
},
onCameraSuccess: function (imageURI) {
nfc.handover(imageURI, success, fail);
}
Launching your App
<intent-filter>
<action android:name=
"android.nfc.action.NDEF_DISCOVERED"/>
<data android:mimeType="text/plain"/>
<category android:name=
"android.intent.category.DEFAULT"/>
</intent-filter>
Recap
Read message from tag or peer
Decode payload using TNF and Type
Write message to a tag
Share a message with a peer
Use handover for large messages
Launch app when scanning a tag
Cordova Hackathon
Tomorrow, Tuesday April 8, 2014
10:30am - 5:30pm
McCourt room at ApacheCon