Android NFC标签读写 配置 过滤器总结 各类NFC数据类型NfcA NfcB IsoDep MifareClassic读取

NFC简介

NFC,即Near Field Communication,近距离无线通讯技术,是一种短距离的(通常<=4cm或更短)高频(13.56M Hz)无线通信技术,它提供了一种简单、触控式的解决方案,可以让消费者简单直观地交换信息、访问内容与服务。

NFC技术由非接触式射频识别(RFID)演变而来,由飞利浦半导体(现恩智浦半导体公司)、诺基亚和索尼共同研制开发,其基础是RFID及互连技术。近场通信(Near Field Communication,NFC)是一种短距高频的无线电技术,在单一芯片上结合感应式读卡器、感应式卡片和点对点的功能,能在13.56MHz频率运行于4厘米距离内,与兼容设备进行识别和数据交换。其传输速度有106 Kbit/秒、212 Kbit/秒或者424 Kbit/秒三种。目前近场通信已通过成为ISO/IEC IS 18092国际标准、ECMA-340标准与ETSI TS 102 190标准。现今这项技术在日韩被广泛应用。手机用户凭着配置了支付功能的手机就可以行遍全国:他们的手机可以用作机场登机验证、大厦的门禁钥匙、交通一卡通、信用卡、支付卡等等。

                                                                      Android NFC标签读写 配置 过滤器总结 各类NFC数据类型NfcA NfcB IsoDep MifareClassic读取_第1张图片 

NFC标签的复杂度不一。简单的标签仅能够提供读写语义,有时编程域是一次性的,写完卡片就变成只读。更复杂一点的tag能够提供数学运算,拥有加密硬件保护区块的访问。最最复杂的tag包含操作环境,允许tag上执行的代码进行交互。我们还能够以各种格式来向tag中写入存储数据,但很多Android的API框架都是基于NFC论坛制定的NDEF标准。

AndroidManifest.xml

为了能够使用Android手机的NFC功能,需要在Manifest文件中添加相应的权限:

使用元素允许设备访问NFC硬件:

使用元素设置最小SDK版本,下面是基于android 4.0环境,因此声明如下:

下面这项不一定需要,如果你希望你的软件可以在android market中显示有NFC硬件,可以使用元素声明:

NFC数据过滤

NFC有三种过滤器分别是ACTION_NDEF_DISCOVERED,ACTION_TECH_DISCOVERED,ACTION_TAG_DISCOVERED。

1. ACTION_NDEF_DISCOVERED

当扫描到的tag中包含有NDEF载荷且为已知类型,该intent将用来启动Activity。该intent的优先级最高,tag分发系统总是先于其他intent用该intent来启动Activity。

2. ACTION_TECH_DISCOVERED

如果manifest中没有注册处理ACTION_NDEF_DISCOVERED类型的intent,该intent将被用以启动Activity。如果tag中没有包含可以映射到MIME或者URI类型的数据,或者虽然没有包含NDEF数据,但是已知的tag技术,则该intent也会被直接启用。

3. ACTION_TAG_DISCOVERED

如果以上两个intent都没人疼,那么该intent就会启动。

过滤器的作用是过滤掉杂质,剩下的就是我们需要的了。这三种过滤方式可同时配置,可以比方成从上到下三层,只要是符合某一层过滤器要求的,过滤完就停止往下一层。

                       Android NFC标签读写 配置 过滤器总结 各类NFC数据类型NfcA NfcB IsoDep MifareClassic读取_第2张图片

NFC TAG的发布系统:

当android设备扫描到一个NFC标签时,会自动寻找最适合的Activity来处理这个TAG,如果有多个Activity满足条件的话,会让用户来选择到底使用哪一个Activity来处理,可以理解为就是简单的事件响应与事件处理。

那么如何让一个Activity监听 ”当扫描到NFC标签时” 的这一个事件呢?使用intent-filter。

可以理解为当检测到一个NFC标签时系统自动创建一个相关Intent对象,含有响应intent-filter的Activity将处理这个Intent。

1.ACTION_NDEF_DISCOVERED过滤器定义如下:


                
                
                

下面是能够筛选URI为http://developer.android.com/index.html的ACTION_NDEF_DISCOVERED过滤器。


                
                
                


                
                
                

2.ACTION_TECH_DISCOVERED过滤器定义如下:


            

            

在res下新建xml文件夹然后新建一个nfc_tech_filter.xml文件,添加进你需要支持的标签类型。


    
    
    android.nfc.tech.IsoDep
    
    
    android.nfc.tech.NfcA
    
    
    android.nfc.tech.NfcB
    
    
    android.nfc.tech.NfcF
    
    
    android.nfc.tech.NfcV
    
    
    android.nfc.tech.Ndef
    
    
    android.nfc.tech.NdefFormatable
    
    
    android.nfc.tech.MifareUltralight
    
    
    android.nfc.tech.MifareClassic
    

不同数据标签类型什么意思:

MIFARE Classic数据格式就是NfcA,MIFARE DESFire数据格式是IsoDep就是各种交通卡像武汉通,羊城通,深圳通,北京市政交通卡,长安通,我们使用的二代身份证用的就是NfcB,Felica用的就是NfcF,德州仪器的VicinityCard卡用的是NfcV,而Android分享文件就是实用的Ndef格式传输数据。

3.ACTION_TAG_DISCOVERED过滤器定义如下:


    

各类NFC数据读取

1.NDEF格式数据读取

@Override 
protected void onCreate(Bundle savedInstanceState) { 
  	super.onCreate(savedInstanceState); 
  	setContentView(R.layout.activity_write); 
  	nfcTView=(TextView)findViewById(R.id.info_tv); 
  	nfcAdapter = NfcAdapter.getDefaultAdapter(this); 
  	if (nfcAdapter == null) { 
   		 nfcTView.setText("设备不支持NFC!"); 
    		inish(); 
    		return; 
 	 } 
 	 if (nfcAdapter!=null&&!nfcAdapter.isEnabled()) { 
    		nfcTView.setText("请在系统设置中先启用NFC功能!"); 
    		finish(); 
    		return; 
 	 } 
} 
@Override 
protected void onResume() { 
  	super.onResume(); 
  	if (NfcAdapter.ACTION_NDEF_DISCOVERED.equals(getIntent().getAction())) { 
    		readFromTag(getIntent()); 
  	} 
} 

//读取内容:
private boolean readFromTag(Intent intent){ 
  	Parcelable[] rawArray = intent.getParcelableArrayExtra(NfcAdapter.EXTRA_NDEF_MESSAGES); 
  	NdefMessage mNdefMsg = (NdefMessage)rawArray[0]; 
  	NdefRecord mNdefRecord = mNdefMsg.getRecords()[0]; 
  	try { 
    		if(mNdefRecord != null){ 
      			readResult = new String(mNdefRecord.getPayload(),"UTF-8"); 
      			return true; 
    		 } 
  	} 
  	catch (UnsupportedEncodingException e) { 
    	e.printStackTrace(); 
 	}; 
  	return false; 
} 

//写入内容
@Override 
protected void onResume() { 
  	super.onResume(); 
  	if (NfcAdapter.ACTION_NDEF_DISCOVERED.equals(getIntent().getAction())) { 
   		Tag tag=getIntent().getParcelableExtra(NfcAdapter.EXTRA_TAG); 
   		Ndef ndef=Ndef.get(tag); 
    	try { 
     		ndef.connect(); 
      		NdefRecord ndefRecord=createTextRecord(data,Locale.US,true); 
      		NdefRecord[] records={ndefRecord}; 
      		NdefMessage ndefMessage=new NdefMessage(records); 
      		ndef.writeNdefMessage(ndefMessage); 
    	} catch (IOException e1) { 
      		e1.printStackTrace(); 
    	} catch (FormatException e) { 
      		   
      		   
      		e.printStackTrace(); 
    }
} 

2.非NDEF数据MifareUltralight读取:

public String readTagUltralight(Tag tag) {
		MifareUltralight mifare = MifareUltralight.get(tag);
		try {
			mifare.connect();
			int size=mifare.PAGE_SIZE;
			byte[] payload = mifare.readPages(0);
			String result="page1:"+ByteArrayToHexString(payload)+"\n"+"总容量:"+String.valueOf(size)+"\n";
            //这里只读取了其中几个page
			byte[] payload1 = mifare.readPages(4);
			byte[] payload2 = mifare.readPages(8);
			byte[] payload3 = mifare.readPages(12);
result+="page4:"+ByteArrayToHexString(payload1)+"\npage8:"+ByteArrayToHexString(payload2)+"\npage12:"+ByteArrayToHexString(payload3)+"\n";
            //byte[] payload4 = mifare.readPages(16);
			//byte[] payload5 = mifare.readPages(20);
			return result;
			//+ new String(payload4, Charset.forName("US-ASCII"));
			//+ new String(payload5, Charset.forName("US-ASCII"));
		} catch (IOException e) {
			Log.e(TAG, "IOException while writing MifareUltralight message...",
					e);
			return "读取失败!";
		} catch (Exception ee) {
			Log.e(TAG, "IOException while writing MifareUltralight message...",
					ee);
			return "读取失败!";
		} finally {
			if (mifare != null) {
				try {
					mifare.close();
				} catch (IOException e) {
					Log.e(TAG, "Error closing tag...", e);
				}
			}
		}
}

3.非NDEF数据MifareClassic读取:

public class NFCActivity extends Activity {
	NfcAdapter nfcAdapter;
	TextView promt;
	private PendingIntent pi;
	@Override
	public void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.nfc_info);
		promt = (TextView) findViewById(R.id.promt);
		// 获取默认的NFC控制器
		nfcAdapter = NfcAdapter.getDefaultAdapter(this);
		pi = PendingIntent.getActivity(this, 0, new Intent(this, getClass()).addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP), 0);
		if (nfcAdapter == null) {
			Toast.makeText(this, "对不起,您的设备不支持nfc功能!", Toast.LENGTH_SHORT).show();
			//promt.setText("设备不支持NFC!");
			finish();
			return;
		}
		if (!nfcAdapter.isEnabled()) {
			Toast.makeText(this, "请在系统设置中开启NFC功能!", Toast.LENGTH_SHORT).show();
			//promt.setText("请在系统设置中先启用NFC功能!");
			finish();
			return;
		}
	}

	public void btn_back(View view){
		this.finish();
	}
	
	@Override
	  protected void onNewIntent(Intent intent) {
	    super.onNewIntent(intent);
	    // 当前app正在前端界面运行,这个时候有intent发送过来,那么系统就会调用onNewIntent回调方法,将intent传送过来
	    // 我们只需要在这里检验这个intent是否是NFC相关的intent,如果是,就调用处理方法
	    if (NfcAdapter.ACTION_TAG_DISCOVERED.equals(intent.getAction())) {
	      processIntent(intent);
	    }
	  }

	  @Override
	  protected void onResume() {
	    super.onResume();
	    nfcAdapter.enableForegroundDispatch(this, pi, null, null);
	  }
	/*@Override
	protected void onResume() {
		super.onResume();
		//得到是否检测到ACTION_TECH_DISCOVERED触发
		if (NfcAdapter.ACTION_TAG_DISCOVERED.equals(getIntent().getAction())) {
			//处理该intent
			processIntent(getIntent());
		}
	}*/
	//字符序列转换为16进制字符串
	private String bytesToHexString(byte[] src) {
		StringBuilder stringBuilder = new StringBuilder("0x");
		if (src == null || src.length <= 0) {
			return null;
		}
		char[] buffer = new char[2];
		for (int i = 0; i < src.length; i++) {
			buffer[0] = Character.forDigit((src[i] >>> 4) & 0x0F, 16);
			buffer[1] = Character.forDigit(src[i] & 0x0F, 16);
			System.out.println(buffer);
			stringBuilder.append(buffer);
		}
		return stringBuilder.toString();
	}
	private String ByteArrayToHexString(byte[] inarray) {
	    int i, j, in;
	    String[] hex = { "0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "A",
	        "B", "C", "D", "E", "F" };
	    String out = "";
	    for (j = 0; j < inarray.length; ++j) {
	      in = (int) inarray[j] & 0xff;
	      i = (in >> 4) & 0x0f;
	      out += hex[i];
	      i = in & 0x0f;
	      out += hex[i];
	    }
	    return out;
	  }
	/**
	 * Parses the NDEF Message from the intent and prints to the TextView
	 */
	private void processIntent(Intent intent) {
		//取出封装在intent中的TAG
		Tag tagFromIntent = intent.getParcelableExtra(NfcAdapter.EXTRA_TAG);
		String CardId =ByteArrayToHexString(tagFromIntent.getId());
		String metaInfo = "";
		metaInfo+="卡片ID:"+CardId;
		for (String tech : tagFromIntent.getTechList()) {
			System.out.println(tech);
		}
		boolean auth = false;
		//读取TAG
		MifareClassic mfc = MifareClassic.get(tagFromIntent);
		try {
			//Enable I/O operations to the tag from this TagTechnology object.
			mfc.connect();
			int type = mfc.getType();//获取TAG的类型
			int sectorCount = mfc.getSectorCount();//获取TAG中包含的扇区数
			String typeS = "";
			switch (type) {
			case MifareClassic.TYPE_CLASSIC:
				typeS = "TYPE_CLASSIC";
				break;
			case MifareClassic.TYPE_PLUS:
				typeS = "TYPE_PLUS";
				break;
			case MifareClassic.TYPE_PRO:
				typeS = "TYPE_PRO";
				break;
			case MifareClassic.TYPE_UNKNOWN:
				typeS = "TYPE_UNKNOWN";
				break;
			}
			metaInfo += "\n卡片类型:" + typeS + "\n共" + sectorCount + "个扇区\n共"
					+ mfc.getBlockCount() + "个块\n存储空间: " + mfc.getSize() + "B\n";
			for (int j = 0; j < sectorCount; j++) {
				//Authenticate a sector with key A.
				auth = mfc.authenticateSectorWithKeyA(j,
						MifareClassic.KEY_DEFAULT);
				int bCount;
				int bIndex;
				if (auth) {
					metaInfo += "Sector " + j + ":验证成功\n";
					// 读取扇区中的块
					bCount = mfc.getBlockCountInSector(j);
					bIndex = mfc.sectorToBlock(j);
					for (int i = 0; i < bCount; i++) {
						byte[] data = mfc.readBlock(bIndex);
						metaInfo += "Block " + bIndex + " : "
								+ bytesToHexString(data) + "\n";
						bIndex++;
					}
				} else {
					metaInfo += "Sector " + j + ":验证失败\n";
				}
			}
			promt.setText(metaInfo);
			//Toast.makeText(this, metaInfo, Toast.LENGTH_SHORT).show();
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
}

4.非NDEF数据IsoDep读取:

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', };
	                String result="";
					byte[] mfRsp = isodep.transceive(getSelectCommand(mf));
					Log.d(TAG, "mfRsp:" + HexToString(mfRsp));
					//select Main Application
					byte[] wht = { (byte) 0x41, (byte) 0x50,
                    //此处以武汉通为例,其它的卡片参考对应的命令,网上可以查到
					(byte) 0x31, (byte) 0x2E, (byte) 0x57, (byte) 0x48, (byte) 0x43,
					(byte) 0x54, (byte) 0x43, };
		            byte[] sztRsp = isodep.transceive(getSelectCommand(wht));
		            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;
		            	result+="  余额:"+String.valueOf(ba);
		            	 
		            }
		            setNoteBody(result); 
		            isodep.close();               

完整代码以厦门公交卡为例

package com.example.nfcdemo;

import java.io.IOException;
import java.nio.ByteBuffer;
import java.util.ArrayList;
import java.util.List;

import android.support.v7.app.ActionBarActivity;
import android.app.PendingIntent;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.IntentFilter.MalformedMimeTypeException;
import android.nfc.NfcAdapter;
import android.nfc.Tag;
import android.nfc.tech.IsoDep;
import android.nfc.tech.NfcF;
import android.nfc.tech.NfcV;
import android.os.Bundle;
import android.util.Log;
import android.widget.TextView;
import android.widget.Toast;
import com.example.nfcdemo2.R;

public class MainActivity extends ActionBarActivity {

    private NfcAdapter nfcAdapter; // NFC适配器
    // NFC前台调度系统
    private PendingIntent pendingIntent = null;
    private TextView show_msg; // 显示数据
    protected final static byte TRANS_CSU = 6; // 如果等于0x06或者0x09,表示刷卡;否则是充值
    protected final static byte TRANS_CSU_CPX = 9; // 如果等于0x06或者0x09,表示刷卡;否则是充值
    public String[][] tenchlists;
    public IntentFilter[] filters;

    @SuppressWarnings("unchecked")
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        show_msg = (TextView) findViewById(R.id.show_msg);
        tenchlists = new String[][] { { IsoDep.class.getName() }, { NfcV.class.getName() }, { NfcF.class.getName() }, };

        try {
            filters = new IntentFilter[] { new IntentFilter(NfcAdapter.ACTION_TECH_DISCOVERED, "*/*") };
        } catch (MalformedMimeTypeException e1) {
            e1.printStackTrace();
        }
        // 初始化PendingIntent,当有NFC设备连接上的时候,就交给当前Activity处理
        pendingIntent = PendingIntent.getActivity(this, 0, new Intent(this, getClass()).addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP), 0);
        // 获取默认的NFC控制器,并进行判断
        nfcAdapter = NfcAdapter.getDefaultAdapter(this);
        if (nfcAdapter == null) {
            Log.d("h_bl", "设备不支持NFC!");
            finish();
            return;
        }
        if (!nfcAdapter.isEnabled()) {
            Toast.makeText(getApplicationContext(), "请在系统设置中先启用NFC功能!", Toast.LENGTH_SHORT).show();
            Log.d("h_bl", "请在系统设置中先启用NFC功能!");
            return;
        }
        Intent intent = this.getIntent(); // 捕获NFC Intent
        praseIntent(intent);
    }

    private void praseIntent(Intent intent) {

        String nfcAction = intent.getAction(); // 解析该Intent的Action
        if (NfcAdapter.ACTION_TECH_DISCOVERED.equals(nfcAction)) {
            Log.d("h_bl", "ACTION_TECH_DISCOVERED");
            Tag tag = intent.getParcelableExtra(NfcAdapter.EXTRA_TAG); // 获取Tag标签,既可以处理相关信息
            for (String tech : tag.getTechList()) {
                Log.d("h_bl", "tech=" + tech);
            }
            IsoDep isoDep = IsoDep.get(tag);
            String str = "";
            try {
                isoDep.connect(); // 连接
                if (isoDep.isConnected()) {
                    Log.d("h_bl", "isoDep.isConnected"); // 判断是否连接上
                    // 1.select PSF (1PAY.SYS.DDF01)
                    // 选择支付系统文件,它的名字是1PAY.SYS.DDF01。
                    byte[] DFN_PSE = { (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', };
                    isoDep.transceive(getSelectCommand(DFN_PSE));
                    // 2.选择公交卡应用的名称
                    byte[] DFN_SRV = { (byte) 0xA0, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x03, (byte) 0x86, (byte) 0x98, (byte) 0x07, (byte) 0x01, };
                    isoDep.transceive(getSelectCommand(DFN_SRV));
                    // 3.读取余额
                    byte[] ReadMoney = { (byte) 0x80, // CLA Class
                            (byte) 0x5C, // INS Instruction
                            (byte) 0x00, // P1 Parameter 1
                            (byte) 0x02, // P2 Parameter 2
                            (byte) 0x04, // Le
                    };
                    byte[] Money = isoDep.transceive(ReadMoney);
                    if (Money != null && Money.length > 4) {
                        int cash = byteToInt(Money, 4);
                        float ba = cash / 100.0f;
                        show_msg.setText("余额:" + ba);
                    }
                    // 4.读取所有交易记录
                    byte[] ReadRecord = { (byte) 0x00, // CLA Class
                            (byte) 0xB2, // INS Instruction
                            (byte) 0x01, // P1 Parameter 1
                            (byte) 0xC5, // P2 Parameter 2
                            (byte) 0x00, // Le
                    };
                    byte[] Records = isoDep.transceive(ReadRecord);
                    // 处理Record
                    Log.d("h_bl", "总消费记录" + Records);
                    ArrayList ret = parseRecords(Records);
                    List retList = parseRecordsToStrings(ret);
                    show_msg.append("\n" + "消费记录如下:");
                    for (String string : retList) {
                        Log.d("h_bl", "消费记录" + string);
                        show_msg.append("\n" + string);
                    }

                }
            } catch (IOException e) {
                e.printStackTrace();
            } finally {
                if (isoDep != null) {
                    try {
                        isoDep.close();
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                }
            }
        }
    }

    @Override
    protected void onPause() {
        if (nfcAdapter != null)
            nfcAdapter.disableForegroundDispatch(this);
        super.onPause();
    }

    @Override
    protected void onResume() {
        super.onResume();
        nfcAdapter.enableForegroundDispatch(this, pendingIntent, filters, tenchlists);
    }

    @Override
    protected void onNewIntent(Intent intent) {
        super.onNewIntent(intent);
        // 当前app正在前端界面运行,这个时候有intent发送过来,那么系统就会调用onNewIntent回调方法,将intent传送过来
        // 我们只需要在这里检验这个intent是否是NFC相关的intent,如果是,就调用处理方法
        if (NfcAdapter.ACTION_TECH_DISCOVERED.equals(intent.getAction())) {
            Log.d("h_bl", "onNewIntent");
            praseIntent(intent);
        }

    }

    public static byte byteToHex(byte arg) {
        byte hex = 0;
        if (arg >= 48 && arg <= 57) {
            hex = (byte) (arg - 48);
        } else if (arg >= 65 && arg <= 70) {
            hex = (byte) (arg - 55);
        } else if (arg >= 97 && arg <= 102) {
            hex = (byte) (arg - 87);
        }
        return hex;
    }

    private byte[] getSelectCommand(byte[] aid) {
        final ByteBuffer cmd_pse = ByteBuffer.allocate(aid.length + 6);
        cmd_pse.put((byte) 0x00) // CLA Class
                .put((byte) 0xA4) // INS Instruction
                .put((byte) 0x04) // P1 Parameter 1
                .put((byte) 0x00) // P2 Parameter 2
                .put((byte) aid.length) // Lc
                .put(aid).put((byte) 0x00); // Le
        return cmd_pse.array();
    }

    /**
     * 整条Records解析成ArrayList
     * 
     * @param Records
     * @return
     */
    private ArrayList parseRecords(byte[] Records) {
        int max = Records.length / 23;
        Log.d("h_bl", "消费记录有" + max + "条");
        ArrayList ret = new ArrayList();
        for (int i = 0; i < max; i++) {
            byte[] aRecord = new byte[23];
            for (int j = 23 * i, k = 0; j < 23 * (i + 1); j++, k++) {
                aRecord[k] = Records[j];
            }
            ret.add(aRecord);
        }
        for (byte[] bs : ret) {
            Log.d("h_bl", "消费记录有byte[]" + bs); // 有数据。解析正确。
        }
        return ret;
    }

    /**
     * ArrayList记录分析List 一条记录是23个字节byte[] data,对其解码如下
     * data[0]-data[1]:index data[2]-data[4]:over,金额溢出??? data[5]-data[8]:交易金额
     * ??代码应该是(5,4) data[9]:如果等于0x06或者0x09,表示刷卡;否则是充值
     * data[10]-data[15]:刷卡机或充值机编号
     * data[16]-data[22]:日期String.format("%02X%02X.%02X.%02X %02X:%02X:%02X"
     * ,data[16], data[17], data[18], data[19], data[20], data[21], data[22]);
     * 
     * @param logs
     * @return
     */
    private List parseRecordsToStrings(ArrayList... Records) {
        List recordsList = new ArrayList();
        for (ArrayList record : Records) {
            if (record == null)
                continue;
            for (byte[] v : record) {
                StringBuilder r = new StringBuilder();
                int cash = Util.toInt(v, 5, 4);
                char t = (v[9] == TRANS_CSU || v[9] == TRANS_CSU_CPX) ? '-' : '+';
                r.append(String.format("%02X%02X.%02X.%02X %02X:%02X ", v[16], v[17], v[18], v[19], v[20], v[21], v[22]));
                r.append("   " + t).append(Util.toAmountString(cash / 100.0f));
                String aLog = r.toString();
                recordsList.add(aLog);
            }
        }
        return recordsList;
    }

    // byteArray转化为int
    private int byteToInt(byte[] b, int n) {
        int ret = 0;
        for (int i = 0; i < n; i++) {
            ret = ret << 8;
            ret |= b[i] & 0x00FF;
        }
        if (ret > 100000 || ret < -100000)
            ret -= 0x80000000;
        return ret;
    }

}

IsoDep主要用于读取各城市公交卡信息如:武汉通,羊城通,深圳通,北京市政交通卡,长安通。

深圳通:
byte[] DFN_SRV = { (byte) 'P', (byte) 'A', (byte) 'Y',
(byte) '.', (byte) 'S', (byte) 'Z', (byte) 'T' };
武汉通:
byte[] DFN_SRV = { (byte) 0x41, (byte) 0x50,
(byte) 0x31, (byte) 0x2E, (byte) 0x57, (byte) 0x48, (byte) 0x43,
(byte) 0x54, (byte) 0x43, };
羊城通:
byte[] DFN_SRV = { (byte) 'P', (byte) 'A', (byte) 'Y',
(byte) '.', (byte) 'A', (byte) 'P', (byte) 'P', (byte) 'Y', };
长安通:
byte[] DFN_SRV = { (byte) 0xA0, (byte) 0x00,
(byte) 0x00, (byte) 0x00, (byte) 0x03, (byte) 0x86, (byte) 0x98,
(byte) 0x07, (byte) 0x01, };
北京市政交通卡:
byte[] DFI_EP = { (byte) 0x10, (byte) 0x01 };

5.非NDEF数据NfcA读取:

 NfcA nfca = NfcA.get(tagFromIntent);
           try{
               nfca.connect();
               if (nfca.isConnected()) {//NTAG216的芯片
               byte[] SELECT = {
                       (byte) 0x30,
                       (byte) 5 & 0x0ff,//0x05
                   };
               byte[] response = nfca.transceive(SELECT);
               nfca.close();
               if(response!=null){
               setNoteBody(new String(response, Charset.forName("utf-8")));
               }
               }
           }
           catch(Exception e){
}

6.非NDEF数据NfcB读取:

nfcbTag = NfcB.get(tag);
try {
     nfcbTag.connect();
     if (nfcbTag.isConnected()) {
	   System.out.println("已连接");
	   Toast.makeText(MainActivity.this, "身份证已连接",Toast.LENGTH_SHORT).show();
	   new CommandAsyncTask().execute();
 
     }
     // nfcbTag.close();
     } catch (IOException e) {
     // TODO Auto-generated catch block
     e.printStackTrace();
}

7.非NDEF数据NfcF读取:

NfcF nfc = NfcF.get(tag);
           try {
               nfc.connect();
               byte[] felicaIDm = new byte[]{0};
               byte[] req = readWithoutEncryption(felicaIDm, 10);
               byte[] res = nfc.transceive(req);
               nfc.close();
               setNoteBody(ByteArrayToHexString(res));
           } catch (Exception e) {
               Log.e(TAG, e.getMessage() , e);
           }

8.非NDEF数据NfcV读取:

NfcV tech = NfcV.get(tag);
    	    if (tech != null) {
    	    	try {
    	    		tech.connect();
                    if (tech.isConnected()) {
                    	byte[] tagUid = tag.getId(); 
                    	int blockAddress = 0;
                    	int blocknum = 4;
                    	byte[] cmd = new byte[] {
                    	        (byte)0x22,  // FLAGS
                    	        (byte)0x23,  // 20-READ_SINGLE_BLOCK,23-所有块
                    	        0, 0, 0, 0, 0, 0, 0,0,
                    	        (byte)(blockAddress & 0x0ff),(byte)(blocknum-1 & 0x0ff)
                    	};
                    	System.arraycopy(tagUid, 0, cmd, 2, tagUid.length);   
                    	byte[] response = tech.transceive(cmd);
                        tech.close();
                        if(response!=null){
                        setNoteBody(new String(response, Charset.forName("utf-8")));
                        }
                    }
                } catch (IOException e) {
                   
                }
    	    }

 

你可能感兴趣的:(Android)