NFC高级

高级 NFC

本文档介绍了高级的NFC主题,如各种标签技术,NFC标签写入和前台发布,它允许即使当其他应用程序过滤器相同的时候,应用程序在前台处理Intent。

Tag技术支持工作



当使NFC Tag和Android的供电设备生效,使用Tag来读取和写入数据的主要格式是NDEF,当设备扫描NDEF数据的Tag,Android提供支持解析的消息,并在可能的情况下将它传入一个NdefMessage,但是,在有些情况下,当你扫描不包含NDEF数据的Tag或当NDEF数据时无法映射到MIME类型或URI时。在那样的情况下,你需要直接与Tag建立沟通及用自己的协议(在原始字节)读写它,Android用android.nfc.tech包对那些情况提供了通用的支持,如表1中所描述的。您可以使用getTechList()方法来确定技术支持Tag,并且用由android.nfc.tech提供的类的其中一个创建相应TagTechnology对象.

表 1. 支持的Tag技术

描述
TagTechnology 这个接口是下面所有tag technology类必须实现的。
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 提供对那些被格式化为NDEFtag的数据的访问和其他操作
NdefFormatable 对那些可以被格式化成NDEF格式的tag提供一个格式化的操作

下面的Tag技术不要求被Android的供电设备支持。

表 2. 可选的支持的Tag技术

描述
MifareClassic 如果android设备支持MIFARE,提供对MIFARE Classic目标的属性和I/O操作。
MifareUltralight 如果android设备支持MIFARE,提供对MIFARE Ultralight目标的属性和I/O操作。

Tag技术工作和 ACTION_TECH_DISCOVERED Intent


当一个设备扫描一个有NDEF数据的Tag,但不能被映射到一个MIME或URI时,Tag发布系统试图启动一个Activity与ACTION_TECH_DISCOVERED Intent。当非NDEF被扫描到时,ACTION_TECH_DISCOVERED的Tag也可以使用.如果Tag发布系统无法为你解析它,此回退让你直接进行扫描标签上的数据,基本步骤与标签技术如下:

  1. 过滤一个你想要处理的Tag技术的 ACTION_TECH_DISCOVERED intent. 获取更多信息请参阅 过滤 NFC intents. 一般来说。 当一个NDEF消息不能被映射到MIME类型或者URI上时,Tag发布系统尝试启动一个ACTION_TECH_DISCOVERED intent, 否则如果被扫描到的Tag不包含NDEF数据. 欲了解如何确定的更多信息,请参阅Tag发布系统.
  2. 当你的应用程序接收到该Intent, 从以图中获取Tag对象:
    Tag tagFromIntent = intent.getParcelableExtra(NfcAdapter.EXTRA_TAG);
  3. 通过调用在android.nfc.tech包的类中的一个get factory方法,获取到TagTechnology的一个实例 . 你可以在调用一个get factory方法以前,计算支持Tag技术通过调用getTechList(). 举例来说, 为了从一个Tag得到MifareUltralight的一个实例, 请执行下列操作:
    MifareUltralight.get(intent.getParcelableExtra(NfcAdapter.EXTRA_TAG));

读取和写入Tags


读取和写入NFC tag涉及到从Intent中获取到Tag并创建与tag的连接. 你必须定义你自己的协议来读写数据到Tag. 然后,记住当直接使用Tag时你仍然能够读写NDEF数据. 你想要如何构建东西,它可以实现. 如下的例子演示如何使用一个MIFARE Ultralight tag.

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; } }

使用前端发布系统


前端发布系统允许一个activity拦截一个 intent并且要求由于其他处理同样intent的activities. 使用这个系统涉及到为了Android系统能够发送合适的intents给你的应用程序而构建几个数据结构. 为了使前端发布系统有效:

  1. 在你的activity的 onCreate()方法中添加如下代码:
    1. 创建一个 PendingIntent 对象, 以便系统可以在它被扫描到时,用tag的细节填充它
      PendingIntent pendingIntent = PendingIntent.getActivity( this, 0, new Intent(this, getClass()).addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP), 0);
    2. 在Intent filters里声明你想要处理的Intent,一个tag被检测到时先检查前台发布系统,如果前台Activity符合Intent filter的要求,那么前台的Activity的将处理此Intent。如果不符合,前台发布系统将Intent转到Intent发布系统。如果指定了null的Intent filters,当任意tag被检测到时,你将收到TAG_DISCOVERED intent。下面的代码片断处理所有NDEF_DISCOVERED的MIME类型. 因此请注意你应该只处理你想要的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. 设置一个你程序要处理的Tag technologies的列表,调用Object.class.getName() 方法来获得你想要支持处理的technology类。
      techListsArray = new String[][] { new String[] { NfcF.class.getName() } };
  2. 覆盖下面的方法来打开或关闭前台发布系统。比如onPause()onResume()方法。必须在主线程里调用enableForegroundDispatch(Activity, PendingIntent, IntentFilter[], String[][]) 而且Activity在前台(可以在onResume()里调用来保证这点)。你也要覆盖onNewIntent回调来处理得到的NFC tag数据。
    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 Demos获取完整的示例演示ForegroundDispatch例子

你可能感兴趣的:(NFC,高级)