陳三清
摘? ?要:近年來(lái),NFC技術(shù)在移動(dòng)設(shè)備、消費(fèi)類電子產(chǎn)品等近距非接觸式的眾多領(lǐng)域得到了廣泛應(yīng)用,其基本原理本質(zhì)上是RFID技術(shù)。Android是現(xiàn)在使用最為廣泛的移動(dòng)智能設(shè)備,Android平臺(tái)上有支持NFC應(yīng)用開發(fā)的類和方法。在Android平臺(tái)的NFC應(yīng)用開發(fā)中,文章主要闡述了AndroidManifest文件中NFC應(yīng)用開發(fā)設(shè)定、NFC標(biāo)簽的過濾、NFC數(shù)據(jù)的關(guān)鍵讀取和寫入操作。
關(guān)鍵詞:近距離無(wú)線通信;Tag標(biāo)簽;Android;近距離無(wú)線通信編程
近年來(lái),隨著通信技術(shù)的發(fā)展和智能設(shè)備的普及,近距離無(wú)線通信(Near Field Communication,NFC)技術(shù)在門禁管理、信用卡、物流管理、非接觸式移動(dòng)支付、登機(jī)驗(yàn)證、智慧海報(bào)及廣告、設(shè)備間數(shù)據(jù)傳輸?shù)缺姸喾矫娴玫搅藦V泛應(yīng)用。與射頻識(shí)別(Radio Frequency IDentification,RFID)類似,NFC信息是通過頻譜中無(wú)線頻率部分的電磁感應(yīng)耦合方式進(jìn)行傳輸,但傳輸范圍要比RFID小,不超過1 m,實(shí)際應(yīng)用通常在10 cm之內(nèi),不需要電源,相比藍(lán)牙來(lái)說(shuō),具有成本低、耗電量低、較高保密性和安全性的特點(diǎn),是在近距離通信領(lǐng)域和場(chǎng)合下對(duì)藍(lán)牙技術(shù)的一種有益補(bǔ)充。
1? ? NFC通信簡(jiǎn)介
RFID是NFC無(wú)線通信的核心技術(shù),通過無(wú)線電信號(hào)識(shí)別特定目標(biāo)并讀寫相關(guān)數(shù)據(jù),而無(wú)須系統(tǒng)與特定目標(biāo)之間建立機(jī)械地或者光學(xué)接觸[1]。從概念上講,RFID類似于條碼掃描,條碼技術(shù)是將已編碼的條形碼附著于目標(biāo)物,并使用專用的掃描器讀寫器,利用光信號(hào)將信息由條形磁傳送到掃描讀寫器[2]。RFID使用專門的RFID讀寫器及專門的可附著于目標(biāo)物的RFID標(biāo)簽,利用頻率信號(hào)將信息由RFID標(biāo)簽傳送至RFID讀寫器。其基本工作原理是[3]:當(dāng)標(biāo)簽進(jìn)入磁場(chǎng)后,接收解讀器發(fā)出的射頻信號(hào),憑借感應(yīng)電流所獲得的能量發(fā)送存儲(chǔ)在芯片中的產(chǎn)品信息,即無(wú)源標(biāo)簽或被動(dòng)標(biāo)簽,Passive Tag,或者由標(biāo)簽主動(dòng)發(fā)送某一頻率的信號(hào),即有源標(biāo)簽或主動(dòng)標(biāo)簽,Active Tag,解讀器讀取信息并解碼后,送至中央信息系統(tǒng)進(jìn)行有關(guān)數(shù)據(jù)處理。
2? ? Android系統(tǒng)中對(duì)NFC的支持
一般來(lái)說(shuō),具有NFC功能的手機(jī),其NFC芯片是作為RFID模塊的一部分的裝在手機(jī)上的,如果沒有NFC硬件模塊,手機(jī)也不能支持基于NFC的應(yīng)用,至少Android 2.3版本以上才支持NFC開發(fā)?;贏ndroid平臺(tái)的NFC應(yīng)用開發(fā),主要使用android.nfc包中的類及方法,包括以下幾個(gè):
(1)NfcManager類和NfcAdapter類。NfcManager類是一個(gè)NFC Adapter的管理器類,通過該類的getDefaultAadpter(context)方法來(lái)獲取系統(tǒng)支持的NFC Adapter,也可使用NfcAdapter類的靜態(tài)方法getDefaultAadpter()來(lái)獲取,有了NFC Adapter后就可以進(jìn)行NFC相關(guān)后續(xù)操作,比如定義一個(gè)Intent來(lái)將系統(tǒng)檢測(cè)到的Tags消息發(fā)送到事先定義好的Activity,并執(zhí)行標(biāo)簽的讀寫操作。
(2)NdefMessage和NdefRecord類。NFC數(shù)據(jù)交換格式(NFC Data Exchange Format,NDEF)是NFC論壇定義的數(shù)據(jù)格式,用來(lái)將有效數(shù)據(jù)存儲(chǔ)到NFC Tags中,如文本、URL和其他MIME類型。一個(gè)NdefMessage就是一個(gè)集合,可以包含0個(gè)或多個(gè)NdefRecord,每一個(gè)NdefRecord有一個(gè)類型。在NdefMessage中第一個(gè)NdefRecord,主要是用來(lái)發(fā)送Tag到一個(gè)Android設(shè)備上的Activity,通過NdefMessage的方法getRecords可以查詢到NdefMessage的所有NdefRecord。
3? ? Android平臺(tái)下的NFC編程應(yīng)用
通常運(yùn)行NFC APP,在Android設(shè)備靠近或檢測(cè)到NFC Tag時(shí),會(huì)自動(dòng)運(yùn)行一個(gè)Activity或?qū)?yīng)的程序處理這個(gè)Tag并顯示處理結(jié)果,能夠簡(jiǎn)化用戶操作的過程,這是編寫NFC APP期望的結(jié)果。由于NFC通信通常在近距離才有效,如果操作過多就會(huì)有可能造成通信斷開。因而在設(shè)計(jì)APP時(shí),要避免用戶做過多選擇或操作,要讓程序自動(dòng)選擇匹配合適、快捷的方式,在編程實(shí)現(xiàn)時(shí),需精確設(shè)計(jì)程序的啟動(dòng)條件和匹配參數(shù)。
3.1? AndroidManifest文件關(guān)鍵設(shè)置
不管以何種方式啟動(dòng)Activity,Android NFC標(biāo)簽調(diào)度系統(tǒng)(Tag Dispatch System,TDS)都會(huì)根據(jù)NFC Tag進(jìn)行相關(guān)后續(xù)的動(dòng)作,在Android NFC APP編程實(shí)現(xiàn)時(shí),做好以下準(zhǔn)備。
首先,在AndroidManifest中添加NFC使用權(quán)限“android.permission.NFC”及設(shè)置SDK的級(jí)別限制
其次,在Activity對(duì)應(yīng)的Intent過濾器中實(shí)現(xiàn)NFC標(biāo)簽過濾。在AndroidManifest文件中設(shè)置NFC標(biāo)簽過濾,就是要匹配啟動(dòng)Activity的Intent中所包含的動(dòng)作類型,有3種類型標(biāo)簽:
(1)Android.nfc.action.NDEF_DISCOVERED標(biāo)簽,對(duì)應(yīng)Intent意圖中的動(dòng)作NfcAdapter.ACTION_NDEF_DISCOVERED,含義是當(dāng)一個(gè)標(biāo)簽包含標(biāo)準(zhǔn)的NDEF數(shù)據(jù)并被正確識(shí)別時(shí),被用來(lái)啟動(dòng)設(shè)定當(dāng)前標(biāo)簽的Activity,且優(yōu)先于其他Activity啟動(dòng)。如果在匹配Activity的同時(shí)過濾數(shù)據(jù),需添加MIME或data過濾。
(2)Android.nfc.action.TECH_DISCOVERED標(biāo)簽,對(duì)應(yīng)Intent意圖中的動(dòng)作NfcAdapter.ACTION_TECH_DISCOVERED,如無(wú)Activity注冊(cè)處理ACTION_NDEF_DISCOVERED意圖,標(biāo)簽調(diào)度系統(tǒng)就會(huì)嘗試啟動(dòng)該標(biāo)簽對(duì)應(yīng)的Activity或應(yīng)用。在設(shè)定此標(biāo)簽時(shí),需指明Activity支持的技術(shù)列表,用于對(duì)比是否為應(yīng)用支持的技術(shù),通常用一個(gè)XML資源文件進(jìn)行說(shuō)明。同時(shí)在AndroidManifest文件中,在
(3)Android.nfc.action.TAG_DISCOVERED標(biāo)簽,對(duì)應(yīng)Intent意圖中的動(dòng)作NfcAdapter.ACTION_TAG_DISCOVERED,在前兩種情況都不匹配的情況下使用。
3.2? 關(guān)鍵代碼實(shí)現(xiàn)
3.2.1? 讀取數(shù)據(jù)操作
首先,要獲取NFC設(shè)備適配器,只需一條語(yǔ)句:NfcAdapter nfcAdapter = NfcAdapter.getDefaultAdapter(this)。
通過判斷nfcAdapter是否為NULL來(lái)判斷設(shè)備是否支持NFC功能。如果手機(jī)不支持NFC,則提示后直接退出,如果沒有開啟則提示開啟NFC功能,這是要進(jìn)行NFC通信的第一步。
完成第一步判斷后,為掃描NFC設(shè)備獲取Tag數(shù)據(jù),通常要用一個(gè)PendingIntent對(duì)象來(lái)封裝NFC標(biāo)簽的詳細(xì)信息。
PendingIntent pendingIntent = PendingIntent.getActivity(this, 0, new Intent(this,getClass()).addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP), 0);
要做一個(gè)IntentFilter,過濾想要的action,如果android設(shè)備支持MIFARE,則要提供對(duì)MIFARE Classic目標(biāo)的屬性和I/O操作允許掃描的標(biāo)簽類型。
以上動(dòng)作在Activity的onCreate()方法中完成,設(shè)置NFC開始掃描的時(shí)間,可以在Activity的onResume()方法中調(diào)用以下方法:
void android.nfc.NfcAdapter.enableForegroundDispatch(Activity activity, PendingIntent intent, IntentFilter[] filters, String[][] techLists)
封裝好相關(guān)的參數(shù),就可以實(shí)現(xiàn)前臺(tái)推送Intent發(fā)起NFC掃描動(dòng)作,此intent還可以用于接收信息。要想解析掃描到的NFC標(biāo)簽的數(shù)據(jù),就需重載onNewIntent(Intent intent)方法,在此方法中對(duì)intent包含的信息進(jìn)行處理,示例如下:
@Override
protected void onNewIntent(Intent intent) {
super.onNewIntent(intent);
if (NfcAdapter.ACTION_TECH_DISCOVERED.equals(intent.getAction())) {
String result = processIntent(intent);//調(diào)用處理方法
resultText.setText(result);//將處理結(jié)果顯示在文本控件上
}
}
這種方法對(duì)在包中將啟動(dòng)模式設(shè)置為“singleTop”的Activity,或是在調(diào)用startactivity時(shí)使用了Intent.FLAG_ACTIVITY_SINGLE_TOP標(biāo)志的Activity會(huì)重新啟動(dòng),而不是新創(chuàng)一個(gè)Activity實(shí)例。
對(duì)掃描到的NFC標(biāo)簽數(shù)據(jù)的處理方法processIntent(Intent intent)是一個(gè)自定義方法,主要是對(duì)Intent包含數(shù)據(jù)進(jìn)行處理,典型處理方式如下:
private String processIntent(Intent intent) {
Parcelable[] rmsgs = intent.getParcelableArrayExtra(NfcAdapter.EXTRA_NDEF_MESSAGES);
NdefMessage msg = (NdefMessage) rmsgs[0];
NdefRecord[] records = msg.getRecords();//獲取NDEF中record數(shù)組
String resultStr = new String(records[0].getPayload());//返回可變長(zhǎng)度的有效負(fù)載
return resultStr;
}
此外,還可用setNdefPushMessageCallback()方法實(shí)現(xiàn)信息接收。
3.2.2? 寫入數(shù)據(jù)操作
要在一個(gè)Activity中實(shí)現(xiàn)向NFC對(duì)象寫入數(shù)據(jù),其部分步驟是與讀出數(shù)據(jù)類似的。先聲明定義PendingIntent對(duì)象、IntentFilter對(duì)象、技術(shù)列表對(duì)象等參數(shù),使其與讀數(shù)據(jù)的操作一致,再在onResume()中使用enableForegroundDispatch()進(jìn)行分發(fā)Tag Intent。不同的是,需在onNewIntent()方法中將普通信息封裝為NdefMessage信息進(jìn)行寫入,以下是封裝方法部分示例代碼:
// 根據(jù)文本生成一個(gè)NdefRecord,然后再封裝為一個(gè)NdefMessage
private NdefMessage getNoteAsNdef() {
…
byte[] textBytes = text.getBytes();
NdefRecord textRecord = new NdefRecord(NdefRecord.TNF_MIME_MEDIA,
“image/jpeg”.getBytes(), new byte[] {}, textBytes);
return new NdefMessage(new NdefRecord[] { textRecord });
}
除此方法外,還可在實(shí)現(xiàn)CreateNdefMessageCallback回調(diào)時(shí)重載createNdefMessage()方法,實(shí)現(xiàn)對(duì)普通信息的NdefMessage格式的封裝。不管是哪種方法,最核心的是要生成NdefMessage消息,然后調(diào)用enableForegroundDispatch()將信息寫入NFC Tag中。
4? ? 結(jié)語(yǔ)
NFC通信是Android手機(jī)一種重要的無(wú)線通信技術(shù),在生活中有著非常突出的應(yīng)用,使用快捷、簡(jiǎn)單,工作原理并不復(fù)雜,但其在Android平臺(tái)的編程應(yīng)用對(duì)很多Android開發(fā)者來(lái)說(shuō)并不是一件簡(jiǎn)單的事情。本文特就NFC編程技術(shù)實(shí)現(xiàn)進(jìn)行了深入分析、研究,著重論述了關(guān)鍵參數(shù)的設(shè)置和關(guān)鍵方法的使用,為順利開發(fā)出更多NFC APP做技術(shù)準(zhǔn)備。
[參考文獻(xiàn)]
[1]馬躍坤.用于動(dòng)態(tài)車輛識(shí)別的高速遠(yuǎn)距離RFID讀寫設(shè)備研究與實(shí)現(xiàn)[D].杭州:浙江工業(yè)大學(xué),2010.
[2]葉淑鳳.試論RFID在圖書館應(yīng)用的可行性[J].科技情報(bào)開發(fā)與經(jīng)濟(jì),2005(4):18-19.
[3]王子陸.基于物聯(lián)網(wǎng)SoC的AGC研究與設(shè)計(jì)[D].北京:北京交通大學(xué),2012.
Research and application of NFC programming technology based on Android
Chen Sanqing
(School of Mathematics and Computer, Panzhihua University, Panzhihua 617000, China)
Abstract:In recent years, NFC has been widely used in many fields such as mobile devices, consumer electronics products, etc. Its basic principle is essentially RFID technology, while Android is the most widely used mobile smart device, on Android platform. Classes and methods supporting NFC application development; In the development of NFC application under Android platform, this paper mainly describes the development settings of NFC application in Android Manifest file, the filtering of NFC tags, the key reading and writing operations of NFC data.
Key words:near field communication; Tag tag; Android; near field communication programming