android使用NFC的读模式

NFC读模式工作流程:NFC芯片轮询执行读模式、点对点和卡模式,当把卡片靠近手机的NFC天线的时候,NFC会识别到卡,然后
把卡对象装到intent里面,并发送广播NfcAdapter.ACTION_TECH_DISCOVERED,应用程序接到这个广播之后,通过
intent.getParcelableExtra(NfcAdapter.EXTRA_TAG)来获取到卡对象,然后就可以对卡进行读写。

了解这个之后,我们就可以写自己的应用了。

两个步骤完成:

1.注册接受广播和过滤器

用静态的方式,在AndroidManifest.xml注册,这样子activity不在运行状态的时候也可以接受到广播。

<activity
	android:name="nfc.read.test.main"
	android:screenOrientation="portrait"
	android:label="@string/app_name" >
	<intent-filter>
		<action android:name="android.intent.action.MAIN" />
                <category android:name="android.intent.category.LAUNCHER" />
	</intent-filter>
	<intent-filter>
                <action android:name="android.nfc.action.TECH_DISCOVERED" />
	</intent-filter>
	<meta-data android:name="android.nfc.action.TECH_DISCOVERED"
				android:resource="@xml/nfc_tech_filter" />
	<intent-filter>
		<action android:name="android.nfc.action.TAG_DISCOVERED" />
		<category android:name="android.intent.category.DEFAULT" />
	</intent-filter>
</activity>

nfc_tech_filter.xml是过滤器,过滤哪些卡片

<?xml version="1.0" encoding="utf-8"?>
<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
	<tech-list>
		<tech>android.nfc.tech.IsoDep</tech>
	</tech-list>
	<tech-list>
		<tech>android.nfc.tech.NfcV</tech>
	</tech-list>
	<tech-list>
		<tech>android.nfc.tech.NfcF</tech>
	</tech-list>
</resources>
2.处理接收到的广播
继承activity的方法public void onNewIntent(Intent intent);
用Tag tag = intent.getParcelableExtra(NfcAdapter.EXTRA_TAG);获取到tag,
把tag转换为IsoDep isodep = IsoDep.get(tag);
也可以把tag转换为MifareClassic mfc = MifareClassic.get(tag);
这个根据读到的tag类型的转换,tag的类型有很多,饭卡门禁卡这些一般是MifareClassic,非接触银行卡公交卡这些一般是IsoDep。
举个例子,下面是读取深圳通卡的余额:

@Override
public void onNewIntent(Intent intent) {
	super.onNewIntent(intent);		
	// 1) Parse the intent and get the action that triggered this intent
	String action = intent.getAction();
	Log.d(TAG, "Discovered tag with intent: " + action);
	// 2) Check if it was triggered by a tag discovered interruption.
	if (NfcAdapter.ACTION_TECH_DISCOVERED.equals(action)) {
		// 3) Get an instance of the TAG from the NfcAdapter
		Tag tagFromIntent = intent.getParcelableExtra(NfcAdapter.EXTRA_TAG);			
		try
		{
			//Get an instance of the type A card from this TAG
			IsoDep isodep = IsoDep.get(tagFromIntent);
			isodep.connect();
			//select the card manager applet
			byte[] mf = { (byte) '1', (byte) 'P',
					(byte) 'A', (byte) 'Y', (byte) '.', (byte) 'S', (byte) 'Y',
					(byte) 'S', (byte) '.', (byte) 'D', (byte) 'D', (byte) 'F',
					(byte) '0', (byte) '1', };
			byte[] mfRsp = isodep.transceive(getSelectCommand(mf));
			Log.d(TAG, "mfRsp:" + HexToString(mfRsp));
			//select Main Application
			byte[] szt = { (byte) 'P', (byte) 'A', (byte) 'Y',
					(byte) '.', (byte) 'S', (byte) 'Z', (byte) 'T' };
			byte[] sztRsp = isodep.transceive(getSelectCommand(szt));
			Log.d(TAG, "sztRsp:" + HexToString(sztRsp));
	            
			byte[] balance = { (byte) 0x80, (byte) 0x5C, 0x00, 0x02, 0x04};
			byte[] balanceRsp = isodep.transceive(balance);
			Log.d(TAG, "balanceRsp:" + HexToString(balanceRsp));
			if(balanceRsp!=null && balanceRsp.length>4)
			{
	            		int cash = byteToInt(balanceRsp, 4);	            	
	            		float ba = cash / 100.0f;
	            		EditText result = (EditText) findViewById(R.id.block4);
				result.setText("Balance:"+ba);
			}	            
	            isodep.close();
		}catch(Exception e)
		{
			Log.e(TAG, "ERROR:" + e.getMessage());
		}
	}
}
下面是读取MifareClassic的例子,使用的是默认密钥:

@Override
public void onNewIntent(Intent intent) {
	super.onNewIntent(intent);		
	// 1) Parse the intent and get the action that triggered this intent
	String action = intent.getAction();
	Log.d(TAG, "Discovered tag with intent: " + action);
	// 2) Check if it was triggered by a tag discovered interruption.
	if (NfcAdapter.ACTION_TECH_DISCOVERED.equals(action)) {
		// 3) Get an instance of the TAG from the NfcAdapter
		Tag tagFromIntent = intent.getParcelableExtra(NfcAdapter.EXTRA_TAG);	
		try {
			//Get an instance of the Mifare classic card from this TAG
			MifareClassic mfc = MifareClassic.get(tagFromIntent);
			mfc.connect();
			Log.d(TAG, "sectorCount=" + mfc.getSectorCount());

			int block = 4;
			EditText result = (EditText) findViewById(R.id.block4);
			//use default key to authenticate
			boolean auth = mfc.authenticateSectorWithKeyA(block / 4, MifareClassic.KEY_DEFAULT);
			if (auth) 
			{
				// read block
				if (FunctionFlag == 0) 
				{
					byte[] data = mfc.readBlock(block);
					result.setText(HexToString(data));
				}
				// write block
				else if (FunctionFlag == 1) 
				{
					byte[] data = StringToHex(result.getText().toString());
					mfc.writeBlock(block, data);
				}
			}
			mfc.close();
		} catch (Exception e) {
			Log.e(TAG, "ERROR:" + e.getMessage());
		}
	}
}

记得添加NFC的权限
<uses-permission android:name="android.permission.NFC" />
源码下载地址,百度网盘:
链接: http://pan.baidu.com/s/1Ectjo 密码: n3mk

评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值