读取NfcA格式数据

   如何读取数据?

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

   NfcA nfcA = NfcA.get(tag);
   nfcA.connect();

   byte[] SELECT = {(byte) 0x30, (byte) 0x05};//我读取的NFC卡片使用的是NTAG216的芯片,这里的指令参数是根据其datasheet的说明写的。

   byte[] result = nfcA.transceive(SELECT);//这里会返回16个字节的数据,根据芯片不同会有差异

   该芯片的快速读写命令是0x3A,可以指定读取页数范围,在使用快速读写命令时,发现读取范围超过70字节android就会报错,所以使用了每次最多读取64字节的方式。

 

   

package com.yorkg.android.nfc;

import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.util.ArrayList;
import java.util.Arrays;

import android.app.Activity;
import android.app.AlertDialog;
import android.app.PendingIntent;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.IntentFilter;
import android.nfc.NfcAdapter;
import android.nfc.Tag;
import android.nfc.tech.MifareClassic;
import android.nfc.tech.NfcA;
import android.os.Bundle;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.Window;
import android.widget.Button;
import android.widget.EditText;
import android.widget.Toast;


import com.yorkg.android.nfc.dataobject.mifare.MifareBlock;
import com.yorkg.android.nfc.dataobject.mifare.MifareClassCard;
import com.yorkg.android.nfc.dataobject.mifare.MifareSector;
import com.yorkg.android.nfc.util.Converter;

public class MyFirstNFCDemoActivity extends Activity {
	/** Called when the activity is first created. */
	
	private Button clearBtn = null;
	
	private EditText sealCompanyName = null;
	private EditText sealName = null;
	private EditText sealNumber = null;
	private EditText sealTaxId = null;
	private EditText sealCode = null;
	private EditText sealMaterial = null;
	private EditText sealSize = null;
	
	private EditText companyMadedName = null;
	private EditText companyMadedTime = null;
	
	private EditText companyCheckedName = null;

	private NfcAdapter mAdapter;
	private PendingIntent mPendingIntent;
	private IntentFilter[] mFilters;
	private String[][] mTechLists;
	
	private static final int AUTH = 1;
	private static final int EMPTY_BLOCK_0 = 2;
	private static final int EMPTY_BLOCK_1 = 3;
	private static final int NETWORK = 4;
	private static final int NFC_OFF = 5;
	private static final int NFC_TYPE_ERROR = 6;
	private static final String TAG = "NfcDemo";
	
	private static boolean READ_LOCK = false;
	
	
	private void initView(){
		sealCompanyName = (EditText) this.findViewById(R.id.edittext_seal_company_name);
		sealName = (EditText) this.findViewById(R.id.edittext_seal_name);
		sealNumber = (EditText) this.findViewById(R.id.edittext_seal_number);
		sealTaxId = (EditText) this.findViewById(R.id.edittext_tax_id);
		sealCode = (EditText) this.findViewById(R.id.edittext_code);
		sealMaterial = (EditText) this.findViewById(R.id.edittext_seal_material);
		sealSize = (EditText) this.findViewById(R.id.edittext_seal_size);
		
		companyMadedName = (EditText) this.findViewById(R.id.edittext_company_maded_name);
		companyMadedTime = (EditText) this.findViewById(R.id.edittext_company_maded_time);
		
		companyCheckedName = (EditText) this.findViewById(R.id.edittext_company_checked_name);
		
		clearBtn = (Button) this.findViewById(R.id.clear_btn);
		clearBtn.setOnClickListener(new OnClickListener() {
			
			@Override
			public void onClick(View v) {
				// TODO Auto-generated method stub
				cleanData();
			}
		});
	}
	
	//清除数据信息
	private void cleanData(){
		sealCompanyName.setText("");
		sealName.setText("");
		sealNumber.setText("");
		sealTaxId.setText("");
		sealCode.setText("");
		sealMaterial.setText("");
		sealSize.setText("");		
		companyMadedName.setText("");
		companyMadedTime.setText("");
		companyCheckedName.setText("");
	}
	
	
	@Override
	public void onCreate(Bundle savedState) {
		super.onCreate(savedState);
		requestWindowFeature(Window.FEATURE_NO_TITLE);
		setContentView(R.layout.main);	
		
		initView();
		
		mAdapter = NfcAdapter.getDefaultAdapter(this);
		mPendingIntent = PendingIntent.getActivity(this, 0, new Intent(this,getClass()).addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP), 0);

		// Setup an intent filter for all MIME based dispatches
		IntentFilter ndef = new IntentFilter(NfcAdapter.ACTION_TECH_DISCOVERED);
//		try {
//			ndef.addDataType("*/*");
//		} catch (MalformedMimeTypeException e) {
//			throw new RuntimeException("fail", e);
//		}
		mFilters = new IntentFilter[] { ndef, };
		mTechLists = new String[][] { new String[] { MifareClassic.class
				.getName() } , new String[] {NfcA.class.getName()}};

		//得到是否检测到ACTION_TECH_DISCOVERED触发  
		if (NfcAdapter.ACTION_TECH_DISCOVERED.equals(getIntent().getAction())) {  
			//处理该intent  
			resolveIntentNfcA(getIntent());
		} 
	}


	@Override
	public void onResume() {
		super.onResume();
		
		if (mAdapter!=null && (!mAdapter.isEnabled())) {  
			showAlert(NFC_OFF, getString(R.string.error5));
		} 
		
		if (mAdapter!=null) {
			mAdapter.enableForegroundDispatch(this, mPendingIntent, mFilters,
					mTechLists);
		}
		
		
	}

	@Override
	public void onNewIntent(Intent intent) {
		resolveIntentNfcA(intent);
	}

	@Override
	public void onPause() {
		super.onPause();
		if (mAdapter!=null){
			mAdapter.disableForegroundDispatch(this);
		}
	}
	void resolveIntentNfcA(Intent intent){
		if (READ_LOCK==false){
			READ_LOCK = true;
			Tag tag = intent.getParcelableExtra(NfcAdapter.EXTRA_TAG);

			if (NfcAdapter.ACTION_TECH_DISCOVERED.equals(intent.getAction()))
			{
			    Tag tagFromIntent = intent.getParcelableExtra(NfcAdapter.EXTRA_TAG);  
			    MyLog.i(TAG, Arrays.toString(tagFromIntent.getTechList()));
			    
			    try
			    {
			    	NfcA nfcA = NfcA.get(tag);
			    	nfcA.connect();
			        byte[] SELECT = { 
			        	(byte) 0x30,
			        	(byte) 0x05,
			        };

			        byte[] result = nfcA.transceive(SELECT);
			        int data_len = ((result[0]&0x0f)<<8)+((result[1]&0xff));
			        MyLog.i(TAG, "是否已写入数据"+result[0]+",写入数据长度:"+data_len);
			        byte[] buf_res = new byte[data_len/2+4];
			        if (result[0]!=0 && data_len!=0){
			        	int count = data_len/2/64;
			        	int i = 0;
			        	for (i=0; i<count; i++){
//			        	//读取数据
			        	byte[] DATA_READ = { 
					            (byte) 0x3A,
					            (byte) (0x06+i*(64/4)), 
					            (byte) (0x06+(i+1)*(64/4))
//					            (byte) (5+data_len/8)
					        };
			        	byte[] data_res = nfcA.transceive(DATA_READ);
			        	System.arraycopy(data_res, 0, buf_res, i*64, 64);
			        	MyLog.i(TAG, "读卡成功");
			        	}
			        	if (((data_len/2)%(64))!=0){
			        	byte[]DATA_READ = { 
					            (byte) 0x3A,
					            (byte) (0x06+i*(64/4)), 
					            (byte) (((0x06+i*(64/4))+(data_len/2/4)%(64/4))-1)
//					            (byte) (5+data_len/8)
					        };
			        	byte[] data_res = nfcA.transceive(DATA_READ);
			        	System.arraycopy(data_res, 0, buf_res, i*64, (data_len/2)%64);
			        	MyLog.i(TAG, "读卡成功2");
			        	}
						String res = gb2312ToString(buf_res);
						MyLog.i(TAG, "stringBytes:"+res);
						showNFCInfo(res);
			        }
			        

			    }catch(IOException e){
			    	e.printStackTrace();
			    	cleanData();
			    	MyLog.e(TAG, "读卡失败");
			    }catch (Exception e) {
					// TODO: handle exception
			    	e.printStackTrace();
			    	showAlert(NFC_TYPE_ERROR, getString(R.string.error6));
				}finally{
			    	
			    }
			    
			}
			READ_LOCK = false;
		}
	}

	
	//将数据转换为GB2312
	private String gb2312ToString(byte[] data) {
	    String str = null;
	    try {
	           str = new String(data, "gb2312");//"utf-8"
	    } catch (UnsupportedEncodingException e) {
	    }   
	    return str;
	 }
	
	//将字符串解析显示到页面
	private void showNFCInfo(String str){
		String[] contents_temp = str.split("\\|");
		String[] contents = new String[contents_temp.length];
		
		int i;
		
		for (i = 0; i < contents_temp.length; i++) {
			contents[i]=contents_temp[i];
		}
		//目前有10项,所以这里只初始化到第10项
		for (int j=i; j<10; j++){
			contents[j]="";
		}
		
		if (contents[0]!=null){
			sealCompanyName.setText(contents[0]);
		}
		if (contents[1]!=null){
			sealName.setText(contents[1]);
		}
		if (contents[2]!=null){
			sealNumber.setText(contents[2]);
		}
		
		if (contents[3]!=null){
			sealTaxId.setText(contents[3]);
		}
		
		if (contents[4]!=null){
			sealCode.setText(contents[4]);
		}
		
		if (contents[5]!=null){
			sealMaterial.setText(contents[5]);
		}
		if (contents[6]!=null){
			sealSize.setText(contents[6]);
		}
		
		if (contents[7]!=null){
			companyMadedName.setText(contents[7]);
		}
		if (contents[8]!=null){
			companyMadedTime.setText(contents[8]);
		}
		
		if (contents[9]!=null){
			companyCheckedName.setText(contents[9]);
		}	
		
		
		
	}


	private void showAlert(int alertCase,String str) {
		// prepare the alert box
		AlertDialog.Builder alertbox = new AlertDialog.Builder(this);
		switch (alertCase) {

		case AUTH:// Card Authentication Error
			alertbox.setMessage(getString(R.string.error1));
			break;
		case EMPTY_BLOCK_0: // Block 0 Empty
			alertbox.setMessage(getString(R.string.error2));
			break;
		case EMPTY_BLOCK_1:// Block 1 Empty
			alertbox.setMessage(getString(R.string.error3));
			break;
		case NETWORK: // Communication Error
			alertbox.setMessage(getString(R.string.error4));
			break;
		case NFC_OFF:
			alertbox.setMessage(getString(R.string.error5));
			break;
		case NFC_TYPE_ERROR:
			alertbox.setMessage(getString(R.string.error6));
		}
		// set a positive/yes button and create a listener
		alertbox.setPositiveButton("OK", new DialogInterface.OnClickListener() {

			// Save the data from the UI to the database - already done
			public void onClick(DialogInterface arg0, int arg1) {
				clearFields();
			}
		});
		// display box
		alertbox.show();

	}
	
	private void clearFields() {
		

	}
}

 

  

  

posted @ 2015-04-20 18:07  苏小七  阅读(7445)  评论(3编辑  收藏  举报