Android NFC P2P開發基礎(android nfc開發教程)
一、 Android Beam實現的幾種方式
在Android中,目前,Beam功能實現的方式可以概括為三種,分別為setNdefPushmessage callback( )、setNdefPushMessage( )以及enableForegroundNdefPush( )。
上述方法中,enableForegroundNdefPush( )是在API 10中加入的提供Android NFC P2P功能方法。從嚴格意義上,該方法并不能稱為Beam方法,API 14中加入的前面兩個方法才算真正的Beam功能。因為Beam的概念是在API 14中提出的,其操作過程中需要用戶的介入(用戶點擊從而選擇Beam的發送端),所以,此處為了描述方便(且Beam功能的本質也即P2P),故將其與Beam功能放一處,讀者只需搞清其中的原因即可。
1.enableForegroundNdefPush( )方法的原型
void enableForegroundNdefPush(activity activity, NdefMessage message):在指定的activity中,enable前臺通過P2P Push NDEF消息功能。
其中,activity為前臺activity;message為將要Push的NDEF消息。當調用該方法的該activity不再前臺時,將會拋出異常。
使用enableForegroundNdefPush()方法時,應注意以下幾點:
(1)在activity中,必須確保每次Resume時,調用該方法,同時每次Paused時調用disable ForegroundNdefPush方法;
(2)Android官方強烈推薦使用setNdefPushMessage方法(API 14 )代替該方法,因為setNdefPushMessage方法將自動根據Android的生命周期來使能,無需開發者自己enable和disable;
(3)activity在調用該方法時,必須是在主線程中;
(4)使用該方法需要在AndroidManifest.xml中添加NFC權限;
(5)使用該方法需要在Android API 10 以上的系統中進行。
2.disableForegroundNdefPush ( )方法的原型
void disableForegroundNdefPush(Activity activity):在指定的activity中,disable 通過P2P Push NDEF消息的功能。
其中,activity為前臺activity。如果當調用該方法的該activity已經停止了(paused),那么將會拋出異常信息。
使用disableForegroundNdefPush()方法時,應注意以下幾點:
(1)activity在調用該方法時,必須在onPause( )之前;
(2)activity在調用該方法時,必須是在主線程中;
(3)Android官方強烈推薦使用setNdefPushMessage方法(API 14 )代替該方法,因為setNdefPushMessage方法將自動根據Android的生命周期來使能,無需開發者自己enable和disable;
(4)使用該方法需要在AndroidManifest.xml中添加NFC權限;
(5)使用該方法需要在Android API 10 以上的系統中進行。
setNdefPushMessageCallback( )和setNdefPushMessage( )是API 14 中加入的實現Beam功能的方法。setNdefPushMessage( )中把接收到的NdefMessage對象作為一個消息設置給Beam,當兩個設備足夠近的時候,就會自動的發送消息;setNdefPushMessageCallback()方法中將接收包含createNdefMessage()方法的回調,當設備在發射數據的范圍內時,這個回調方法會被調用,回調會讓你只在需要的時候創建NDEF消息。
3.setNdefPushMessage ( )方法的原型
public void setNdefPushMessage (NdefMessage message, Activity activity, Activity… activities):通過Android Beam發送靜態NDEF消息句。
其中,message為待發送的靜態NDEF消息。為NULL時,當前activity的setNdefPushMessage功能將會disable;activity為當前push消息的activity;activities為附加activity。強烈建議在每個activity中,該方法只注冊一次。
使用setNdefPushMessage()方法時注意以下幾點:
(1)activity在調用該方法時,可以在onDestroy( )之前的任何地方,官方建議在onCreate()中調用;
(2)該方法并不阻塞線程,所以可以在UI主線程中使用;
(3)使用該方法時,如果message為null,則調用該方法的Activity的setNdefPushMessage功能將會disable;
(4)當同時使用該方法和setNdefPushMessageCallback( )方法時,setNdefPushMessage Callback方法具有較高優先級;
(5)如6.1.2節所述,在兩個Android NFC設備靠近時,如果發送設備上(BNM)當前打開的應用程序并沒有實現Android Beam功能,那么系統也會自動發送一條默認的NDEF消息給接收端(RBM);如果要想阻止Android系統發送默認的NDEF消息,那么可以在AndroidManifest.xml中的application添加如下代碼:
<application ...> <meta-data android:name="android.nfc.disable_beam_default" android:value="true" /> </application>
(6)關于該方法的使用,官方提供的使用范例如下(關于更詳細的使用方法,讀者可以參考本節后面的具體實例):
protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); NfcAdapter nfcAdapter = NfcAdapter.getDefaultAdapter(this); if (nfcAdapter == null) return; // NFC not available on this device nfcAdapter.setNdefPushMessage(ndefMessage, this); }
(7)使用該方法需要在AndroidManifest.xml中添加NFC權限;
(8)使用該方法需要在Android API 10 以上的系統中進行。
4.setNdefPushMessageCallback ( ) 方法的原型
public void setNdefPushMessageCallback (NfcAdapter.CreateNdefMessageCallback callback, Activity activity, Activity… activities):其中,callback為回調接口;activity為待Push NDEF消息的activity;activities為附加activity選項。強烈建議在每個activity中,該方法只注冊一次。
使用setNdefPushMessageCallback()方法時,應注意以下幾點:
(1)activity在調用該方法時,可以在onDestroy( )之前的任何地方,官方建議在onCreate()中調用;
(2)該方法并不阻塞線程,所以可以在UI主線程中使用;
(3)使用該方法時,如果callback為null,則該Activity的NDEF Push功能將會disable;
(4)當同時使用該方法和 setNdefPushMessage( )方法時,該方法具有較高優先級;
(5)如6.1.2節所述,在兩個Android NFC設備靠近時,如果發送設備上(BNM)當前打開的應用程序并沒有實現Android Beam功能,那么系統也會自動發送一條默認的NDEF消息給接收端(RBM),如果要想阻止Android系統發送默認的NDEF消息,那么可以在AndroidManifest.xml中的application添加如下代碼:
<application ...> <meta-data android:name="android.nfc.disable_beam_default" android:value="true" /> </application>
(6)關于該方法的使用,官方提供的使用范例如下(關于更詳細的使用方法,讀者可以參考本節后面的具體實例):
protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); NfcAdapter nfcAdapter = NfcAdapter.getDefaultAdapter(this); if (nfcAdapter == null) return; // NFC not available on this device nfcAdapter.setNdefPushMessageCallback(callback, this); }
(7)使用該方法需要在AndroidManifest.xml中添加NFC權限;
(8)使用該方法需要在Android API 10 以上的系統中進行。
二、 Beam NDEF消息(BNM)
兩個NFC設備之間通過Beam實現數據傳遞時,數據發送端即Beam NDEF消息端,本書中簡寫為BNM(Beam NDEF Message)。在BNM時,首先需要準備NDEF記錄和消息。創建NDEF記錄和消息的方法和第5章中相同,讀者可參考第5章的相關內容。
Android中提供了兩種BNM的方法(enableForegroundNdefPush()除外),分別為setNdefPush MessageCallback( )和setNdefPushMessage( ),下面分別對這兩種方法BNM的實現步驟進行闡述,具體實例參考本章6.3中的相關內容。
1.BNM By setNdefPushMessageCallback( )的使用步驟
(1)在Activity中實現CreateNdefMessageCallback接口;
(2)在需要的地方調用setNdefPushMessageCallback( )方法;
(3)在回調函數(createNdefMessage(NfcEvent))中實現Beam Data。
其中,在第2步中,setNdefPushMessageCallback( )中NDEF消息的生成是動態的,開發中可以在其Activity中的任何地方實現調用(筆者建議首選onCreate( ))。當有BNM發現有目標設備(RBM)時,系統會自動激活createNdefMessage(NfcEvent)回調接口函數,此時,該回調接口函數中返回的NDEF消息被發送給RBM,開發者需要做的就是在回調接口中準備Beam Data即可。
2.BNM By setNdefPushMessage ( )的使用步驟
(1)創建NDEF消息;
(2)在需要的地方調用setNdefPushMessage( )方法。
其中,在第2步中,setNdefPushMessage( )中NDEF消息的生成是靜態的,即由用戶選擇生成然后作為參數進行傳遞。
3.setNdefPushMessageCallback( )和setNdefPushMessage( )的選擇
當應用程序Activity需要在任何時候都推送相同的NDEF消息時,可使用setNdefPushMessage( )方法;當應用程序Activity希望根據用戶不同的操作行為來進行推送時,可使用setNdefPush MessageCallback( )方法。當Activity中兩者都使用時,由于setNdefPushMessageCallback( )的優先級要高于setNdefPushMessage ( ),因此系統會首選setNdefPushMessageCallback( )方法。
注意,在上述兩種方法中,若NDEF消息為NULL,此時,NDEF Push功能在該Activity中將被Disable。
三、 接收Beam消息(RBM)
兩個NFC設備之間通過Beam實現數據傳遞時,數據接收端即接收Beam消息端,本書中簡寫為RBM(Receive Beam Message)。接收Beam消息的方法與第五章中接收Tag消息類似,實現步驟如下:
(1)在應用中實現onNewIntent( Intent)方法,該方法會調用setIntent(Intent),由第3章的Android生命周期描述中可知,在使用onNewIntent(Intent)方法后,onResume()方法會自動調用;
(2)在應用的onResume( )方法中,檢測當前消息是否來自Beam,如果是,獲取并處理該NDEF消息;
(3)調用自己定義的消息解析函數,將獲取的NDEF消息解析并獲取Payload,再對Payload進行進一步UI操作。
四、 enableForegroundNdefPush的使用
在API 14 的Android系統中,可以使用上述兩種方法實現Beam功能的開發。若系統在API 10~API 13之間,或者說希望在API 10~API 13之間的Android系統的用戶也同樣能夠使用該APP,此時需要考慮第3種方式:enableForegroundNdefPush( )方法。
關于enableForegroundNdefPush( )方法可參考6.2.1節中的描述,同時還可參閱第4章中介紹的NFC前臺調度系統的相關知識。本節為大家介紹通過enableForegroundNdefPush( )方法實現Beam功能的開發步驟,具體實例參見6.3節的內容。
通過enableForegroundNdefPush( )方法實現(發送端)Beam 功能開發步驟如下:
(1)創建需要Beam的NDEF數據;
(2)在Activity需要的地方中調用enableForegroundNdefPush (Activity activity, NdefMessage message)方法;在該方法中,message為步驟1中創建的NDEF消息,該方法創建后,message處于掛起狀態;一旦系統檢測到RBM設備,該message就會通過Beam傳輸給接收端;
(3)在應用程序的onPause( )方法中,需要調用disableForegroundNdefPush(Activity)方法;由于這是一種前臺推送方法,因此,一旦Activity不出于前臺,Foreground NDEF Push就要立即停止;
(4)在應用程序的onResume( )方法中,可以通過調用enableForegroundNdefPush (Activity activity, NdefMessage message)再次啟用Foreground NDEF Push推送。
通過enableForegroundNdefPush( )方法實現(接收端)Beam 功能開發步驟如下:
(1)在應用中實現onNewIntent( Intent)方法,在該方法中調用setIntent(Intent);由第3章介紹的Android生命周期的描述中可知,在使用onNewIntent(Intent)方法后,onResume()方法會自動調用;
(2)在應用程序的onResume( )方法中,檢測當前消息是否來自Beam,如果是,獲取該NDEF消息;
(3)解析并處理接收到的NDEF數據。
上述接收端的實現方法其實還是NFC標簽調度系統實現的。與enableForegroundNdefPush( )對應的,如果需要徹底的使用前臺調度系統,那么可以使用enableForegroundDispatch()方法。關于該方法的描述如下。
1.enableForegroundDispatch ( )方法的原型
void enableForegroundDispatch(Activity activity, PendingIntent intent, IntentFilter[] filters, String[][] techLists):在指定的activity中enable前臺dispatch功能。
其中,activity為將要dispatch to的activity;intent為將啟動dispatch的PendingIntent;filters為過濾dispatch信息。activity為null時,表示一直處理所有信息。techLists用來匹配ACTIONTECH DISCOVERED意圖。
如果當調用該方法的該activity已經不再前臺了,就會拋出異常信息。
使用enableForegroundDispatch()方法時,應注意以下幾點:
(1)當使用該方法時,當前activity發現有Tag信息時,前臺Dispatch擁有最高優先級 ——即,第4章中所描述的當APP同時擁有NFC前臺調度系統和NFC標簽調度系統時,NFC前臺調度系統優先級高于NFC標簽調度系統;
(2)IntentFilter過濾dispatch信息,包括ACTIONNDEF_DISCOVERED和ACTION Tag_DISCOVERED兩種;
(3)當APP中的filters和techLists都為NULL時,當前activity將接收所有的Tag信息通過ACTION_NDEF_DISCOVERED意圖;
(4)activity在調用該方法時,必須是在主線程中,且必須是前臺activity——即,當activity即將處于后臺時(onPause或onDestroy),需要調用disableForegroundDispatch方法;
(5)使用該方法需要在AndroidManifest.xml中添加NFC權限;
(6)使用該方法需要在Android API 10 以上的系統中進行。
2.disableForegroundDispatch ( )方法的原型。
void disableForegroundDispatch(Activity activity):在指定的activity中disable前臺dispatch功能。
其中,activity為將要disable的activity。如果調用該方法的activity的ForegroundDispatch已經disable了,就會拋出異常信息。
使用disableForegroundDispatch()方法時,應注意以下幾點:
(1)activity在調用該方法時,必須在onPause( )之前;
(2)activity在調用該方法時,必須是在主線程中;
(3)使用該方法需要在AndroidManifest.xml中添加NFC權限;
(4)使用該方法需要在Android API 10 以上的系統中進行。
3.具體開發步驟
(1)在應用中實現onNewIntent( Intent)方法,并在該方法中調用setIntent(Intent)。由第3章所介紹的Android生命周期的描述中可知,在使用onNewIntent(Intent)方法后,onResume()方法會自動調用。
(2)在應用的onResume( )方法中,調用enableForegroundDispatch( ),使當前activity的前臺調度系統有效。
(3)在應用的onPause ( )方法中,調用disableForegroundDispatch ( ),使當前activity的前臺調度系統disable。
本文節選自圖書《Android NFC開發實戰詳解》。
本書中,將普及NFC相關基礎概念和知識,將剖析NFC NDEF協議,將介紹Android NFC應用開發,將闡述Android NFC體系架構,最后還會有具體實例呈現,可以說,縱然是第一本介紹NFC的書籍,卻把NFC相關知識(除硬件)都進行了闡述,做到了既新又全。