文章译自:Advanced NFC
本文档介绍了高级NFC,如与各种标签技术协作,NFC标签写入和前台调度,它允许应用程序在前台处理的intent,即使当其他应用程序过滤器相同的。
Table 1. Supported tag technologies
Class | Description |
---|---|
TagTechnology |
所有标签技术类必须实现的接口。 |
NfcA |
提供NFC-A(ISO 14443-3A)的性能和I / O操作的访问。 |
NfcB |
提供NFC-B (ISO 14443-3B)的性能和I / O操作的访问。 |
NfcF |
提供 NFC-F (JIS 6319-4)的性能和I / O操作的访问。 |
NfcV |
提供 NFC-V (ISO 15693)的性能和I / O操作的访问。 |
IsoDep |
提供 ISO-DEP (ISO 14443-4)的性能和I / O操作的访问。 |
Ndef |
提供NFC标签已被格式化为NDEF的数据和操作的访问。 |
NdefFormatable |
提供可能被格式化为NDEF的 formattable的标签。 |
下面的tag技术并不强制android设备支持(即选择性的支持)。
Table 2. Optional supported tag technologies
Class | Description |
---|---|
MifareClassic |
如果此Android设备支持MIFARE,提供访问的MIFARE Classic性能和I / O操作。 |
MifareUltralight |
如果此Android设备支持MIFARE,提供访问的MIFARE 超轻性能和I / O操作。 |
当设备扫描含有NDEF数据的tag,但不能被映射到一个MIME或URI,标签调度系统试图启动一个携带ACTION_TECH_DISCOVERED intent的activity。 扫描tag不是NDEF数据格式时,ACTION_TECH_DISCOVERED也可使用。有这种东西,如果标签调度系统无法解析tag时,可以直接与tag上数据进行交互。tag技术工作时的基本步骤如下:
1、过滤指定要处理的标签技术的ACTION_TECH_DISCOVERED intent。在一般情况下,标签调度系统尝试启动一个ACTION_TECH_DISCOVERED的intent,当NDEF消息,不能被映射为MIME类型或URI,或者如果标签扫描不包含NDEF数据。如何确定欲了解更多信息,请参阅标签调度系统。
2、当你的应用程序接收的intent,取得标签对象:
Tag tagFromIntent = intent.getParcelableExtra(NfcAdapter.EXTRA_TAG);3、获得实例的TagTechnology,通过调用android.nfc.tech包 的get方法。调用get方法前,通过调用getTechList()可以列举tag支持的技术。例如,从tag中要获得一个实例MifareUltralight,可以如下做:
MifareUltralight.get(intent.getParcelableExtra(NfcAdapter.EXTRA_TAG));
NFC标签读写必须确保获得intent并打开tag间通信。为了读取和写入数据到标签,您必须定义自己的协议栈。请记住,当直接与tag交互时,你仍然可以读取写NDEF格式的数据。它依赖你怎么去构建。下面的例子显示了如何使用一个MIFARE超轻标签。
package com.example.android.nfc; import android.nfc.Tag; import android.nfc.tech.MifareUltralight; import android.util.Log; import java.io.IOException; import java.nio.charset.Charset; public class MifareUltralightTagTester { private static final String TAG = MifareUltralightTagTester.class.getSimpleName(); public void writeTag(Tag tag, String tagText) { MifareUltralight ultralight = MifareUltralight.get(tag); try { ultralight.connect(); ultralight.writePage(4, "abcd".getBytes(Charset.forName("US-ASCII"))); ultralight.writePage(5, "efgh".getBytes(Charset.forName("US-ASCII"))); ultralight.writePage(6, "ijkl".getBytes(Charset.forName("US-ASCII"))); ultralight.writePage(7, "mnop".getBytes(Charset.forName("US-ASCII"))); } catch (IOException e) { Log.e(TAG, "IOException while closing MifareUltralight...", e); } finally { try { ultralight.close(); } catch (IOException e) { Log.e(TAG, "IOException while closing MifareUltralight...", e); } } } public String readTag(Tag tag) { MifareUltralight mifare = MifareUltralight.get(tag); try { mifare.connect(); byte[] payload = mifare.readPages(4); return new String(payload, Charset.forName("US-ASCII")); } catch (IOException e) { Log.e(TAG, "IOException while writing MifareUltralight message...", e); } finally { if (mifare != null) { try { mifare.close(); } catch (IOException e) { Log.e(TAG, "Error closing tag...", e); } } } return null; } }
a、创建一个PendingIntent对象,android系统可以填充在tag被扫描到的内容。PendingIntent pendingIntent = PendingIntent.getActivity( this, 0, new Intent(this, getClass()).addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP), 0);b、声明intent过滤器来处理你想拦截的intent。前台调度系统检查过滤指定的intent,这个intent是扫描标签时收到的。如果匹配,那么你的应用程序处理的意图。如果它不匹配,前台调度系统回到intent调度系统的。指定一个空的数组intent过滤器和技术过滤器,指定要过滤所有的标签,回到TAG_DISCOVERED intent。下面的代码片段处理所有MIME类型NDEF_DISCOVERED。您应该只处理那些你需要的。IntentFilter ndef = new IntentFilter(NfcAdapter.ACTION_NDEF_DISCOVERED); try { ndef.addDataType("*/*");/* Handles all MIME based dispatches. You should specify only the ones that you need. */ } catch (MalformedMimeTypeException e) { throw new RuntimeException("fail", e); } intentFiltersArray = new IntentFilter[] {ndef, };c、设置您的应用程序要处理tag技术的数组。调用 Object.class.getName()方法来获取支持的所以技术。techListsArray = new String[][] { new String[] { NfcF.class.getName() } };
public void onPause() { super.onPause(); mAdapter.disableForegroundDispatch(this); } public void onResume() { super.onResume(); mAdapter.enableForegroundDispatch(this,pendingIntent,intentFiltersArray,techListsArray); } public void onNewIntent(Intent intent) { Tag tagFromIntent = intent.getParcelableExtra(NfcAdapter.EXTRA_TAG); //do something with tagFromIntent }