《Android NFC开发实战详解》——6.2节Android NFC P2P开发基础-阿里云开发者社区

开发者社区> 异步社区> 正文

《Android NFC开发实战详解》——6.2节Android NFC P2P开发基础

简介:
+关注继续查看

本节书摘来自异步社区《Android NFC开发实战详解》一书中的第6章,第6.2节Android NFC P2P开发基础,作者 赵波,更多章节内容可以访问云栖社区“异步社区”公众号查看

6.2 Android NFC P2P开发基础
Android NFC开发实战详解
本节主要介绍Android NFC P2P开发中的一些基础知识,为后续的实例开发提供基础。通过本章的学习,使读者熟悉Android中Beam实现的几种方式,Beam NDEF消息和接收Beam消息的方法,同时也会对第4章中提到的Intent过滤机制在P2P中的使用进行阐述。

6.2.1 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添加如下代码:

<meta-data android:name="android.nfc.disable_beam_default"
    android:value="true" />


(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+以上的系统中进行。

6.2.2 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。

6.2.3 接收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操作。

6.2.4 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游戏开发详解》一2.8 对象的基础知识
我们已经应用了第1章中介绍过的概念来编写和运行一些非常简单的Java程序。接下来,我们将把注意力转向对象,它使得我们能够编写更加复杂和强大的程序。
1187 0
《企业级ios应用开发实战》一2.4 搭建iOS开发环境
本节书摘来自华章出版社《企业级ios应用开发实战》一 书中的第2章,第2.4节,作者:杨宏焱,更多章节内容可以访问云栖社区“华章计算机”公众号查看。
1709 0
《React Native移动开发实战》一一1.6 小 结
本节书摘来自华章出版社《React Native移动开发实战》一 书中的第1章,第1.6节,作者:袁林 著 ,更多章节内容可以访问云栖社区“华章计算机”公众号查看。
789 0
JAVA开发实战经典(持续更新)
 http://www.verycd.com/topics/2783340/
441 0
+关注
异步社区
异步社区(www.epubit.com)是人民邮电出版社旗下IT专业图书旗舰社区,也是国内领先的IT专业图书社区,致力于优质学习内容的出版和分享,实现了纸书电子书的同步上架,于2015年8月上线运营。公众号【异步图书】,每日赠送异步新书。
11939
文章
0
问答
文章排行榜
最热
最新
相关电子书
更多
文娱运维技术
立即下载
《SaaS模式云原生数据仓库应用场景实践》
立即下载
《看见新力量:二》电子书
立即下载