本文档介绍了在Android中执行的基本NFC任务。 它解释了如何以NDEF消息的形式发送和接收NFC数据,并描述了支持这些功能的Android框架API。 有关更高级的主题,包括讨论使用非NDEF数据的讨论,请参阅高级NFC。
1、从NFC标签读取NDEF数据。
2、使用Android Beam™将NDEF消息从一个设备发送到另一个设备
一、标签调度系统
1、解析NFC标签,找出MIME类型或标识标签中数据有效内容的URI。
2、将MIME类型或URI和有效内容封装成意图。 NFC标签如何映射到MIME类型和URI中描述了前两个步骤。
3、根据意图启动活动。 这在NFC标签如何分派到应用程序中有所描述。
一)、NFC标签如何映射到MIME类型和URI
1、3位TNF(类型名称格式)
2、可变长度类型
3、可变长度ID
4、可变长度有效载荷
| Type Name Format (TNF) | Mapping |
|---|---|
TNF_ABSOLUTE_URI |
基于类型字段的URI。 |
TNF_EMPTY |
Falls back to ACTION_TECH_DISCOVERED. |
TNF_EXTERNAL_TYPE |
URI based on the URN in the type field. The URN is encoded into the NDEF type field in a shortened form: <domain_name>:<service_name>. Android maps this to a URI in the form: vnd.android.nfc://ext/<domain_name>:<service_name>. |
TNF_MIME_MEDIA |
MIME type based on the type field. |
TNF_UNCHANGED |
Invalid in the first record, so falls back to ACTION_TECH_DISCOVERED. |
TNF_UNKNOWN |
Falls back to ACTION_TECH_DISCOVERED. |
TNF_WELL_KNOWN |
MIME type or URI depending on the Record Type Definition (RTD), which you set in the type field. See Table 2 for more information on available RTDs and their mappings. |
| Record Type Definition (RTD) | Mapping |
|---|---|
RTD_ALTERNATIVE_CARRIER |
Falls back to ACTION_TECH_DISCOVERED. |
RTD_HANDOVER_CARRIER |
Falls back to ACTION_TECH_DISCOVERED. |
RTD_HANDOVER_REQUEST |
Falls back to ACTION_TECH_DISCOVERED. |
RTD_HANDOVER_SELECT |
Falls back to ACTION_TECH_DISCOVERED. |
RTD_SMART_POSTER |
URI based on parsing the payload. |
RTD_TEXT |
MIME type of text/plain. |
RTD_URI |
URI based on payload. |
二)、NFC标签如何分派到应用程序
1、ACTION_NDEF_DISCOVERED:当扫描包含NDEF有效负载的标签并且是公认类型时,此意图用于启动“活动”。 这是最高优先级的意图,标签发送系统尽可能尝试在任何其他意图之前以此意图启动活动。
2、ACTION_TECH_DISCOVERED:如果没有活动注册以处理ACTION_NDEF_DISCOVERED意图,则标记分发系统尝试以此意图启动应用程序。 如果扫描的标签包含无法映射到MIME类型或URI的NDEF数据,或者标签不包含NDEF数据但是已知标签技术,则此意图也将直接启动(首先不启动ACTION_NDEF_DISCOVERED)。
3、ACTION_TAG_DISCOVERED:如果没有活动处理ACTION_NDEF_DISCOVERED或ACTION_TECH_DISCOVERED意图,则此意图启动。
1、尝试在解析NFC标签(ACTION_NDEF_DISCOVERED或ACTION_TECH_DISCOVERED)时由标记分派系统创建的意图启动活动。
2、如果没有为此意图过滤活动,请尝试启动具有下一个最低优先级意图(ACTION_TECH_DISCOVERED或ACTION_TAG_DISCOVERED)的活动,直到应用程序过滤意图或直到标签分派系统尝试所有可能的意图。
3、如果没有应用程序过滤任何意图,不做任何事情。
二、在Android清单中请求NFC访问
1、NFC <uses-permission>元素访问NFC硬件:
<uses-permission android:name="android.permission.NFC" />
讯享网
2、应用程序可以支持的最低SDK版本。 API级别9仅通过ACTION_TAG_DISCOVERED支持有限的标签分发,并且只能通过EXTRA_NDEF_MESSAGES额外的方式访问NDEF消息。 没有其他标签属性或I / O操作可访问。 API 10级包括全面的读写器支持以及前景NDEF推送,API 14级提供了一种更轻松的方法,可以将NDEF消息推送到其他具有Android Beam的设备,并提供了额外的便利方法来创建NDEF记录。
讯享网<uses-sdk android:minSdkVersion="10"/>
3、使用要素元素,使您的应用程序仅在具有NFC硬件的设备上显示在Google Play中:
<uses-feature android:name="android.hardware.nfc" android:required="true" />
如果您的应用程序使用NFC功能,但该功能对您的应用程序并不重要,则可以省略use-feature元素,并在运行时检查NFC avalailbility,以查看getDefaultAdapter()是否为空。

三、过滤NFC意图
一)、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>
以下示例以http://developer.android.com/index.html的形式过滤URI。
<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
讯享网<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>
您还可以指定多个技术列表集。 每个技术列表集都被视为独立的,如果任何单个技术列表集合是getTechList()返回的技术的一部分,您的活动将被视为匹配项。 这提供了用于匹配技术的AND和OR语义。 以下示例匹配可支持NfcA和Ndef技术的标签,或者可以支持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>元素<element>元素中创建的资源文件,如下例所示:
讯享网<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>
有关使用标签技术和ACTION_TECH_DISCOVERED意图的更多信息,请参阅高级NFC文档中的使用支持的标签技术。
三)、ACTION_TAG_DISCOVERED
<intent-filter> <action android:name="android.nfc.action.TAG_DISCOVERED"/> </intent-filter>
1、从意图获取信息
1)、EXTRA_TAG(必需):表示扫描标签的标签对象。
2)、EXTRA_NDEF_MESSAGES(可选):从标签解析的NDEF消息数组。 ACTION_NDEF_DISCOVERED意图是强制性的。
3)、EXTRA_ID(可选):标签的低级ID。
讯享网@Override protected void onNewIntent(Intent intent) { super.onNewIntent(intent); ... if (intent != null && NfcAdapter.ACTION_NDEF_DISCOVERED.equals(intent.getAction())) { Parcelable[] rawMessages = intent.getParcelableArrayExtra(NfcAdapter.EXTRA_NDEF_MESSAGES); if (rawMessages != null) { NdefMessage[] messages = new NdefMessage[rawMessages.length]; for (int i = 0; i < rawMessages.length; i++) { messages[i] = (NdefMessage) rawMessages[i]; } // Process the messages array. ... } } }
或者,您可以从意图获取Tag对象,该对象将包含有效负载,并允许您枚举标记的技术:
Tag tag = intent.getParcelableExtra(NfcAdapter.EXTRA_TAG);
四、创建NDEF记录的常见类型
一)、TNF_ABSOLUTE_URI
讯享网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]);
以前的NDEF记录的意图过滤器将如下所示:
<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
讯享网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> <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>
三)、使用RTD_TEXT的TNF_WELL_KNOWN
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; }
以前的NDEF记录的意图过滤器将如下所示:
讯享网<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与RTD_URI
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);
以前的NDEF记录的意图过滤器将如下所示:
讯享网<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"<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>
android:pathPrefix="" /></intent-filter>讯享网
五)、TNF_EXTERNAL_TYPE您可以通过以下方式创建一个TNF_EXTERNAL_TYPE NDEF记录:

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容,请联系我们,一经查实,本站将立刻删除。
如需转载请保留出处:https://51itzy.com/kjqy/34445.html