Advanced NFC(高级NFC)——翻译自developer.android.com

来源:互联网 发布:推荐一本编程的书籍 编辑:程序博客网 时间:2024/06/12 00:23

高级NFC  Advanced NFC

这篇介绍高级NFC主题,比如说使用各种不同的标签诗句,写入nfc标签,和前台派发。前台派发可以让有其他的应用也注册了过滤该intent的过滤器的时候,前台的应用可以截获intent。

使用支持的标签技术  Working with Supported Tag Technologies

当使用NFC标签和Android设备的时候,使用的主要的格式是ndef格式。当扫描到一个NDEF标签,Android系统会提供解析消息成为NdefMessage的支持。但是有一些情况下你会扫描到不包含NDEF格式数据的标签,或者NDEF数据不能为转化成为MIMIE类型或者URI。这种情况下,你需要直接与标签建立连接,并使用你自己定义的协议栈,使用原始字节和标签读写通信。 Android 使用android.nfc.tech包对这种非ndef情况进行提供支持,如表1中所示。你可以使用getTechList方法来判断标签支持的的技术,并且使用android.nfc.tech的类创建与之对应的TagTechnology对象。
表1.

Table 1. 支持的NFC标签技术

ClassDescriptionTagTechnologyThe interface that all tag technology classes must implement.NfcAProvides access to NFC-A (ISO 14443-3A) properties and I/O operations.NfcBProvides access to NFC-B (ISO 14443-3B) properties and I/O operations.NfcFProvides access to NFC-F (JIS 6319-4) properties and I/O operations.NfcVProvides access to NFC-V (ISO 15693) properties and I/O operations.IsoDepProvides access to ISO-DEP (ISO 14443-4) properties and I/O operations.NdefProvides access to NDEF data and operations on NFC tags that have been formatted as NDEF.NdefFormatableProvides a format operations for tags that may be NDEF formattable.

下面是不强求android设备支持的技术。

Table 2. 可选技术

ClassDescriptionMifareClassicProvides access to MIFARE Classic properties and I/O operations, if this Android device supports MIFARE.MifareUltralightProvides access to MIFARE Ultralight properties and I/O operations, if this Android device supports MIFARE.

使用标签技术和ACTION_TECH_DISCOVERED intent  Working with tag technologies and the ACTION_TECH_DISCOVERED intent

当设备扫描到包含NDEF的数据,但是无法将其转化为MIME类型或者URI的时候,或者没有NDEF格式的时候,就会让标签派发系统产生一个ACTION_TECH_DISCOVERED的intent来启动activity。这个备选项可以在系统不能为你解析标签的时候,让你可以直接处理标签。下面是使用标签技术的基本步骤:

1.过滤你想处理的标签技术的ACTION_TECH_DISCOVERED intent。细节可以查看 Filtering for NFC intents。当不含有NDEF格式或者无法转换为MIME或者URI类型的时候,就会启动这种intent,系统如何判定的,可以参见Tag Dispatch System。
2.app接收到intent的时候,从中获取Tag对象。
Tag tagFromIntent = intent.getParcelableExtra(NfcAdapter.EXTRA_TAG);
3.通过包android.nfc.tech中的类的get工厂方法,来获取标签技术类TagTechnology的实例。在这之前你可以通过调用getTechList来获取标签支持的技术的列举。下面是一个用Tag对象获取MifareUltralight 的例子:
MifareUltralight.get(intent.getParcelableExtra(NfcAdapter.EXTRA_TAG));

读写标签 Reading and writing to tags

读写标签包含从intent中获取标签和跟标签建立通信。你需要建立自己的协议栈来的读写标签。然而当你直接和标签通信的时候,你仍然可以读写NDEF格式的数据。你可以决定其组织的结构。下面是一个使用MIFARE Ultralight 标签的例子。

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;    }}
使用前台派发系统 Using the Foreground Dispatch System

前台派发系统可以让activity拦截intent,并且声明比其他要拦截同样intent的activity的更高的优先级。使用这个系统需要构建一些数据结构,从而使得android的系统可以向你的应用发送正确的intent。步骤如下:

1.在你的activity的onCreate方法中创建如下代码。
1.创建一个PendingIntent,这样系统在扫描到标签的时候会把标签的详细信息填充进去。
PendingIntent pendingIntent = PendingIntent.getActivity(    this, 0, new Intent(this, getClass()).addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP), 0);
2.为你想拦截intent建立过滤器。出现标签时,系统会用过滤器进行匹配,如果成功则activity获得intent,如果失败则前台派发系统退化为之前的intent派发系统。声明一个null的Filter的数组,和标签技术个过滤器的数组,然后填入当回退为TAG_DISVOERED intent的时候你想要捕获的intent的类型。下面的代码片是拦截所有MIME类型的NDEF_DISCOVERED类型的intent的例子,你应该根据你的需要拦截几种。

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, };
3.设置你的app想拦截的标签技术的数组。调用Object.class.getName方法来获得你想支持的技术的类。
techListsArray = new String[][] { new String[] { NfcF.class.getName() } };

2.重写activity声明周期的回到函数,并且加入随着activity获取焦点(onPause)和失去焦点(onResume)的时候启用和禁用前台派发的逻辑。enableForegroundDispatch一定要从主线程中调用,并且仅当activity在前台的时候才可以(使用onResume来保证)。你还需要实现onNewIntent的回调函数来处理从NFC标签中得到的数据。
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}
完整的例子请查看API Demo中的ForegroundDispatch的例子。
0 0
原创粉丝点击