欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  技术分享

Android NFC开发MifareUltralight读写Demo实例下载

程序员文章站 2022-03-01 13:33:14
...

简介

基于这两天一直在研究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