當(dāng)前位置:首頁 > 嵌入式 > 嵌入式軟件
[導(dǎo)讀]Android 2.3.3 近場通信NFC介紹

NFC( 近場通信 )

NFC 是一套短距離的無線通信,通常距離是 4 厘米或更短。 NFC 工作頻率是 13.56M Hz, 傳輸速率是 106kbit/s 到848kbit/s. NFC 總是在一個發(fā)起者和一個被動目標(biāo)之間發(fā)生。發(fā)起者發(fā)出近場無線電波,這個近場可以給被動目標(biāo)供電。這些被動的目標(biāo)包括不需要電源的標(biāo)簽,卡,也可以是有電源的設(shè)備。

與其他無線通信技術(shù)比較, 例如藍(lán)牙和 WiFi , NFC 提供更低貸款和距離,并且低成本,不需要供電,不需要實現(xiàn)匹配,整個通信過程僅僅是短短的靠近一秒就能完成。

一個帶有 NFC 支持的 android 設(shè)備通常是一個發(fā)起者。也可以作為 NFC 的讀寫設(shè)備。他將檢測 NFC tags 并且打開一個Activity 來處理 . Android 2.3.3 還有支持有限的 P2P 。

Tags 分很多種,其中簡單的只提供讀寫段,有的只能讀。復(fù)雜的 tags 可以支持一些運算,加密來控制對 tags 里數(shù)據(jù)段的讀寫。甚至一些 tags 上有簡單的操作系統(tǒng),允許一些復(fù)雜的交互和可以執(zhí)行一些代碼。

API 概覽

Android.nfc package 包含頂層類用來與本地 NFC 適配器交互 . 這些類可以表示被檢測到的 tags 和用 NDEF 數(shù)據(jù)格式。

android.nfc.techpackage 包含那些對 tag 查詢屬性和進(jìn)行 I/O 操作的類。這些類分別標(biāo)示一個 tag 支持的不同的NFC 技術(shù)標(biāo)準(zhǔn)。

聲明 Android Manifest.xml 的元素

在你能訪問一個設(shè)備的 NFC 硬件和正確的處理 NFC 的 Intent 之前,需要在 AndroidManifest.xml 中先聲明下面的項:

1. NFC 使用 元素來訪問 NFC 硬件 :

2. 最小 SDK 版本需要設(shè)置正確, API level 9 只包含有限的 tag 支持 , 包括:

. 通過 ACTION_TAG_DISCOVERED來發(fā)布 Tag 信息

. 只有通過 EXTRA_NDEF_MESSAGES擴(kuò)展來訪問 NDEF 消息

. 其他的 tag 屬性和 I/O 操作都不支持

所以你可能想要用 API level 10 來實現(xiàn)對 tag 的廣泛的讀寫支持。

3. uses-feature 元素定義:你的程序可以再 android 市場里顯示有 NFC 硬件。

4. NFC intent filter 告訴 android 系統(tǒng)你的 activity 能處理 NFC 數(shù)據(jù),可以定義 1 個或多個 intent filter :

android:resource = "@xml/nfc_tech_filter .xml" />

上邊 3 個 intent filters 有優(yōu)先級,更多信息可以看下面的 Tag 發(fā)布系統(tǒng)

也可以看 NFCDemo 例子的 AndroidManifest.xml 來有個更深的理解。

Tag 發(fā)布系統(tǒng)

當(dāng) android 設(shè)備掃描到一個 NFC tag ,通用的行為是自動找最合適的 Activity 會處理這個 tag Intent 而不需要用戶來選擇哪個 Activity 來處理。因為設(shè)備掃描 NFC tags 是在很短的范圍和時間,如果讓用戶選擇的話,那就有可能需要移動設(shè)備,這樣將會打斷這個掃描過程。你應(yīng)該開發(fā)你只處理需要處理的 tags 的 Activity ,以防止讓用戶選擇使用哪個 Activity來處理的情況。 Android 提供兩個系統(tǒng)來幫助你正確的識別一個 NFC tag 是否是你的 Activity 想要處理的: Intent 發(fā)布系統(tǒng)和前臺 Activity 發(fā)布系統(tǒng)。

Intent 發(fā)布系統(tǒng)檢查所有 Activities 的 intent filters ,找出那些定義了可以處理此 tag 的 Activity ,如果有多個 Activity 都配置了處理同一個 tag Intent ,那么將使用 Activity 選擇器來讓用戶選擇使用哪個 Activity 。用戶選擇之后,將使用選擇的 Activity 來處理此 Intent .

前臺發(fā)布系統(tǒng)允許一個 Activity 覆蓋掉 Intent 發(fā)布系統(tǒng)而首先處理此 tag Intent ,這要求你將要處理 Tag Intent 的 Activity運行在前臺,這樣當(dāng)一個 NFC tag 被掃描到,系統(tǒng)先檢測前臺的 Activity 是否支持處理此 Intent ,如果支持,即將此Intent 傳給此 Activity ,如果不支持,則轉(zhuǎn)到 Intent 發(fā)布系統(tǒng)。

使用 Intent 發(fā)布系統(tǒng)

Intent 發(fā)布系統(tǒng)指定了 3 個 intent 有不同的優(yōu)先級。通常當(dāng)一個 tag 被檢測到之后, Intent 就被啟動( start )了,這個啟動遵循以下行為 :

· android.nfc.action.NDEF_DISCOVERED : 這個 intent 是在一個包含 NDEF 負(fù)載的 tag 被檢測到時啟動,這是最高優(yōu)先級的 intent, android 系統(tǒng)不會讓你指定一個 Intent 能處理所有的 NFC 數(shù)據(jù)類型,你必須在AndroidManifest.xml 中指定與 NFC tag 對應(yīng)的 元素,這樣當(dāng)掃描到的 tag 傳過來的數(shù)據(jù)類型與你定義的相匹配時,你的 Activity 就會被調(diào)用。例如想處理一個包含 plain text 的 NDEF_DISCOVERED intent ,你要按照如下定義AndroidManifest.xml file:

如果 NDEF_DISCOVERED intent 已經(jīng)被啟動, TECH_DISCOVERED 和 TAG_DISCOVERED intents 將不會被啟動。假如一個未知的 tag 或者不包含 NDEF 負(fù)載的 tag 被檢測到,此 Intent 就不會被啟動。

· android.nfc.action.TECH_DISCOVERED : 如果 NDEF_DISCOVERED intent 沒啟動或者沒有一個 Activity 的filter 檢測 NDEF_DISCOVERED ,并且此 tag 是已知的,那么此 TECH_DISCOVERED Intent 將會啟動 .TECH_DISCOVERED intent 要求你在一個資源文件里 (xml) 里指定你要支持 technologies 列表。更多細(xì)節(jié)請看下面的Specifying tag technologies to handle .

· android.nfc.action.TAG_DISCOVERED : 如果沒有一個 activity 處理 _DISCOVERED and TECH_DISCOVEREDintents 或者 tag 被檢測為未知的,那么此 Intent 將會被啟動。

Specifying tag technologies to handle 指定處理的 technologies

假如你的 Activity 在 AndroidManifest.xml 文件里聲明了處理 android.nfc.action.TECH_DISCOVERED intent,你必須創(chuàng)建一個 Xml 格式的資源文件,并加上你的 activity 支持的 technologies 到 tech-list 集合里。這樣你的 activity將被認(rèn)作能處理這些 tech-list 的處理者,如果 tag 使用的 technology 屬于你的定義的 list 里,你的 Activity 將接收此Intent 。你可以用 getTechList() 來獲得 tag 支持的 technologies 。

例如:如果一個 tag 被檢測到支持 MifareClassic, NdefFormatable, 和 NfcA ,你的 tech-list 集合必須指定了其中的一項或者多項來保證你的 Activity 能處理此 Intent 。

下面是一個資源文件例子,定義了所有的 technologies. 你可以根據(jù)需要刪掉不需要的項,將此文件以任意名字 +.xml 保存到 /res/xml 文件夾 .

asis:names:tc:xliff:document:1.2" >

android.nfc.tech.IsoDep

android.nfc.tech.NfcA

android.nfc.tech.NfcB

android.nfc.tech.NfcF

android.nfc.tech.NfcV

android.nfc.tech.Ndef

android.nfc.tech.NdefFormatable

android.nfc.tech.MifareClassic

android.nfc.tech.MifareUltralight

你也可以指定多個 tech-list 集合,每個集合都認(rèn)做獨立的。如果任何單個 tech-list 集合是 getTechList() 返回的technologies 集合的子集,那么你的 Activity 將被認(rèn)為匹配了。這個還提供 ’ 與 ’ 和 ’ 或 ’ 操作。下面的例子表示支持NfcA 和 NDef 的卡,或者支持 NfcB 和 NDef 的卡:

asis:names:tc:xliff:document:1.2" >

android.nfc.tech.NfcA

android.nfc.tech.Ndef

asis:names:tc:xliff:document:1.2" >

android.nfc.tech.NfcB

android.nfc.tech.Ndef

在 AndroidManifest.xml 文件中 , 指定這個 tech-list 資源文件的方法是在 元素中創(chuàng)建 元素,例如下面例子 :

...

android:resource = "@xml/nfc_tech_filter" />

...

使用前臺發(fā)布系統(tǒng) Using the foreground dispatch system

前臺發(fā)布系統(tǒng)允許一個 Activity 攔截一個 tag Intent 獲得最高優(yōu)先級的處理,這種方式很容易使用和實現(xiàn):

1. 添加下列代碼到 Activity 的 onCreate() 方法里

a. 創(chuàng)建一個 PendingIntent對象 , 這樣 Android 系統(tǒng)就能在一個 tag 被檢測到時定位到這個對象

PendingIntent pendingIntent = PendingIntent . getActivity (

this , 0 , new Intent ( this , getClass ()). addFlags ( Intent .FLAG_ACTIVITY_SINGLE_TOP ), 0 );

b. 在 Intent filters 里聲明你想要處理的 Intent ,一個 tag 被檢測到時先檢查前臺發(fā)布系統(tǒng),如果前臺 Activity 符合Intent filter 的要求,那么前臺的 Activity 的將處理此 Intent 。如果不符合,前臺發(fā)布系統(tǒng)將 Intent 轉(zhuǎn)到 Intent 發(fā)布系統(tǒng)。如果指定了 null 的 Intent filters ,當(dāng)任意 tag 被檢測到時,你將收到 TAG_DISCOVERED intent 。因此請注意你應(yīng)該只處理你想要的 Intent 。

[!--empirenews.page--]

IntentFilter ndef = new IntentFilter ( NfcAdapter . ACTION_NDEF_DISCOVERED);

try {

ndef . addDataType ( "*/*" ); /* Handles all MIME based dispatches.

You should specify only the ones that you need. */

}

catch ( MalformedMimeTypeException e ) {

throw new RuntimeException ( "fail" , e );

}

intentFiltersArray = new IntentFilter [] {

ndef ,

};

c. 設(shè)置一個你程序要處理的 Tag technologies 的列表,調(diào)用 Object.class.getName() 方法來獲得你想要支持處理的 technology 類。

techListsArray = new String [][] { new String [] { NfcF . class . getName () } };

2. 覆蓋下面的方法來打開或關(guān)閉前臺發(fā)布系統(tǒng)。比如 onPause() 和 onResume ()方法。必須在主線程里調(diào)用[url=http://developer.android.com/reference/android/nfc/NfcAdapter.html#enableForegroundDispatch%28android.app.Activity,%20android.app.PendingIntent,%20android.content.IntentFilter[],%20java.lang.String[][]%29]enableForegroundDispatch(Activity, PendingIntent, IntentFilter[], String[][])[/url]而且Activity 在前臺(可以在 onResume() 里調(diào)用來保證這點)。你也要覆蓋 onNewIntent 回調(diào)來處理得到的 NFC tag 數(shù)據(jù)。

public void onPause () {

super . onPause ();

mAdapter . disableForegroundDispatch ( this );

}

public void onResume () {

super . onResume ();

mAdapter . enableForegroundDispatch ( this , pendingIntent , intentFiltersArray, techListsArray );

}

public void onNewIntent ( Intent intent ) {

Tag tagFromIntent = intent . getParcelableExtra ( NfcAdapter . EXTRA_TAG );

//do something with tagFromIntent

}

See the ForegroundDispatch sample from API Demos for the complete sample.

使用 NFC tag 上的數(shù)據(jù)

NFC tag 上的數(shù)據(jù)是以字節(jié)存放,所以你可以將其轉(zhuǎn)換成其他你想要的格式。當(dāng)往 tag 寫東西時,你必須以字節(jié)格式來寫。 Android 提供 API 來幫助寫符合 NDEF 標(biāo)準(zhǔn)的信息。使用此標(biāo)準(zhǔn)能保證你的數(shù)據(jù)在往 tag 寫時能被所有 Android NFC 設(shè)備支持。然而,很多 tag 使用他們自己的標(biāo)準(zhǔn)來存儲數(shù)據(jù),這些標(biāo)準(zhǔn)也被 Android 支持。但你必須自己實現(xiàn)協(xié)議棧來讀寫這些 tag 。你可以在 android.nfc.tech 里找到所有支持的 technologies ,并且可以在 TagTechnology 接口里對technology 有個了解。這一段是簡單介紹在 android 系統(tǒng)里怎樣使用 NDEF 消息。這不意味著是一個完整的 NDEF 功能的介紹。但標(biāo)出了主要需要注意和使用的東西。

為了方便使用 NDEF 消息, android 提供 NdefRecord和 NdefMessage來包裝原始字節(jié)數(shù)據(jù)為 NDEF 消息。一個NdefMessage 是保存 0 個或多個 NdefRecords 的容器。每個 NdefRecord 有自己的唯一類型名字格式,記錄類型和 ID 來與其他記錄區(qū)分開。你可以存儲不同類型的記錄,不同的長度到同一個 NdefMessage 。 NFC tag 容量的限制決定你的NdefMessage 的大小。

那些支持 Ndef 和 NdefFormatable 技術(shù)的 tag 可以返回和接受 NdefMessage 對象為參數(shù)來進(jìn)行讀寫操作。你需要創(chuàng)建你自己的邏輯來為其他在 android.nfc.tech 的 tag 技術(shù)實現(xiàn)讀寫字節(jié)的操作。

你可以從 NFC Forum(http://www.nfc-forum.org/specs/) 下載 NDEF 消息標(biāo)準(zhǔn)的技術(shù)文檔,比如純文本和智慧型海報 . NFCDemo 例子里聲明了純文本和智慧型海報的 NDef 消息。

讀一個 NFC tag

當(dāng)一個 NFC tag 靠近一個 NFC 設(shè)備,一個相應(yīng)的 Intent 將在設(shè)備上被創(chuàng)建。然后通知合適的程序來處理此 Intent 。

下面的方法處理 TAG_DISCOVERED intent 并且使用迭代器來獲得包含在 NDEF tag 負(fù)載的數(shù)據(jù)

NdefMessage [] getNdefMessages ( Intent intent ) {

// Parse the intent

NdefMessage [] msgs = null ;

String action = intent . getAction ();

if ( NfcAdapter . ACTION_TAG_DISCOVERED . equals ( action )) {

arcelable [] rawMsgs = intent . getParcelableArrayExtra ( NfcAdapter .EXTRA_NDEF_MESSAGES );

if ( rawMsgs != null ) {

msgs = new NdefMessage [ rawMsgs . length ];

for ( int i = 0 ; i < rawMsgs . length ; i ++) {

msgs [ i ] = ( NdefMessage ) rawMsgs [ i ];

}

}

else {

// Unknown tag type

byte [] empty = new byte [] {};

NdefRecord record = new NdefRecord ( NdefRecord . TNF_UNKNOWN , empty , empty, empty );

NdefMessage msg = new NdefMessage ( new NdefRecord [] { record });

msgs = new NdefMessage [] { msg };

}

}

else {

Log . e ( TAG , "Unknown intent " + intent );

finish ();

}

return msgs ;

}

請記住 NFC 設(shè)備讀到的數(shù)據(jù)是 byte 類型,所以你可能需要將他轉(zhuǎn)成其他格式來呈現(xiàn)給用戶。 NFCDemo 例子展示了怎樣用 com.example.android.nfc.record 中的類來解析 NDEF 消息,比如純文本和智慧型海報。

寫 NFC tag

往 NFC tag 寫東西涉及到構(gòu)造一個 NDEF 消息和使用與 tag 匹配的 Tag 技術(shù)。下面的代碼展示怎樣寫一個簡單的文本到NdefFormatable tag :

NdefFormatable tag = NdefFormatable . get ( t );

Locale locale = Locale . US ;

final byte [] langBytes = locale . getLanguage (). getBytes ( Charsets . US_ASCII );

String text = "Tag, you‘re it!" ;

final byte [] textBytes = text . getBytes ( Charsets . UTF_8 );

final int utfBit = 0 ;

final char status = ( char ) ( utfBit + langBytes . length );

final byte [] data = Bytes . concat ( new byte [] {( byte ) status }, langBytes , textBytes);

NdefRecord record = NdefRecord ( NdefRecord . TNF_WELL_KNOWN , NdefRecord . RTD_TEXT , newbyte [ 0 ], data );

try {

NdefRecord [] records = { text };

NdefMessage message = new NdefMessage ( records );

tag . connect ();

tag . format ( message );

}

catch ( Exception e ){

//do error handling

}

點對點的數(shù)據(jù)交換

前臺推送技術(shù)支持簡單點對點的數(shù)據(jù)交換,你可以用 enableForegroundNdefPush(Activity, NdefMessage)方法來打開此功能 . 為了用這個功能:

· 推送數(shù)據(jù)的 Activity 必須是前臺 Activity 。

· 你必須將你要發(fā)送的數(shù)據(jù)封裝到 NdefMessage 對象里。

· 接收推送數(shù)據(jù)的設(shè)備必須支持 com.android.npp NDEF 推送協(xié)議,這個對于 Android 設(shè)備是可選的

假如你的 Activity 打開了前臺推送功能并且位于前臺,這時標(biāo)準(zhǔn)的 Intent 發(fā)布系統(tǒng)是禁止的。然而,如果你的Activity 允許前臺發(fā)布系統(tǒng),那么此時檢測 tag 的功能仍然是可用的,不過只適用于前臺發(fā)布系統(tǒng)。

要打開前臺推送 :

1. 創(chuàng)建一個你要推送給其他 NFC 設(shè)備的包含 NdefRecords 的 NdefMessage 。

2. 在你的 Activity 里實現(xiàn) onResume()和 onPause()的回調(diào)來正確處理前臺推送的生命周期。你必須在你的Activity 位于前臺并在主線程里調(diào)用 enableForegroundNdefPush(Activity, NdefMessage)(可以在onResume() 里調(diào)用來保證這點) .

public void onResume () {

super . onResume ();

if ( mAdapter != null )

mAdapter . enableForegroundNdefPush ( this , myNdefMessage );

}

public void onPause () {

super . onPause ();

if ( mAdapter != null )

mAdapter . disableForegroundNdefPush ( this );

}

當(dāng) Activity 位于前臺,你可以靠近另外一個 NFC 設(shè)備來推送數(shù)據(jù)。請參考例子 ForegroundNdefPush 來了解點對點數(shù)據(jù)交換。

本站聲明: 本文章由作者或相關(guān)機(jī)構(gòu)授權(quán)發(fā)布,目的在于傳遞更多信息,并不代表本站贊同其觀點,本站亦不保證或承諾內(nèi)容真實性等。需要轉(zhuǎn)載請聯(lián)系該專欄作者,如若文章內(nèi)容侵犯您的權(quán)益,請及時聯(lián)系本站刪除。
換一批
延伸閱讀

9月2日消息,不造車的華為或?qū)⒋呱龈蟮莫毥谦F公司,隨著阿維塔和賽力斯的入局,華為引望愈發(fā)顯得引人矚目。

關(guān)鍵字: 阿維塔 塞力斯 華為

加利福尼亞州圣克拉拉縣2024年8月30日 /美通社/ -- 數(shù)字化轉(zhuǎn)型技術(shù)解決方案公司Trianz今天宣布,該公司與Amazon Web Services (AWS)簽訂了...

關(guān)鍵字: AWS AN BSP 數(shù)字化

倫敦2024年8月29日 /美通社/ -- 英國汽車技術(shù)公司SODA.Auto推出其旗艦產(chǎn)品SODA V,這是全球首款涵蓋汽車工程師從創(chuàng)意到認(rèn)證的所有需求的工具,可用于創(chuàng)建軟件定義汽車。 SODA V工具的開發(fā)耗時1.5...

關(guān)鍵字: 汽車 人工智能 智能驅(qū)動 BSP

北京2024年8月28日 /美通社/ -- 越來越多用戶希望企業(yè)業(yè)務(wù)能7×24不間斷運行,同時企業(yè)卻面臨越來越多業(yè)務(wù)中斷的風(fēng)險,如企業(yè)系統(tǒng)復(fù)雜性的增加,頻繁的功能更新和發(fā)布等。如何確保業(yè)務(wù)連續(xù)性,提升韌性,成...

關(guān)鍵字: 亞馬遜 解密 控制平面 BSP

8月30日消息,據(jù)媒體報道,騰訊和網(wǎng)易近期正在縮減他們對日本游戲市場的投資。

關(guān)鍵字: 騰訊 編碼器 CPU

8月28日消息,今天上午,2024中國國際大數(shù)據(jù)產(chǎn)業(yè)博覽會開幕式在貴陽舉行,華為董事、質(zhì)量流程IT總裁陶景文發(fā)表了演講。

關(guān)鍵字: 華為 12nm EDA 半導(dǎo)體

8月28日消息,在2024中國國際大數(shù)據(jù)產(chǎn)業(yè)博覽會上,華為常務(wù)董事、華為云CEO張平安發(fā)表演講稱,數(shù)字世界的話語權(quán)最終是由生態(tài)的繁榮決定的。

關(guān)鍵字: 華為 12nm 手機(jī) 衛(wèi)星通信

要點: 有效應(yīng)對環(huán)境變化,經(jīng)營業(yè)績穩(wěn)中有升 落實提質(zhì)增效舉措,毛利潤率延續(xù)升勢 戰(zhàn)略布局成效顯著,戰(zhàn)新業(yè)務(wù)引領(lǐng)增長 以科技創(chuàng)新為引領(lǐng),提升企業(yè)核心競爭力 堅持高質(zhì)量發(fā)展策略,塑強(qiáng)核心競爭優(yōu)勢...

關(guān)鍵字: 通信 BSP 電信運營商 數(shù)字經(jīng)濟(jì)

北京2024年8月27日 /美通社/ -- 8月21日,由中央廣播電視總臺與中國電影電視技術(shù)學(xué)會聯(lián)合牽頭組建的NVI技術(shù)創(chuàng)新聯(lián)盟在BIRTV2024超高清全產(chǎn)業(yè)鏈發(fā)展研討會上宣布正式成立。 活動現(xiàn)場 NVI技術(shù)創(chuàng)新聯(lián)...

關(guān)鍵字: VI 傳輸協(xié)議 音頻 BSP

北京2024年8月27日 /美通社/ -- 在8月23日舉辦的2024年長三角生態(tài)綠色一體化發(fā)展示范區(qū)聯(lián)合招商會上,軟通動力信息技術(shù)(集團(tuán))股份有限公司(以下簡稱"軟通動力")與長三角投資(上海)有限...

關(guān)鍵字: BSP 信息技術(shù)
關(guān)閉
關(guān)閉