Android NFC开发MifareUltralight读写Demo实例下载
2015-06-12 12:07:38  By: dwtedx

简介

基于这两天一直在研究NFC的相关技术、昨天发表了一篇 Android NFC开发MifareClassic读写Demo实例下载 相关的文章、是Android NFC的MifareClassic数据格式的实现方式、今天将和大家分享另外一种数据格式的读写方式MifareUltralight、希望有需求的哥们少走弯路


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对象


支持的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技术

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


Tag技术工作和 ACTION_TECH_DISCOVERED Intent

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

过滤一个你想要处理的Tag技术的 ACTION_TECH_DISCOVERED intent. 获取更多信息请参阅 过滤 NFC intents. 一般来说、当一个NDEF消息不能被映射到MIME类型或者URI上时、Tag发布系统尝试启动一个ACTION_TECH_DISCOVERED intent、否则如果被扫描到的Tag不包含NDEF数据. 欲了解如何确定的更多信息、请参阅Tag发布系统

当你的应用程序接收到该Intent、从以图中获取Tag对象

Tag tagFromIntent = intent.getParcelableExtra(NfcAdapter.EXTRA_TAG);


通过调用在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

读取数据

public String readTag(Tag tag) {
	MifareUltralight mifare = MifareUltralight.get(tag);
	try {
		mifare.connect();
		byte[] payload1 = mifare.readPages(4);
		byte[] payload2 = mifare.readPages(8);
		
		return new String(payload1, Charset.forName("US-ASCII"))
			  new String(payload2, Charset.forName("US-ASCII"));
	} catch (IOException e) {
		Log.e(TAG, "IOException while writing MifareUltralight message...", e);
		return "读取失败!";
	} catch (Exception ee) {
		Log.e(TAG, "Exception message...", ee);
		return "读取失败!";
	} finally {
		if (mifare != null) {
		   try {
			   mifare.close();
		   }
		   catch (IOException e) {
			   Log.e(TAG, "Error closing tag...", e);
		   }
		}
	}
}


写数据

public void writeTag(Tag tag, String tagText) {
	MifareUltralight ultralight = MifareUltralight.get(tag);
	try {
		ultralight.connect();
		ultralight.writePage(4, "aaaa".getBytes(Charset.forName("US-ASCII")));
		ultralight.writePage(5, "bbbb".getBytes(Charset.forName("US-ASCII")));
		ultralight.writePage(6, "cccc".getBytes(Charset.forName("US-ASCII")));
		ultralight.writePage(7, "dddd".getBytes(Charset.forName("US-ASCII")));
		ultralight.writePage(8, "eeee".getBytes(Charset.forName("US-ASCII")));
		ultralight.writePage(9, "ffff".getBytes(Charset.forName("US-ASCII")));
		ultralight.writePage(10, "gggg".getBytes(Charset.forName("US-ASCII")));
		ultralight.writePage(11, "hhhh".getBytes(Charset.forName("US-ASCII")));
		Toast.makeText(this, "成功写入", Toast.LENGTH_SHORT).show();
	} catch (IOException e) {
		Log.e(TAG, "IOException while closing MifareUltralight...", e);
		Toast.makeText(this, "写入失败", Toast.LENGTH_SHORT).show();
	} finally {
		try {
			ultralight.close();
		} catch (IOException e) {
			Log.e(TAG, "Exception MifareUltralight...", e);
		}
	}
}


使用前端发布系统

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

首先、创建一个 PendingIntent 对象、以便系统可以在它被扫描到时、用tag的细节填充它、然后、在Intent filters里声明你想要处理的Intent、一个tag被检测到时先检查前台发布系统、如果前台Activity符合Intent filter的要求、那么前台的Activity的将处理此Intent、如果不符合、前台发布系统将Intent转到Intent发布系统、如果指定了null的Intent filters、当任意tag被检测到时、你将收到TAG_DISCOVERED intent、下面的代码片断处理所有NDEF_DISCOVERED的MIME类型、因此请注意你应该只处理你想要的Intent、最后、设置一个你程序要处理的Tag technologies的列表、调用Object.class.getName() 方法来获得你想要支持处理的technology类

onCreate代码如下

public void onCreate(Bundle savedInstanceState) {
	super.onCreate(savedInstanceState);
	setContentView(R.layout.main);
	promt = (TextView) findViewById(R.id.text);
	writeButton = (Button)findViewById(R.id.writeTag_button);
	writeButton.setOnClickListener(this);
	// 获取默认的NFC控制器
	mAdapter = NfcAdapter.getDefaultAdapter(this);
	if (mAdapter == null) {
		promt.setText("设备不支持NFC!");
		Toast.makeText(this, "设备不支持NFC!", 
			Toast.LENGTH_SHORT).show();
		finish();
		return;
	}
	if (!mAdapter.isEnabled()) {
		promt.setText("请在系统设置中先启用NFC功能!");
		Toast.makeText(this, "请在系统设置中先启用NFC功能!", 
			Toast.LENGTH_SHORT).show();
		finish();
		return;
	}
	
	pendingIntent = PendingIntent.getActivity(
			this, 0, new Intent(this, getClass())
			.addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP), 0);
	
	IntentFilter ndef = new IntentFilter(NfcAdapter
		.ACTION_NDEF_DISCOVERED);
	try {
		ndef.addDataType("*/*");
	}
	catch (MalformedMimeTypeException e) {
		throw new RuntimeException("fail", e);
	}
	intentFiltersArray = new IntentFilter[] {ndef, };
	techListsArray = new String[][] { 
		new String[] { MifareUltralight.class.getName() } 
	};
}


另外、覆盖下面的方法来打开或关闭前台发布系统、比如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
}


好了、到这里、基本的核心代码就分析完了、希望对大家有用、另外关于AndroidManifest.xml和nfc_teach_filter.xml请参考另外一篇文章 Android NFC开发MifareClassic读写Demo实例下载

Android官方MifareUltralight文档请参考http://developer.android.com/intl/zh-cn/reference/android/nfc/tech/MifareUltralight.html

国内是无法访问 developer.android.com 的、另如果想访问 developer.android.com 可参考 国内如何翻墙访问google.com_google.hk

源代码下载链接: http://dwtedx.com/download.html?bdkey=s/1gdGSuUB 密码: sip7

若资源对你有帮助、浏览后有很大收获、不妨小额打赏我一下、你的鼓励是维持我不断写博客最大动力

想获取DD博客最新代码、你可以扫描下方的二维码、关注DD博客微信公众号(ddblogs)

或者你也可以关注我的新浪微博、了解DD博客的最新动态:DD博客官方微博(dwtedx的微博)

如对资源有任何疑问或觉得仍然有很大的改善空间、可以对该博文进行评论、希望不吝赐教

为保证及时回复、可以使用博客留言板给我留言: DD博客留言板(dwtedx的留言板)

感谢你的访问、祝你生活愉快、工作顺心、欢迎常来逛逛


快速评论


技术评论

  • 该技术还没有评论、赶快抢沙发吧...
DD记账
top
+