前言:
? ? ? ? 說(shuō)道NFC,是Near Field Communication縮寫(xiě),就是近距離無(wú)線通訊技術(shù)肘迎。NFC采用主動(dòng)和被動(dòng)兩種通信模式,工作的模式有三種甥温,讀寫(xiě)標(biāo)簽,點(diǎn)對(duì)點(diǎn)妓布,仿真卡模式姻蚓,今天我們只是簡(jiǎn)單的介紹一下讀寫(xiě)標(biāo)簽(因?yàn)槲乙呀?jīng)廢了一張公交卡了。匣沼。狰挡。。 大家在學(xué)習(xí)的時(shí)候可以去某寶買幾張NFC標(biāo)簽貼紙。加叁。)倦沧,好了下面開(kāi)始開(kāi)始介紹。
1.Android中處理NFC重要的兩個(gè)包 android.nfc 和 android.nfc.tech它匕。
2.Android SDK API支持下面3種NDEF數(shù)據(jù)的操作:
(1)從NFC標(biāo)簽讀取NDEF格式的數(shù)據(jù)展融。
(2)向NFC標(biāo)簽寫(xiě)入NDEF格式的數(shù)據(jù)。
(3)通過(guò)Android Beam技術(shù)將NDEF數(shù)據(jù)發(fā)送到另一部NFC設(shè)備豫柬。
android.nfc下面用到的類也是我們需要使用的:
(1)NdefMessage:描述NDEF格式的信息告希,實(shí)際上我們寫(xiě)入NFC標(biāo)簽的就是NdefMessage對(duì)象,所以我們可以理解為數(shù)據(jù)對(duì)象這樣就簡(jiǎn)單多了烧给。
(2)NdefRecord:描述NDEF信息的一個(gè)信息段燕偶,一個(gè)NdefMessage可能包含一個(gè)或者多個(gè)NdefRecord,也就是對(duì)象中的一個(gè)個(gè)屬性础嫡。
(3)Tag:表示一個(gè)被動(dòng)的NFC的目標(biāo)指么,tag對(duì)象將被創(chuàng)建并且封裝到一個(gè)Intent里,然后NFC 發(fā)布系統(tǒng)將這個(gè)Intent用startActivity發(fā)送到注冊(cè)了接受這種Intent的activity里驰吓。簡(jiǎn)單來(lái)說(shuō)就是比如現(xiàn)在使用的公交卡涧尿,電梯卡,就是這個(gè)Tag檬贰,里面封裝了一個(gè)tag對(duì)象姑廉,當(dāng)注冊(cè)了
(4)NfcAdapter : 表示本地設(shè)備的NFC adapter,可以定義Intent來(lái)請(qǐng)求將系統(tǒng)檢測(cè)到tags的提醒發(fā)送到你的Activity.并提供方法去注冊(cè)前臺(tái)tag提醒發(fā)布和前臺(tái)NDEF推送。
(5)NfcManager:NFC adapter的管理器翁涤,列出所有本地Android設(shè)備支持所有的NFC adapter.
但是大部分Android 設(shè)備只有一個(gè)NFC adapter桥言。
對(duì)了在這里說(shuō)下Android api版本的區(qū)別
1.API level 9以前不支持NFC,當(dāng)然現(xiàn)在市面上的系統(tǒng)基本上都是4.0以上葵礼,低版本的就暫時(shí)不考慮了号阿。
2.在API level 10實(shí)現(xiàn)對(duì)tag的廣泛的讀寫(xiě)支持。
? ? ?好了現(xiàn)在開(kāi)始上代碼以及解釋鸳粉。首先我們我們字啊Android studio開(kāi)始一個(gè)工程扔涧,在AndroidManifest清單文件里面設(shè)置項(xiàng)目權(quán)限nfc,要求當(dāng)前設(shè)備必須要有NFC芯片届谈,沒(méi)有就GG了
? ? ?定義一個(gè)基礎(chǔ)的接收nfc tag的activity枯夜,類似我們?cè)陧?xiàng)目中的基礎(chǔ)baseActivity,通常來(lái)說(shuō)為了讓我們的設(shè)備在靠近nfc標(biāo)簽的時(shí)候艰山,能夠讓我們的界面Activity調(diào)用起來(lái)湖雹,所以清單需要配置一下activity的 launchMode屬性為singletop,子類需要在onCreate方法中做Activity初始化,子類需要在onNewIntent方法中進(jìn)行NFC標(biāo)簽相關(guān)操作曙搬。當(dāng)launchMode設(shè)置為singleTop時(shí)摔吏,第一次運(yùn)行調(diào)用onCreate方法鸽嫂,第二次運(yùn)行將不會(huì)創(chuàng)建新的Activity實(shí)例,將調(diào)用onNewIntent方法所以我們獲取intent傳遞過(guò)來(lái)的tag數(shù)據(jù)操作放在onNewIntent方法中執(zhí)行征讲,如果在棧中已經(jīng)有該Activity的實(shí)例据某,就重用該實(shí)例(會(huì)調(diào)用實(shí)例的onNewIntent())。下面是baseActivity稳诚,在界面onStart的時(shí)候獲取支持的nfcadapter哗脖,同時(shí)截獲NFC消息瀑踢,通過(guò)PendingIntent調(diào)用窗口扳还。界面onResume和onPause的時(shí)候讓設(shè)備處理當(dāng)前NFC數(shù)據(jù)優(yōu)先于其他的NFC處理。
? ? ? 現(xiàn)在我們已經(jīng)有了基礎(chǔ)的NfcBLBaseActivity,現(xiàn)在我們做一個(gè)簡(jiǎn)單的入門(mén)橱夭,我們把nfc標(biāo)簽貼近Android設(shè)備寫(xiě)入一個(gè)數(shù)據(jù)到nfc標(biāo)簽氨距,寫(xiě)入成功后把nfc標(biāo)簽移開(kāi)Android設(shè)備,然后再把demo退出到后臺(tái)棘劣,再把nfc標(biāo)簽貼近Android設(shè)備俏让,這個(gè)時(shí)候Android設(shè)備跳轉(zhuǎn)到系統(tǒng)的短信界面去。就是這樣的一個(gè)操作場(chǎng)景〔缦荆現(xiàn)在寫(xiě)一個(gè)界面繼承NfcBLBaseActivity在onNewIntent中首昔,界面打開(kāi)的時(shí)候會(huì)去結(jié)束nfc標(biāo)簽的數(shù)據(jù) 獲取tag對(duì)象,往設(shè)備里面寫(xiě)入我們的標(biāo)簽信息以便第二次打開(kāi)的時(shí)候獲取tag糙俗。
? ? 寫(xiě)書(shū)標(biāo)簽數(shù)據(jù)的代碼如下勒奇,獲取標(biāo)簽中獲取到的標(biāo)簽tag對(duì)象,new一個(gè)NdefMessage把我們提前定義的字符串穿進(jìn)去巧骚,看一下源碼赊颠,我們傳進(jìn)去的是系統(tǒng)短信的包名com.android.mms
? ? ? 然后獲取NdefMessage對(duì)象字節(jié)長(zhǎng)度,通過(guò)Ndef.get(Ndef 對(duì)tag查詢屬性和進(jìn)行I/O操作的類。Ndef是NFC-F (JIS 6319-4)技術(shù)標(biāo)準(zhǔn) )劈彪。判斷ndef是否為NDEF格式的標(biāo)簽竣蹦,是的話調(diào)用連接,判斷是否支持可寫(xiě)沧奴,再判斷標(biāo)簽的容量和現(xiàn)在的寫(xiě)入的數(shù)據(jù)長(zhǎng)度比較痘括,都符合的情況下開(kāi)始writeNdefMessage寫(xiě)入數(shù)據(jù)。不是NDEF格式的話滔吠,還有就是我們剛買來(lái)的的NFC的標(biāo)簽貼紙是沒(méi)有分區(qū)或者格式化纲菌,這個(gè)時(shí)候我們就需要格式化一下NdefFormatable.get(tag),判斷是否獲得了NdefFormatable格式化對(duì)象屠凶,有一些標(biāo)簽是只讀的或者不允許格式化的驰后。然后再格式化寫(xiě)入數(shù)據(jù)。好了矗愧,到此為止我們就已經(jīng)完成了nfc數(shù)據(jù)的寫(xiě)入灶芝,讀取的時(shí)候就是在onNewIntent里面獲取tag標(biāo)簽數(shù)據(jù)郑原。在設(shè)備里面有這個(gè)標(biāo)簽對(duì)象的時(shí)候,nfc標(biāo)簽再貼近設(shè)備的時(shí)候就會(huì)執(zhí)行我們想要的操作夜涕,跳轉(zhuǎn)到系統(tǒng)的短信界面犯犁,下面是數(shù)據(jù)寫(xiě)入的代碼。
public voidwriteNFCTag(Tag tag) {
if(tag ==null) {
return;
}
NdefMessage ndefMessage =newNdefMessage(newNdefRecord[]{NdefRecord
.createApplicationRecord(mNfctagName)});
//轉(zhuǎn)換成字節(jié)獲得大小
intsize = ndefMessage.toByteArray().length;
try{
//判斷NFC標(biāo)簽的數(shù)據(jù)類型(通過(guò)Ndef.get方法)
Ndef ndef = Ndef.get(tag);
//判斷是否為NDEF標(biāo)簽
if(ndef !=null) {
ndef.connect();
//判斷是否支持可寫(xiě)
if(!ndef.isWritable()) {
return;
}
//判斷標(biāo)簽的容量是否夠用
if(ndef.getMaxSize() < size) {
return;
}
//3.寫(xiě)入數(shù)據(jù)
ndef.writeNdefMessage(ndefMessage);
Toast.makeText(this,"寫(xiě)入數(shù)據(jù)成功",Toast.LENGTH_SHORT).show();
}else{//當(dāng)我們買回來(lái)的NFC標(biāo)簽是沒(méi)有格式化的女器,或者沒(méi)有分區(qū)的執(zhí)行此步
//Ndef格式類
NdefFormatable format = NdefFormatable.get(tag);
//判斷是否獲得了NdefFormatable對(duì)象酸役,有一些標(biāo)簽是只讀的或者不允許格式化的
if(format !=null) {
//連接
format.connect();
//格式化并將信息寫(xiě)入標(biāo)簽
format.format(ndefMessage);
Toast.makeText(this,"寫(xiě)入數(shù)據(jù)成功",Toast.LENGTH_SHORT).show();
}else{
Toast.makeText(this,"寫(xiě)入數(shù)據(jù)失敗",Toast.LENGTH_SHORT).show();
}
}
}catch(Exception e) {
}
}
? ? ? ?截圖就不上傳了,因?yàn)橹皇菍?xiě)了一下入門(mén)的小demo驾胆,分享下自己所得涣澡,感謝大家的閱讀,語(yǔ)言組織不合適的地方還請(qǐng)包涵,謝謝丧诺。