android NFC学习笔记 (一)

一:NFC的tag分发系统
如果想让android设备感应到NFC标签,你要保证两点
1:屏幕没有锁住
2:NFC功能已经在设置中打开

当系统检测到一个NFC标签的时候,他会自动去寻找最合适的activity去处理这个intent.
他所发出的这个Intent将会有三种action:

ACTION_NDEF_DISCOVERED:当系统检测到tag中含有NDEF格式的数据时,且系统中有activity声明可以接受包含NDEF数据的Intent的时候,系统会优先发出这个action的intent。

ACTION_TECH_DISCOVERED:当没有任何一个activity声明自己可以响应ACTION_NDEF_DISCOVERED时,系统会尝试发出TECH的intent.即便你的tag中所包含的数据是NDEF的,但是如果这个数据的MIME type或URI不能和任何一个activity所声明的想吻合,系统也一样会尝试发出tech格式的intent,而不是NDEF.

ACTION_TAG_DISCOVERED:当系统发现前两个intent在系统中无人会接受的时候,就只好发这个默认的TAG类型的

二:NFC相关androidManifest文件设置
首先是权限:<uses-permission android:name="android.permission.NFC" />
然后是sdk级别限制:建议API10开始比较合适:<uses-sdk android:minSdkVersion="10"/>
接着是特殊功能限制<uses-feature android:name="android.hardware.nfc" android:required="true" />
声明使用者必须拥有nfc功能。

三:NFC标签过滤
在activity的intent过滤xml声明中,你可以同时声明过滤这三种action.但是由之前所说,你应该知道系统在发送intent的时候是有优先级的,所以你最好清楚自己最想处理哪个。
1:过滤ACTION_TAG_DISCOVERED:
<intent-filter>
<action android:name="android.nfc.action.TAG_DISCOVERED"/>
<category android:name="android.intent.category.DEFAULT"/>
</intent-filter>
这个最简单,也是最后一个被尝试接受intent的选项。

2:过滤ACTION_NDEF_DISCOVERED:
<intent-filter>
<action android:name="android.nfc.action.NDEF_DISCOVERED"/>
<category android:name="android.intent.category.DEFAULT"/>
<data android:mimeType="text/plain" />
</intent-filter>

其中最重要的应该算是data的mimeType类型了,这个定义的越准确,intent指向你这个activity的成功率就越高,否则系统可能不会发出你想要的NDEF intent了。下面在讲如何使用NDEF写入NFC标签的时候会多举几个类型的例子。

3:过滤ACTION_TECH_DISCOVERED:
你首先需要在你的<project-path>/res/xml下面创建一个过滤规则文件。名字任取,比如可以叫做nfc_tech_filter.xml。这个里面定义的是nfc实现的各种标准,每一个nfc卡都会符合多个不同的标准,个人理解为这些标准有些相互之间也是兼容的。你可以在检测到nfc标签后使用getTechList()方法来查看你所检测的tag到底支持哪些nfc标准。
一个nfc_tech_filter.xml中可以定义多个<tech-list>结构组。每一组代表我声明我只接受同时满足这些标准的nfc标签。比如A组表示,只有同时满足IsoDep,NfcA,NfcB,NfcF这四个标准的nfc标签的intent才能进入。A与B组之间的关系就是只要满足其中一个就可以了。换句话说,你的nfc标签技术,满足A的声明也可以,满足B的声明也可以。

<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<tech-list> --------------------------------A组
<tech>android.nfc.tech.IsoDep</tech> <tech>android.nfc.tech.NfcA</tech>
<tech>android.nfc.tech.NfcB</tech> <tech>android.nfc.tech.NfcF</tech>
</tech-list>

<tech-list>-----------------------------------------B组
  <tech>android.nfc.tech.NfcV</tech> <tech>android.nfc.tech.Ndef</tech>
  <tech>android.nfc.tech.NdefFormatable</tech> 
  <tech>android.nfc.tech.MifareClassic</tech> 
  <tech>android.nfc.tech.MifareUltralight</tech>
</tech-list>

</resources>

在androidManifest文件中声明xml过滤的举例如下
<activity>
<intent-filter>
<action android:name="android.nfc.action.TECH_DISCOVERED"/>
</intent-filter>
<meta-data android:name="android.nfc.action.TECH_DISCOVERED"
android:resource="@xml/nfc_tech_filter" />这个就是你的资源文件名
</activity>

4:nfc标签前台分发系统
之所以把他也归类在nfc的过滤里面,主要是因为他跟解析nfc标签到不是那么的紧密,他解决的是接受哪些nfc标准的标签问题。所以更接近nfc的过滤。

什么叫nfc的前台发布系统?就是说当我们已经打开我们的应用的时候,那么通过这个前台发布系统的设置,我们可以让我们已经启动的activity拥有更高的优先级来依据我们在代码中定义的标准来过滤和处理intent,而不是让别的声明了intent filter的activity来干扰,甚至连自己声明在androidManifest中的intent filter都不会来干扰。也就是说foreground Dispatch的优先级大于intent filter。

第一种情况:当你的activity没有启动的时候,去扫描tag,那么系统中所有的intent filter都将一起参与过滤。
第二种情况:当你的actiity启动了,去扫描tag时,那么将直接使用你在foreground dispatch中代码写入的过滤标准。如果这个标准没有命中任何intent,那么系统将使用所有activity声明的intent filter xml来过滤。

在OnCreate中你可以添加如下代码
mPendingIntent = PendingIntent.getActivity(this, 0,
new Intent(this, getClass()).addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP), 0);

    // 做一个IntentFilter过滤你想要的action 这里过滤的是ndef
    IntentFilter ndef = new IntentFilter(NfcAdapter.ACTION_NDEF_DISCOVERED);

//如果你对action的定义有更高的要求,比如data的要求,你可以使用如下的代码来定义intentFilter
// try {
// ndef.addDataType("/");
// } catch (MalformedMimeTypeException e) {
// // TODO Auto-generated catch block
// e.printStackTrace();
// }
//生成intentFilter
mFilters = new IntentFilter[] {
ndef,
};

    // 做一个tech-list。可以看到是二维数据,每一个一维数组之间的关系是或,但是一个一维数组之内的各个项就是与的关系了
    mTechLists = new String[][] { 
            new String[] { NfcF.class.getName()},
            new String[]{NfcA.class.getName()},
            new String[]{NfcB.class.getName()},
            new String[]{NfcV.class.getName()}
           };

在onPause和 onResume中需要加入相应的代码。
public void onPause() {
super.onPause();
//反注册 mAdapter.disableForegroundDispatch(this);
}

public void onResume() {
super.onResume();
//设定intentfilter和tech-list。如果两个都为null就代表优先接收任何形式的TAG action。也就是说系统会主动发TAG intent。
mAdapter.enableForegroundDispatch(this, mPendingIntent, mFilters, mTechLists);

}

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 204,921评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 87,635评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 151,393评论 0 338
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,836评论 1 277
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,833评论 5 368
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,685评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,043评论 3 399
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,694评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 42,671评论 1 300
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,670评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,779评论 1 332
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,424评论 4 321
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,027评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,984评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,214评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,108评论 2 351
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,517评论 2 343

推荐阅读更多精彩内容