打造你的第一支 NFC 程式 – Hello,NFC!

作者:
瀏覽:659

打造你的第一支 NFC 程式 – Hello,NFC!

(圖片來源:http://www.android-apk.com/wp-content/uploads/2013/05/sony-nfc-promo.jpg

想像有一天,看到朋友們拿著手機熱烈的討論著某位正妹的照片,你不用擠破頭跟大家搶手機來看,你只需要將兩隻手機輕輕一碰,正妹的照片咻一下的就傳了過來。回家要搭捷運,再也不需要在人擠人的捷運站匆忙的找著悠遊卡,只要拿出手機,感應一下就可通過,達到卡機合一的境界。晚上要睡覺前,輕輕感應床頭邊的貼紙,手機立刻就調成靜音模式並且設定好隔日的鬧鐘。
如此輕鬆方便的生活,NFC 都可以為您做到!

那 NFC 到底是什麼呢?

NFC (Near Field Communication) 中文稱為近場通訊,是由 Nokia,Philips 和 SONY 共同研發的一種短距離通訊技術,允許兩件設備在20公分內進行非接觸式的資料傳輸[1]。
NFC 這項技術在近幾年來是越來越熱門,新出的 Android 手機大都支援 NFC,也因此衍生出越來越多的應用和產品,像是利用 NFC 在手機間分享資料,NFC 付款等等。也有比較特別的像 NFC 印表機,NFC 冰箱等新奇的產品。
不過要成為一位專業的 NFC 玩家,並不是一定要購買市面上五花八門的產品,其實我們也可以客製化自己的 NFC,以下就來介紹如何利用 Firefox OS 來撰寫自己的第一支 NFC 程式!

打造我的 Hello, NFC !

首先要準備以下材料:
1. 一隻支援 NFC 的手機 (目前支援 NFC 的 FireFox OS 手機是 Nexus4)。
2. 一張可讀寫的 NFC Tag。
3. B2G 開發環境。

就只要這樣,接下來就可以開始 Coding 囉 ~
我們的目標是要來撰寫一支當手機感應到 NFC Tag 時,可以印出 Hello, NFC! 的程式。而第一件事就是要告訴系統當感應到 NFC Tag 時,必須要通知我們。
而在 Firefox OS 裡,是利用 Web Activities [2] 來通知應用程式有關 NFC 的訊息,因此首先我們先在 webapp.manifest 增加下列屬性

"activities": {
  "nfc-ndef-discovered": {
  }
}

看到這裡,相信各位一定有個疑問,什麼是 NDEF ?
這裡的 NDEF (NFC Data Exchange Format) [3]指的是 NFC Tag 裡儲存的資料格式,是 NFC Forum 用來統一不同 NFC 裝置傳輸的界面,簡而言之,就是一種公定的資料格式,而在稍候的文章會有更進一步的介紹。

而除了 manifest 外,在 js code 中,也要新增處理 activity 的程式碼

navigator.mozSetMessageHandler('activity', activityHandler);

function activityHandler(activity) {
  var activityName = activity.source.name;
  var data = activity.source.data;

  switch (activityName) {
    case 'nfc-ndef-discovered':
      console.log('Hello, NFC!');
      handleNDEF(data);
      break;
  }
}

寫到這裡,其實已經大功告成了,各位可以拿出手機去感應一下手邊的 NFC Tag,相信就可以從 log 上看到令人感動的 Hello, NFC! 了。如果沒有看到的話,請記得去設定頁面將 NFC 打開。
不過相信這短短的10行 code 是沒有辦法滿足大家的,因此我們可以再更進一步將 Tag 的內容讀出,而要讀取 Tag 裡的資料,就需要跟 NDEF message 打交道,不過在處理 NDEF 之前,讓我們先來了解一下 NDEF 的格式。

從圖一可以看出一個 NDEF Message 是由許多個 NDEF Record 所組成。

打造你的第一支 NFC 程式 – Hello,NFC!

圖一、NDEF 格式

而在 NDEF Record 中的 TNF (Type Name Format) 欄位則定義了這些 Record 的內容。

打造你的第一支 NFC 程式 – Hello,NFC!

圖二、TNF

從圖二可以看到除了 RFC 所定義的標準格式外,還有 NFC Forum 自己定義的 RTD (Record Type Definition)[4],因此當我們要判斷 NDEF 裡的內容時,首先要先檢查 TNF ,如果是 RTD type 的話就要再檢查是哪一種 RTD 。

假設今天我們想要得到 NFC Tag 裡文字的內容,利用下列程式碼就可以判斷感應到的 Tag 是否儲存文字並將資料讀出。

function handleNDEF(data) {
  if (data.records[0].tnf == 1 && data.records[0].type == 'T') {
    // Assume there is only one record for simplicity.
    let textPayload = data.records[0].payload;
  } else {
    // Not Text Data
  }
}

程式碼中的 textPayload 就儲存了文字的內容,而這樣我們也就完成了一支可以讀取 NFC Tag 的程式了,是不是非常容易!
當然除了讀寫 NFC Tag 以外,NFC 也支援所謂的點對點 (P2P) 模式,我們可以在兩隻支援 NFC 的手機間互相傳送資料,像是照片,音樂,聯絡人資訊 … 等等。
而 Firefox OS 當然也支援大家來共同開發這樣的應用程式,不過由於筆者懶惰篇幅有限,就不在此贅述了。
有興趣的人可以加入我們或參考Wiki[5],相信一定很快就可以寫出更厲害的 NFC App!

參考資料:
[1] http://en.wikipedia.org/wiki/Near_field_communication
[2] https://developer.mozilla.org/zh-TW/docs/WebAPI/Web_Activities
[3] http://developer.nokia.com/Community/Wiki/Understanding_NFC_Data_Exchange_Format_%28NDEF%29_messages
[4] NFC Record Type Definition (RTD) Technical Specification
[5] https://wiki.mozilla.org/WebAPI/WebNFC