Android 2.3.3 近場通信NFC介紹
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è)置一個(gè)你程序要處理的 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)用來保證這點(diǎn))。你也要覆蓋 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 寫東西時(shí),你必須以字節(jié)格式來寫。 Android 提供 API 來幫助寫符合 NDEF 標(biāo)準(zhǔn)的信息。使用此標(biāo)準(zhǔn)能保證你的數(shù)據(jù)在往 tag 寫時(shí)能被所有 Android NFC 設(shè)備支持。然而,很多 tag 使用他們自己的標(biāo)準(zhǔn)來存儲數(shù)據(jù),這些標(biāo)準(zhǔn)也被 Android 支持。但你必須自己實(shí)現(xiàn)協(xié)議棧來讀寫這些 tag 。你可以在 android.nfc.tech 里找到所有支持的 technologies ,并且可以在 TagTechnology 接口里對technology 有個(gè)了解。這一段是簡單介紹在 android 系統(tǒng)里怎樣使用 NDEF 消息。這不意味著是一個(gè)完整的 NDEF 功能的介紹。但標(biāo)出了主要需要注意和使用的東西。
為了方便使用 NDEF 消息, android 提供 NdefRecord和 NdefMessage來包裝原始字節(jié)數(shù)據(jù)為 NDEF 消息。一個(gè)NdefMessage 是保存 0 個(gè)或多個(gè) NdefRecords 的容器。每個(gè) NdefRecord 有自己的唯一類型名字格式,記錄類型和 ID 來與其他記錄區(qū)分開。你可以存儲不同類型的記錄,不同的長度到同一個(gè) NdefMessage 。 NFC tag 容量的限制決定你的NdefMessage 的大小。
那些支持 Ndef 和 NdefFormatable 技術(shù)的 tag 可以返回和接受 NdefMessage 對象為參數(shù)來進(jìn)行讀寫操作。你需要創(chuàng)建你自己的邏輯來為其他在 android.nfc.tech 的 tag 技術(shù)實(shí)現(xiàn)讀寫字節(jié)的操作。
你可以從 NFC Forum(http://www.nfc-forum.org/specs/) 下載 NDEF 消息標(biāo)準(zhǔn)的技術(shù)文檔,比如純文本和智慧型海報(bào) . NFCDemo 例子里聲明了純文本和智慧型海報(bào)的 NDef 消息。
讀一個(gè) NFC tag
當(dāng)一個(gè) NFC tag 靠近一個(gè) NFC 設(shè)備,一個(gè)相應(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 消息,比如純文本和智慧型海報(bào)。
寫 NFC tag
往 NFC tag 寫東西涉及到構(gòu)造一個(gè) NDEF 消息和使用與 tag 匹配的 Tag 技術(shù)。下面的代碼展示怎樣寫一個(gè)簡單的文本到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
}
點(diǎn)對點(diǎn)的數(shù)據(jù)交換
前臺推送技術(shù)支持簡單點(diǎn)對點(diǎn)的數(shù)據(jù)交換,你可以用 enableForegroundNdefPush(Activity, NdefMessage)方法來打開此功能 . 為了用這個(gè)功能:
· 推送數(shù)據(jù)的 Activity 必須是前臺 Activity 。
· 你必須將你要發(fā)送的數(shù)據(jù)封裝到 NdefMessage 對象里。
· 接收推送數(shù)據(jù)的設(shè)備必須支持 com.android.npp NDEF 推送協(xié)議,這個(gè)對于 Android 設(shè)備是可選的
假如你的 Activity 打開了前臺推送功能并且位于前臺,這時(shí)標(biāo)準(zhǔn)的 Intent 發(fā)布系統(tǒng)是禁止的。然而,如果你的Activity 允許前臺發(fā)布系統(tǒng),那么此時(shí)檢測 tag 的功能仍然是可用的,不過只適用于前臺發(fā)布系統(tǒng)。
要打開前臺推送 :
1. 創(chuàng)建一個(gè)你要推送給其他 NFC 設(shè)備的包含 NdefRecords 的 NdefMessage 。
2. 在你的 Activity 里實(shí)現(xiàn) onResume()和 onPause()的回調(diào)來正確處理前臺推送的生命周期。你必須在你的Activity 位于前臺并在主線程里調(diào)用 enableForegroundNdefPush(Activity, NdefMessage)(可以在onResume() 里調(diào)用來保證這點(diǎn)) .
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 位于前臺,你可以靠近另外一個(gè) NFC 設(shè)備來推送數(shù)據(jù)。請參考例子 ForegroundNdefPush 來了解點(diǎn)對點(diǎn)數(shù)據(jù)交換。
p2p機(jī)相關(guān)文章:p2p原理
評論