标签:
本文档介绍了Android中执行基本任务NFC。它说明了如何在NDEF消息的形式发送和接收数据的NFC并介绍了支持这些功能的Andr??oid框架的API。对于更高级的主题,包括与非NDEF数据工作的讨论,请参阅高级NFC。如果没有应用程序筛选任何意图的,什么也不做。
只要有可能,以NDEF消息和ACTION_NDEF_DISCOVERED意图工作,因为它是最特定出的三个。此意向,您可以在比其他两个意图更适当的时间启动应用程序,给用户更好的体验。
请求在Android清单NFC访问
在可以访问设备的NFC硬件,妥善处理NFC意图,声明在AndroidManifest.xml文件以下项目:
该NFC<使用许可权>元素访问NFC硬件:
<uses-permission android:name="android.permission.NFC" />最低SDK版本,你的应用程序可以支持。 API级9只支持通过ACTION_TAG_DISCOVERED有限标签调度,并只给出了通过额外的NDEF邮件中多余的访问NDEF消息。没有其他标签属性或I / O操作都可以访问。 API级别10包括全面的读/写支持,以及前景NDEF推搡,和API级14提供了一个更简单的方法来推动NDEF消息,Android Beam功能和额外的便利方法的其他设备来创建NDEF记录。
<uses-sdk android:minSdkVersion="10"/>用途特征元素所以只有您的应用程序在谷歌显示出来玩的有NFC硬件设备:
<uses-feature android:name="android.hardware.nfc" android:required="true" />如果应用程序使用NFC功能,但该功能是不是你的应用是至关重要的,你可以省略的用途,特征元素,并检查是否getDefaultAdapter()是空在运行时检查NFC avalailbility。
<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技术或可以支持NFC和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> ... <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>有关与标签技术和动作TECH_DISCOVERED意图,请参阅使用高级NFC文件中支持的标签技术的更多信息。
<intent-filter> <action android:name="android.nfc.action.TAG_DISCOVERED"/> </intent-filter>从意向获取信息
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 }另外,您也可以从意向,其中将包含有效载荷,并允许您列举标记的技术的Tag对象:
Tag tag = intent.getParcelableExtra(NfcAdapter.EXTRA_TAG);创建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]);前一个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媒体
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>TNF_WELL_KNOWN与RTD_TEXT
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> <action android:name="android.nfc.action.NDEF_DISCOVERED" /> <category android:name="android.intent.category.DEFAULT" /> <data android:mimeType="text/plain" /> </intent-filter>
使用createUri(String)方法:
NdefRecord rtdUriRecord1 = NdefRecord.createUri("http://example.com");使用创建的URI(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" android:pathPrefix="" /> </intent-filter>TNF_EXTERNAL_TYPE
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);前一个NDEF记录的意图过滤器是这样的:
<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>使用更多通用的NFC标签部署TNF_EXTERNAL_TYPE,以更好地支持Android的供电和非Android设备。
NdefMessage msg = new NdefMessage( new NdefRecord[] { ..., NdefRecord.createApplicationRecord("com.example.android.beam")}喜气洋洋NDEF消息给其它设备
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,你可以删除。如果启用了AIR,在AAR指定的应用程序总是收到Android Beam的消息。如果应用程序不存在,谷歌播放开始下载应用程序。因此,如果使用的AAR以下意图过滤器是不适合的Android4.0设备或更高技术上必需的:
<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>有了这个意图过滤器中,com.example.android.beam应用程序现在可以在扫描NFC标签或接收到的Android梁式com.example.android.beam的AAR,或当NDEF格式的消息包含一个开始类型应用程序/ vnd.com.example.android.beam的MIME纪录。
Android API Guides---NFC Basics
标签:
原文地址:http://blog.csdn.net/qq_21413973/article/details/51189538