如何读取数据?
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() { } }