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标准。现今这项技术在日韩被广泛应用。手机用户凭着配置了支付功能的手机就可以行遍全国:他们的手机可以用作机场登机验证、大厦的门禁钥匙、交通一卡通、信用卡、支付卡等等。

                                                                       

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就会启动。

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

                       

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入门教学,android基础)