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è)置一個你程序要處理的 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)換成其他你想要的格式。當往 tag 寫東西時,你必須以字節(jié)格式來寫。 Android 提供 API 來幫助寫符合 NDEF 標準的信息。使用此標準能保證你的數(shù)據(jù)在往 tag 寫時能被所有 Android NFC 設(shè)備支持。然而,很多 tag 使用他們自己的標準來存儲數(shù)據(jù),這些標準也被 Android 支持。但你必須自己實現(xiàn)協(xié)議棧來讀寫這些 tag 。你可以在 android.nfc.tech 里找到所有支持的 technologies ,并且可以在 TagTechnology 接口里對technology 有個了解。這一段是簡單介紹在 android 系統(tǒng)里怎樣使用 NDEF 消息。這不意味著是一個完整的 NDEF 功能的介紹。但標出了主要需要注意和使用的東西。
為了方便使用 NDEF 消息, android 提供 NdefRecord和 NdefMessage來包裝原始字節(jié)數(shù)據(jù)為 NDEF 消息。一個NdefMessage 是保存 0 個或多個 NdefRecords 的容器。每個 NdefRecord 有自己的唯一類型名字格式,記錄類型和 ID 來與其他記錄區(qū)分開。你可以存儲不同類型的記錄,不同的長度到同一個 NdefMessage 。 NFC tag 容量的限制決定你的NdefMessage 的大小。
那些支持 Ndef 和 NdefFormatable 技術(shù)的 tag 可以返回和接受 NdefMessage 對象為參數(shù)來進行讀寫操作。你需要創(chuàng)建你自己的邏輯來為其他在 android.nfc.tech 的 tag 技術(shù)實現(xiàn)讀寫字節(jié)的操作。
你可以從 NFC Forum(http://www.nfc-forum.org/specs/) 下載 NDEF 消息標準的技術(shù)文檔,比如純文本和智慧型海報 . NFCDemo 例子里聲明了純文本和智慧型海報的 NDef 消息。
讀一個 NFC tag
當一個 NFC tag 靠近一個 NFC 設(shè)備,一個相應的 Intent 將在設(shè)備上被創(chuàng)建。然后通知合適的程序來處理此 Intent 。
下面的方法處理 TAG_DISCOVERED intent 并且使用迭代器來獲得包含在 NDEF tag 負載的數(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 打開了前臺推送功能并且位于前臺,這時標準的 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 );
}
當 Activity 位于前臺,你可以靠近另外一個 NFC 設(shè)備來推送數(shù)據(jù)。請參考例子 ForegroundNdefPush 來了解點對點數(shù)據(jù)交換。
p2p機相關(guān)文章:p2p原理
評論