NFC基础
最近开发NFC功能,网上搜了好久都是一些没有什么用的文章,后来看了这篇文章,才觉得有所了解。一篇基础,一篇高级。对于NFC开发来说够用了。
原文地址:http://blog.csdn.net/zoeice/article/details/9714867
- 从一个NFC Tag读取NDEF数据
- 通过Android Beam™, 从一个设备到另一个设备发送NDEF消息
Tag发布系统
- 解析NFC Tag和计算出的MIME类型或一个用于在标签上确定数据有效载荷的URI。
- 封装的MIME类型,或者URI和有效载荷送入Intent。前两个步骤是对NFC标签如何被映射到MIME类型和URI的描述。
- 启动Activity的Intent。这是描述了如何发布应用NFC标签。
NdefMessage
)中的第一条NdefRecord,来判断如何解释整个NDEF消息(一个NDEF消息能够有多条NDEF记录)。在格式良好的NDEF消息中,第一条NdefRecord包含以下字段信息:
标签调度系统使用TNF和类型字段来尝试把MIME类型或URI映射到NDEF消息中。如果成功,它会把信息跟实际的负载一起封装到ACTION_NDEF_DISCOVERED类型的Intent中。但是,会有标签调度系统不能根据第一条NDEF记录来判断数据类型的情况,这样就会有NDEF数据不能被映射到MIME类型或URI,或者是NFC标签没有包含NDEF开始数据的情况发生。在这种情况下,就会用一个标签技术信息相关的Tag
对象和封装在ACTION_TECH_DISCOVERED类型Intent对象内部的负载来代替。
表 1.介绍标签调度系统映射如何把TNF和类型字段映射到MIME型或URI上。同时也介绍了那种类型的TNF不能被映射到MIME类型或URI上。这种情况下,标签调度系统会退化到ACTION_TECH_DISCOVERED类型的Intent对象。
TNF_ABSOLUTE_URI
类型的记录,它会把这个记录的可变长度类型字段映射到一个URI中。标签调度系统会把这个URI跟其他相关的标签的信息(如数据负载)一起封装到ACTION_NDEF_DISCOVERED的Intent对象中。在另一方面,如果遇到了TNF_UNKNOWN类型,它会创建一个封装了标签技术信息的Intent对象来代替。
表 1.所支持的TNF和它们的映射
TNF_ABSOLUTE_URI
|
基于类型字段的URI. |
TNF_EMPTY
|
回落到ACTION_TECH_DISCOVERED .
|
TNF_EXTERNAL_TYPE
|
URI基于类型字段中的URN.URN是缩短的格式(<domain_name>:<service_name> .)被编码到NDEF类型中Android会把这个URN映射成以下格式的vnd.android.nfc://ext/<domain_name>:<service_name>
|
TNF_MIME_MEDIA
|
基于类型字段的MIME类型 |
TNF_UNCHANGED
|
在第一条记录中是无效的, 因此回落到ACTION_TECH_DISCOVERED .
|
TNF_UNKNOWN
|
回落到ACTION_TECH_DISCOVERED .
|
TNF_WELL_KNOWN
|
依赖你在类型字段中设置的记录类型定义(RTD)的MIME类型或URI, 欲了解有效的RTDs和它们的映射更多信息,请参考表 2 |
表 2.TNF_WELL_KNOWN所支持的RTD和它们的映射
RTD_ALTERNATIVE_CARRIER
|
回落到ACTION_TECH_DISCOVERED .
|
RTD_HANDOVER_CARRIER
|
回落到ACTION_TECH_DISCOVERED .
|
RTD_HANDOVER_REQUEST
|
回落到ACTION_TECH_DISCOVERED .
|
RTD_HANDOVER_SELECT
|
回落到ACTION_TECH_DISCOVERED .
|
RTD_SMART_POSTER
|
基于负载解析的URI |
RTD_TEXT
|
text/plain 类型的MIME.
|
RTD_URI
|
基于负载的URI |
应用程序如何调度NFC Tags
当标签调度系统完成对NFC标签和它的标识信息封装的Intent对象的创建时,它会把该Intent对象发送给感兴趣的应用程序。如果有多个应用程序能够处理该Intent对象,就会显示Activity选择器,让用户选择Activity。标签调度系统定义了三种Intent对象,以下按照由高到低的优先级列出这三种Intent对象:
-
ACTION_NDEF_DISCOVERED
:这种Intent用于启动包含NDEF负载和已知类型的标签的Activity。这是最高优先级的Intent,并且标签调度系统在任何其他Intent之前,都会尽可能的尝试使用这种类型的Intent来启动Activity。 -
ACTION_TECH_DISCOVERED
:如果没有注册处理ACTION_NDEF_DISCOVERED类型的Intent的Activity,那么Tag调度系统会尝试使用这种类型的Intent来启动应用程序。如果被扫描到的标签包含了不能被映射到MIME类型或URI的NDEF数据,或者没有包含NDEF数据,但是是已知的标签技术,那么也会直接启动这种类型的Intent对象(而不是先启动ACTION_NDEF_DISCOVERED类型的Intent) -
ACTION_TAG_DISCOVERED
:如果没有处理ACTION_NDEF_DISCOVERED
或ACTION_TECH_DISCOVERED类型Intent的Activity,就会启动这种类型的Intent。
Tag调度系统的基本工作方法如下:
- 用解析NFC标签时由Tag调度系统创建的Intent对象(ACTION_NDEF_DISCOVERED或ACTION_TECH_DISCOVERED)来尝试启动Activity;
- 如果没有对应的处理Intent的Activity,那么就会尝试使用下一个优先级的Intent(ACTION_TECH_DISCOVERED或ACTION_TAG_DISCOVERED)来启动Activity,直到有对应的应用程序来处理这个Intent,或者是直到Tag调度系统尝试了所有可能的Intent。
- 如果没有应用程序来处理任何类型的Intent,那么就不做任何事情。
图 1.Tag调度系统
在 Android Manifest 中申请 NFC 访问
-
在
<uses-permission>
元素中声明访问NFC硬件:<uses-permission android:name="android.permission.NFC" />
-
你的应用程序所支持的最小的SDK版本。API Level 9只通过ACTION_TAG_DISCOVERED来支持有限的标签调度,并且只能通过
EXTRA_NDEF_MESSAGES
来访问NDEF消息。没有其他的标签属性或I/O操作可用。API Level 10中包含了广泛的读写支持,从而更好的推动了NDEF的应用前景,并且API Leve 14用Android Beam和额外的方便的创建NDEF记录的方法,向外提供了更容易的把NDEF消息推送给其他设备的方法。
<uses-sdk android:minSdkVersion="10"/>
-
使用
uses-feature
元素,在Google Play中,以便你的应用程序能够只针对有NFC硬件的设备来显示。<uses-feature android:name="android.hardware.nfc" android:required="true" />
如果你的应用程序使用了NFC功能,但是相关的功能又不是你的应用程序的关键功能,你可以忽略uses-feature元素,并且要在运行时通过调用getDefaultAdapter()方法来检查NFC是否有效。
过滤 NFC 的 Intents
要在你想要处理被扫描到的NFC标签时启动你的应用程序,可以在你的应用程序的Android清单中针对一种、两种或全部三种类型的NFC的Intent来过滤。但是,通常想要在应用程序启动时控制最常用的ACTION_NDEF_DISCOVERED类型的Intent。在没有过滤ACTION_NDEF_DISCOVERED类型的Intent的应用程序,或数据负载不是NDEF时,才会从ACTION_NDEF_DISCOVERED类型的Intent回退到ACTION_TECH_DISCOVERED类型的Intent。通常ACTION_TAG_DISCOVERED
是最一般化的过滤分类。很多应用程序都会在过滤ACTION_TAG_DISCOVERED
之前,过滤ACTION_NDEF_DISCOVERED或ACTION_TECH_DISCOVERED,这样就会降低你的应用程序被启动的可能性。ACTION_TAG_DISCOVERED
只是在没有应用程序处理ACTION_NDEF_DISCOVERED或ACTION_TECH_DISCOVERED类型的Intent的情况下,才使用的最后手段。
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>
<intent-filter>
<action android:name="android.nfc.action.NDEF_DISCOVERED"/>
<category android:name="android.intent.category.DEFAULT"/>
<data android:scheme="http"
android:host="developer.android.com"
android:pathPrefix="/index.html" />
</intent-filter>
ACTION_TECH_DISCOVERED
ACTION_TECH_DISCOVERED
类型的Intent,你必须创建一个XML资源文件,该文件在tech-list集合中指定你的Activity所支持的技术。如果tech-list集合是标签所支持的技术的一个子集,那么你的Activity被认为是匹配的。通过调用getTechList()方法来获得标签所支持的技术集合。
举例来说,如果被扫描到的Tag支持 MifareClassic, NdefFormatable, 和 NfcA, 你的tech-list
设置 为了匹配你的activity,你必须列举出这些技术(并没有其他的)的三个,两个,或者一个.
下面的例子定义了所有的技术. 你可以删除你不需要的. 保存这个文件 (你可以用你想要的任何名字命名它)到<project-root>/res/xml
文件夹.
<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<tech-list>
<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>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>
你也能够指定多个tech-list集合,每个tech-list集合被认为是独立的,并且如果任何一个tech-list集合是由getTechList()返回的技术的子集,那么你的Activity就被认为是匹配的。下列示例能够跟支持NfcA和Ndef技术NFC标签或者跟支持NfcB和Ndef技术的标签相匹配:
<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<tech-list>
<tech>android.nfc.tech.NfcA</tech>
<tech>android.nfc.tech.Ndef</tech>
</tech-list>
</resources>
<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<tech-list>
<tech>android.nfc.tech.NfcB</tech>
<tech>android.nfc.tech.Ndef</tech>
</tech-list>
</resources>
在你的AndroidManifest.xml
文件中,像下面的例子一样,在<activity>
元素中,在你指定的<meta-data>
元素中创建资源文件:
<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>
欲了解有关 tag 技术和ACTION_TECH_DISCOVERED
intent更详细的信息,
请参阅在高级NFC文档中的Working
with Supported Tag Technologies.
ACTION_TAG_DISCOVERED
为了过滤出ACTION_TAG_DISCOVERED,
用如下的
intent filter:
<intent-filter>
<action android:name="android.nfc.action.TAG_DISCOVERED"/>
</intent-filter>
从 intents 获取信息
如果由于 NFC intent 导致一个activity被启动, 你可以从intent 获取关于扫描到的NFC Tag的信息. Intents包含如下附加的信息,它依赖于被扫描到的Tag:
EXTRA_TAG
(必须的): 一个Tag
对象,表示被扫描到的tag.EXTRA_NDEF_MESSAGES
(可选的): 一个从tag解析到的NDEF信息数组. 这个付托在intents上.
{@link android.nfc.NfcAdapter#EXTRA_ID
(可选的): Tag的low-level ID.
要获取这些附加信息,就要确保你的Activity是被扫描到的NFC的Intent对象启动的,然后才能获得Intent之外的附加信息。下例检查ACTION_NDEF_DISCOVERED类型的Intent,并从Intent对象的附加信息中获取NDEF消息。
public void onResume() {
super.onResume();
...
if (NfcAdapter.ACTION_NDEF_DISCOVERED.equals(getIntent().getAction())) {
Parcelable[] 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];
}
}
}
//process the msgs array
}
此外,你还能够从Intent对象中获得一个Tag对象,该对象包含了数据负载,并允许你列举标签的技术:
Tag tag = intent.getParcelableExtra(NfcAdapter.EXTRA_TAG);
创建 NDEF 记录的一般类型
本节介绍如何创建通用的NDEF记录类型,以便帮助你向NFC标签写入或用Android Beam发送数据。从Android4.0(API Level14)开始,可以用createUri()方法来帮助你自动的创建URI记录。从Android4.1(API Level 16)开始,可以用createExternal()和createMime()方法来帮助你创建MIME和外部类型的NDEF记录。使用这些辅助方法会尽可能的避免手动创建NDEF记录的错误。
本章也描述了如何为对应的记录创建intent filter. 所有的 NDEF记录的例子应该在那些你写进Tag或者Beaming的NDEF消息的第一条NDEF记录里.
TNF_ABSOLUTE_URI
注意:我们推荐用RTD_URI
类型替代TNF_ABSOLUTE_URI
,
因为它效率更高.
你可以用下面的方法创建一条TNF_ABSOLUTE_URI
NDEF
记录:
NdefRecord uriRecord = new NdefRecord(
NdefRecord.TNF_ABSOLUTE_URI ,
"http://developer.android.com/index.html".getBytes(Charset.forName("US-ASCII")),
new byte[0], new byte[0]);
<intent-filter>
<action android:name="android.nfc.action.NDEF_DISCOVERED" />
<category android:name="android.intent.category.DEFAULT" />
<data android:scheme="http"
android:host="developer.android.com"
android:pathPrefix="/index.html" />
</intent-filter>
TNF_MIME_MEDIA
你可以用下面的方式创建TNF_MIME_MEDIA
NDEF
记录.
使用createMime()
方法:
NdefRecord mimeRecord = NdefRecord.createMime("application/vnd.com.example.android.beam",
"Beam me up, Android".getBytes(Charset.forName("US-ASCII")));
手动创建NdefRecord
:
NdefRecord mimeRecord = new NdefRecord(
NdefRecord.TNF_MIME_MEDIA ,
"application/vnd.com.example.android.beam".getBytes(Charset.forName("US-ASCII")),
new byte[0], "Beam me up, Android!".getBytes(Charset.forName("US-ASCII")));
先前的 NDEF 记录的intent filter这样表示:
<intent-filter>
<action android:name="android.nfc.action.NDEF_DISCOVERED" />
<category android:name="android.intent.category.DEFAULT" />
<data android:mimeType="application/vnd.com.example.android.beam" />
</intent-filter>
TNF_WELL_KNOWN with RTD_TEXT
可以用下面这种方式创建一条TNF_WELL_KNOWN
NDEF
记录:
public NdefRecord createTextRecord(String payload, Locale locale, boolean encodeInUtf8) {
byte[] langBytes = locale.getLanguage().getBytes(Charset.forName("US-ASCII"));
Charset utfEncoding = encodeInUtf8 ? Charset.forName("UTF-8") : Charset.forName("UTF-16");
byte[] textBytes = payload.getBytes(utfEncoding);
int utfBit = encodeInUtf8 ? 0 : (1 << 7);
char status = (char) (utfBit + langBytes.length);
byte[] data = new byte[1 + langBytes.length + textBytes.length];
data[0] = (byte) status;
System.arraycopy(langBytes, 0, data, 1, langBytes.length);
System.arraycopy(textBytes, 0, data, 1 + langBytes.length, textBytes.length);
NdefRecord record = new NdefRecord(NdefRecord.TNF_WELL_KNOWN,
NdefRecord.RTD_TEXT, new byte[0], data);
return record;
}
intent filter 这样表示:
<intent-filter>
<action android:name="android.nfc.action.NDEF_DISCOVERED" />
<category android:name="android.intent.category.DEFAULT" />
<data android:mimeType="text/plain" />
</intent-filter>
TNF_WELL_KNOWN with RTD_URI
你可以用下面这种方式创建一条TNF_WELL_KNOWN
NDEF
记录.
使用createUri(String)
方法:
NdefRecord rtdUriRecord1 = NdefRecord.createUri("http://example.com");
使用createUri(Uri)
方法:
Uri uri = new Uri("http://example.com");
NdefRecord rtdUriRecord2 = NdefRecord.createUri(uri);
手动创建NdefRecord
:
byte[] uriField = "example.com".getBytes(Charset.forName("US-ASCII"));
byte[] payload = new byte[uriField.length + 1]; //add 1 for the URI Prefix
byte payload[0] = 0x01; //prefixes http://www. to the URI
System.arraycopy(uriField, 0, payload, 1, uriField.length); //appends URI to payload
NdefRecord rtdUriRecord = new NdefRecord(
NdefRecord.TNF_WELL_KNOWN, NdefRecord.RTD_URI, new byte[0], payload);
<intent-filter>
<action android:name="android.nfc.action.NDEF_DISCOVERED" />
<category android:name="android.intent.category.DEFAULT" />
<data android:scheme="http"
android:host="example.com"
android:pathPrefix="" />
</intent-filter>
TNF_EXTERNAL_TYPE
你可以用下面这种方式创建一条TNF_EXTERNAL_TYPE
NDEF
记录:
使用createExternal()
方法:
byte[] payload; //assign to your data
String domain = "com.example"; //usually your app's package name
String type = "externalType";
NdefRecord extRecord = NdefRecord.createExternal(domain, type, payload);
手动创建NdefRecord
:
byte[] payload;
...
NdefRecord extRecord = new NdefRecord(
NdefRecord.TNF_EXTERNAL_TYPE, "com.example:externalType", new byte[0], payload);
<intent-filter>
<action android:name="android.nfc.action.NDEF_DISCOVERED" />
<category android:name="android.intent.category.DEFAULT" />
<data android:scheme="vnd.android.nfc"
android:host="ext"
android:pathPrefix="/com.example:externalType"/>
</intent-filter>
使用更加一般化的TNF_EXTERNAL_TYPE类型NFC部署,以便更好的支持Android设备和非Android设备。
注意:TNF_EXTERNAL_TYPE类型的URN包含以下格式:urn:nfc:ext:example.com:externalType
,但是,NFC论坛的RTD规范声明,URN的urn:nfc:ext:部分在NDEF记录中必须忽略。因此你需要提供的所有信息是用“:”号把域名(示例中的example.com)和类型(示例中的externalType)分离开。在调度TNF_EXTERNAL_TYPE类型的记录时,Android会把urn:nfc:ext:example.com:externalType的URN转换成vnd.android.nfc://ext/example.com:externalType的URI,它是在示例中声明的Intent过滤器。
android应用程序记录-AAR
在Android4.0(API Level 14)中引入的Android应用程序记录(AAR),提供了较强的在扫描到NFC标签时,启动应用程序的确定性。AAR有嵌入到NDEF记录内部的应用程序的包名。你能够把一个AAR添加到你的NDEF消息的任何记录中,因为Android会针对AAR来搜索整个NDEF消息。如果它找到一个AAR,它就会基于AAR内部的包名来启动应用程序。如果该应用程序不在当前的设备上,会启动Google Play来下载对应的应用程序。
如果NFC标签中包含了AAR,则NFC标签调度系统会按照下列方式来调度:
1.通常,尝试使用Intent过滤器来启动一个Activity。如果跟该Intent匹配的Activity也跟AAR匹配,那么就启动该Activity。
2.如果跟Intent队形的Activity跟AAR不匹配,或者是有多个Activity能够处理该Intent,或者是没有能够处理该Intent的Activity存在,那么就启动由AAR指定的应用程序。
3.如果没有跟该AAR对应的应用程序,那么就会启动Google Play来小组基于该AAR的应用程序。
注意:你能够用前端调度系统来重写AAR和Intent调度系统,在NFC标签被发现时。它允许优先使用前台的Activity。用这种方法,Activity必须是在前台来重写AAR和Intent调度系统。
createApplicationRecord()
。你需要做的所有工作就是把AAR嵌入到你的NdefMessage中。除非AAR是NdefMessage中的唯一记录,否则不要把使用NdefMessage的第一条记录。这是因为,Android系统会检查NdefMessage的第一条记录来判断NFC标签的MIME类型或URI,这些信息被用于创建对应应用程序的Intent对象。以下代码演示了如何创建一个AAR:
NdefMessage msg = new NdefMessage(
new NdefRecord[] {
...,
NdefRecord.createApplicationRecord("com.example.android.beam")}
把 NDEF 消息发射到其他设备上
Android Beam允许在两个Android设备之间进行简单的对等数据交换,想要把数据发送给另一个设备的应用程序必须是在前台,并且接收数据的设备必须不被锁定。当发射设备跟接收设备的距离足够近的时候,发射设备会显示“Touch to Beam(触摸发射)”的UI。然后,用户能够选择是否把消息发射给接收设备。
注意:在API Level 10中可以利用前台的NDEF推送,它提供了与Android
Beam类似的功能。这些API已经过时了,但是在一些老旧设备上还有效。更多的信息请看enableForegroundNdefPush()
.
通过调用下列两个方法中的任意一个,就能够为你的应用程序启用Android Beam:
-
setNdefPushMessage()
:这个方法把接收到的NdefMessage
对象作为一个消息设置给Beam。当两个设备足够近的时候,就会自动的发送消息。 -
setNdefPushMessageCallback()
:接收包含createNdefMessage()
方法的回调,当设备在发射数据的范围内时,这个回调方法会被调用。回调会让你只在需要的时候创建NDEF消息。
一个Activity一次只能推送一条NDEF消息,因此如果同时使用了这两种方法,因此setNdefPushMessageCallback()
方法的优先级要高于setNdefPushMessage()
方法。要使用Android
Beam,通常必须满足以下条件:
- 发射数据的Activity必须是在前台。两个设备的屏幕都必须没有被锁定.
- 必须发要发射的数据封装到一个
NdefMessage
对象中. -
接收发射数据的NFC设备必须支持
com.android.npp
推送协议或是NFC组织的SNEP协议(简单的NDEF交换协议)。在API Level9(Android2.3)到API Level 13(Android3.2)的设备上需要com.android.npp
协议。在API Level 14(Android4.0)和以后的设备上,com.android.npp
和SNEP都需要。
注意:如果在前台的Activity启用了Android Beam,那么标准的Intent调度系统就会被禁用。但是,如果该Activity还启用了前端调度系统,那么在前台调度系统中,它依然能够扫描到跟Intent过滤器匹配的NFC标签。
启用Android Beam:
-
创建一个准备推送到另一个设备上的包含
NdefRecord
的NdefMessage对象 -
调用带有NdefMessage类型参数的setNdefPushMessage()方法,或者是在Activity的
onCreate()
方法中调用setNdefPushMessageCallback方法来传递实现NfcAdapter.CreateNdefMessageCallback接口的对象。这两个方法都至少需要一个准备要启用Android Beam的Activity,以及一个可选的其他的活跃的Activity列表。 -
通常,如果你的Activity在任何时候都值推送相同的NDEF消息,那么当两个设备在通信范围内的时候,使用
setNdefPushMessage()
就可以了。当你的应用程序要关注应用程序的当前内容,并想要根据用户在你的应用程序中的行为来推送NDEF消息时,就要使用setNdefPushMessageCallback方法。
NfcAdapter.CreateNdefMessageCallback
方法(完整的示例请看AndroidBeamDemo)。这个示例中还有帮助创建MIME记录的方法:
package com.example.android.beam;
import android.app.Activity;
import android.content.Intent;
import android.nfc.NdefMessage;
import android.nfc.NdefRecord;
import android.nfc.NfcAdapter;
import android.nfc.NfcAdapter.CreateNdefMessageCallback;
import android.nfc.NfcEvent;
import android.os.Bundle;
import android.os.Parcelable;
import android.widget.TextView;
import android.widget.Toast;
import java.nio.charset.Charset;
public class Beam extends Activity implements CreateNdefMessageCallback {
NfcAdapter mNfcAdapter;
TextView textView;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
TextView textView = (TextView) findViewById(R.id.textView);
// Check for available NFC Adapter
mNfcAdapter = NfcAdapter.getDefaultAdapter(this);
if (mNfcAdapter == null) {
Toast.makeText(this, "NFC is not available", Toast.LENGTH_LONG).show();
finish();
return;
}
// Register callback
mNfcAdapter.setNdefPushMessageCallback(this, this);
}
@Override
public NdefMessage createNdefMessage(NfcEvent event) {
String text = ("Beam me up, Android!\n\n" +
"Beam Time: " + System.currentTimeMillis());
NdefMessage msg = new NdefMessage(
new NdefRecord[] { createMime(
"application/vnd.com.example.android.beam", text.getBytes())
/**
* The Android Application Record (AAR) is commented out. When a device
* receives a push with an AAR in it, the application specified in the AAR
* is guaranteed to run. The AAR overrides the tag dispatch system.
* You can add it back in to guarantee that this
* activity starts when receiving a beamed message. For now, this code
* uses the tag dispatch system.
*/
//,NdefRecord.createApplicationRecord("com.example.android.beam")
});
return msg;
}
@Override
public void onResume() {
super.onResume();
// Check to see that the Activity started due to an Android Beam
if (NfcAdapter.ACTION_NDEF_DISCOVERED.equals(getIntent().getAction())) {
processIntent(getIntent());
}
}
@Override
public void onNewIntent(Intent intent) {
// onResume gets called after this to handle the intent
setIntent(intent);
}
/**
* Parses the NDEF Message from the intent and prints to the TextView
*/
void processIntent(Intent intent) {
textView = (TextView) findViewById(R.id.textView);
Parcelable[] rawMsgs = intent.getParcelableArrayExtra(
NfcAdapter.EXTRA_NDEF_MESSAGES);
// only one message sent during the beam
NdefMessage msg = (NdefMessage) rawMsgs[0];
// record 0 contains the MIME type, record 1 is the AAR, if present
textView.setText(new String(msg.getRecords()[0].getPayload()));
}
}
注意:上例代码把AAR给注释掉了,你可以删除它。如果你启用了AAR,那么该应用程序就会始终接收在AAR中指定的Android Beam消息。如果该应用程序不存在,Google Play就会启动下载程序。因此,如果使用AAR,对于Android4.0以后的设备,下列的Intent过滤器,在技术上不是必须的:
<intent-filter>
<action android:name="android.nfc.action.NDEF_DISCOVERED"/>
<category android:name="android.intent.category.DEFAULT"/>
<data android:mimeType="application/vnd.com.example.android.beam"/>
</intent-filter>
application/vnd.com.example.android.beam
.类型的MIME记录的Android
beam的时候。
即使通过AAR能够保证了一个应用程序被启动或下载,但是还是推荐使用Intent过滤器,因为它会让你选择启动应用程序中Activity,而不是总启动AAR中指定的应用程序包的主Activity。AAR没有Activity级别的粒度。而且还有一些android设备不支持AAR,你还应该在NDEF消息的第一条NDEF记录中嵌入标识信息,以及对应的过滤器。欲了解有关如何创建记录的更多信息请查阅Creating Common Types of NDEF records
相关推荐
Android 近场通信—NFC 基础 Android 近场通信—NFC 基础是一个基于 Android 平台的近场通信技术,利用 NFC(Near Field Communication,近场通信)技术实现设备之间的数据交换。NFC 技术可以让设备在短距离内实现...
NFC软件基础 ...NFC基础知识培训是指对NFC技术的基础知识进行培训,包括NFC技术的基本原理、NFC技术的应用、NFC技术的挑战等方面的知识。NFC基础知识培训的目的是让学员能更好地理解和应用NFC技术。
Android近场通信(NFC,Near Field Communication)是一种短距离无线通信技术,允许两台设备在靠近时交换数据。在Android系统中,NFC被广泛...了解并熟练掌握这些基础知识,将有助于构建高效且用户友好的NFC应用程序。
一、NFC基础知识 1. NFC工作原理:NFC采用电磁场进行通信,两个设备间距离小于10厘米时,即可进行数据交换。NFC支持三种操作模式:读/写模式、点对点模式和卡模拟模式。 2. RFID高频卡:RFID卡分为低频、高频和超...
1. **NFC基础**: - NFC技术基于射频识别(RFID)演变而来,工作在13.56MHz频率下,有效距离通常小于10厘米。 - NFC标签通常包含存储信息的芯片,可以被具有NFC功能的设备读取或写入。 - NFC有三种模式:读/写...
一、NFC基础 1. NFC技术原理:NFC基于射频识别(RFID)技术,工作频率为13.56MHz,最远有效距离通常在10厘米以内。它支持三种模式:读/写模式、卡模拟模式和点对点模式。 2. Android NFC API:Android提供了全面的...
1. **NFC基础知识**:理解NFC的工作原理,包括其近距离交互特性、传输距离限制(一般在4厘米内)以及支持的数据交换协议(如NDEF - NFC Data Exchange Format)。 2. **AndroidManifest.xml配置**:在Android应用中...
1. **NFC基础知识** - **工作原理**:NFC基于射频识别(RFID)技术,通过电磁场进行通信,最大有效距离一般为4厘米。 - **三种模式**:读/写模式、卡片模式和点对点(P2P)模式。在Android中,你可以实现这三种...
同时,Android还提供了对ISO14443和ISO18092标准的支持,使得开发者可以开发和运行与现有NFC基础设施兼容的应用。 然而,Android的NFC实现也存在一定的局限性。例如,对于特定类型的NFC标签,可能需要额外的硬件...
一、NFC基础知识 1. NFC工作原理:NFC基于射频识别(RFID)技术,通过短距离的高频无线通信,实现设备间的交互。通常,NFC的工作模式有读/写模式、点对点模式(P2P)和卡片模拟模式。 2. Android中的NFC框架:...
一、NFC基础概念 1. NFC工作原理:NFC通过电磁场进行数据交换,两个设备间的距离通常需在10厘米以内。它支持读写模式、卡模拟模式和点对点模式。 2. 标签(Tag):NFC标签包含存储数据的芯片,可以被手机读取或写入...
1. NFC基础: NFC技术基于RFID(Radio Frequency Identification)原理,工作频率通常在13.56MHz,最大传输距离约为10厘米。它支持三种模式:读/写模式、点对点模式(P2P)和卡片模拟模式。 2. Android NFC API: ...
一、NFC基础 1. NFC工作原理:NFC基于射频识别(RFID)技术,通过两个设备间的磁场交互来传输数据。它的工作距离通常在4厘米以内,适合快速、简单的数据交换。 2. NFC模式:NFC有三种主要工作模式——卡模拟模式、...
一、NFC基础 1.1 NFC工作原理:NFC基于RFID(Radio Frequency Identification)技术,通过电磁波进行通信,有效距离通常在4厘米以内。设备间可以进行读/写操作,点对点通信或模拟卡片模式。 1.2 Android中的NFC ...
1. **NFC基础知识**:NFC工作在13.56MHz频率下,支持三种模式:读/写模式、卡模拟模式和点对点模式。在Android中,NFC功能主要由`android.nfc`包下的类和接口提供,如`NfcAdapter`, `Ndef`和`Tag`等。 2. **...
一、NFC基础 1. 工作原理:NFC基于射频识别(RFID)技术,工作频率通常为13.56MHz,有效范围一般在4厘米以内。设备间通过电磁波进行数据传输,无需物理接触,且功耗低。 2. 支持模式:NFC支持三种主要模式:读/写...
1. **NFC基础知识**: - **工作原理**:NFC基于射频识别(RFID)技术,通过电磁场进行通信,距离通常在4厘米内。 - **模式**:NFC设备可以工作在读卡器模式、卡片模式和点对点(P2P)模式。 2. **API组件**: - ...
1. **NFC基础知识** - **工作原理**:NFC采用了RFID(无线频率识别)技术,通过电磁场进行通信。通信双方设备只需一个处于激活状态,另一个可以处于被动模式。 - **NFC类型**:包括卡模拟模式(Card Emulation)、...