package com.dayu.qihealonelibrary.tools; 
 | 
  
 | 
import android.app.Activity; 
 | 
import android.content.Intent; 
 | 
import android.nfc.NfcAdapter; 
 | 
import android.nfc.Tag; 
 | 
import android.nfc.tech.MifareClassic; 
 | 
import android.util.Log; 
 | 
  
 | 
import com.dayu.baselibrary.tools.HexUtil; 
 | 
import com.dayu.baselibrary.utils.BaseCommon; 
 | 
import com.dayu.qihealonelibrary.card.UserCard; 
 | 
import com.dayu.qihealonelibrary.utils.CardCommon; 
 | 
  
 | 
  
 | 
import java.io.IOException; 
 | 
import java.util.ArrayList; 
 | 
import java.util.Arrays; 
 | 
import java.util.HashMap; 
 | 
import java.util.List; 
 | 
import java.util.Map; 
 | 
  
 | 
/** 
 | 
 * @author zx 
 | 
 * @date 2018/4/23 14:31 
 | 
 * email 1058083107@qq.com 
 | 
 * description nfc读取工具类 
 | 
 */ 
 | 
public class NfcReadHelper extends BaseNFCHelper { 
 | 
  
 | 
    private Tag tag; 
 | 
    //    private NFCCallback callback; 
 | 
    private static NfcReadHelper helper; 
 | 
  
 | 
  
 | 
    public NfcReadHelper(Intent intent, Activity activity) { 
 | 
        super(activity); 
 | 
        this.tag = intent.getParcelableExtra(NfcAdapter.EXTRA_TAG); 
 | 
    } 
 | 
  
 | 
    /** 
 | 
     * 单例初始化 
 | 
     * 
 | 
     * @param intent 
 | 
     * @return 
 | 
     */ 
 | 
    public static NfcReadHelper getInstence(Intent intent, Activity activity) { 
 | 
        if (helper == null) { 
 | 
            helper = new NfcReadHelper(intent, activity); 
 | 
        } 
 | 
        return helper; 
 | 
    } 
 | 
  
 | 
    /** 
 | 
     * 获取用户卡信息 
 | 
     * 
 | 
     * @return 
 | 
     */ 
 | 
    public UserCard getUserCardData() { 
 | 
        UserCard userCard = null; 
 | 
        Map<String, List<byte[]>> map = new HashMap<>(); 
 | 
        MifareClassic mfc = MifareClassic.get(tag); 
 | 
        if (null != mfc) { 
 | 
            try { 
 | 
                //链接NFC 
 | 
                mfc.connect(); 
 | 
                //获取扇区数量 
 | 
                int count = mfc.getSectorCount(); 
 | 
                //存储空间 
 | 
                int size = mfc.getSize(); 
 | 
                //用于判断时候有内容读取出来 
 | 
                boolean flag = false; 
 | 
                List<byte[]> list = new ArrayList<>(); 
 | 
                //验证扇区密码,否则会报错(链接失败错误) 
 | 
                boolean isOpen = mfc.authenticateSectorWithKeyA(1, defauleKey); 
 | 
                if (!isOpen) { 
 | 
                    isOpen = mfc.authenticateSectorWithKeyA(1, companyKey); 
 | 
                } 
 | 
                if (isOpen) { 
 | 
                    //获取扇区里面块的数量 
 | 
                    int bCount = mfc.getBlockCountInSector(1); 
 | 
                    //获取扇区第一个块对应芯片存储器的位置(我是这样理解的,因为第0扇区的这个值是4而不是0) 
 | 
                    int bIndex = mfc.sectorToBlock(1); 
 | 
                    //String data1 = ""; 
 | 
                    for (int j = 0; j < bCount; j++) { 
 | 
                        //读取数据 
 | 
                        byte[] data = null; 
 | 
                        try { 
 | 
                            data = mfc.readBlock(bIndex); 
 | 
                            bIndex++; 
 | 
                            list.add(data); 
 | 
                        } catch (Exception e) { 
 | 
                            e.printStackTrace(); 
 | 
                        } 
 | 
                    } 
 | 
                    flag = true; 
 | 
                } 
 | 
  
 | 
                if (flag) { 
 | 
                    userCard = UserCard.getBean(list); 
 | 
                    return userCard; 
 | 
                } 
 | 
            } catch (IOException e) { 
 | 
                e.printStackTrace(); 
 | 
            } catch (Exception e) { 
 | 
                e.printStackTrace(); 
 | 
            } finally { 
 | 
                try { 
 | 
                    mfc.close(); 
 | 
                } catch (Exception e) { 
 | 
                    e.printStackTrace(); 
 | 
                } 
 | 
            } 
 | 
        } 
 | 
        return null; 
 | 
    } 
 | 
  
 | 
    /** 
 | 
     * 获取卡号 
 | 
     * 
 | 
     * @return 
 | 
     */ 
 | 
    public String getCardNumber() { 
 | 
        MifareClassic mfc = MifareClassic.get(tag); 
 | 
        if (null != mfc) { 
 | 
            try { 
 | 
                mfc.connect(); 
 | 
                //获取当前卡号 
 | 
                boolean isOpen = mfc.authenticateSectorWithKeyA(0, defauleKey); 
 | 
                if (!isOpen) { 
 | 
                    isOpen = mfc.authenticateSectorWithKeyA(0, companyKey); 
 | 
                } 
 | 
                if (isOpen) { 
 | 
                    int bIndex = mfc.sectorToBlock(0); 
 | 
                    byte[] data = mfc.readBlock(bIndex + 0); 
 | 
                    if (data != null && data.length > 0) { 
 | 
                        String hex = HexUtil.bytesToHex(Arrays.copyOfRange(data, 0, 4)); 
 | 
//                        hex = HexUtil.spaceHex(hex); 
 | 
//                        hex = HexUtil.HighLowHex(hex); 
 | 
                        Log.i("NFCWreatActivity", "hex===" + hex); 
 | 
                        return hex.toUpperCase(); 
 | 
                    } 
 | 
                } 
 | 
  
 | 
            } catch (IOException e) { 
 | 
                return BaseCommon.CARD_TYPE_ERROR1; 
 | 
            } finally { 
 | 
                try { 
 | 
                    mfc.close(); 
 | 
                } catch (IOException e) { 
 | 
                    e.printStackTrace(); 
 | 
                } 
 | 
            } 
 | 
        } 
 | 
        return ""; 
 | 
    } 
 | 
  
 | 
  
 | 
    /** 
 | 
     * 获取卡片类型和卡号 
 | 
     * 
 | 
     * @return 
 | 
     */ 
 | 
    public String getCradTypeAndCardNumber() { 
 | 
  
 | 
        MifareClassic mfc = MifareClassic.get(tag); 
 | 
        if (null != mfc) { 
 | 
            try { 
 | 
                mfc.connect(); 
 | 
                StringBuilder strData = new StringBuilder(); 
 | 
                //获取当前卡号 
 | 
                boolean isOpen = mfc.authenticateSectorWithKeyA(0, defauleKey); 
 | 
                if (!isOpen) { 
 | 
                    isOpen = mfc.authenticateSectorWithKeyA(0, companyKey); 
 | 
                } 
 | 
                if (isOpen) { 
 | 
                    int bIndex = mfc.sectorToBlock(0); 
 | 
                    byte[] data = mfc.readBlock(bIndex + 0); 
 | 
                    if (data != null && data.length > 0) { 
 | 
                        String hex = HexUtil.bytesToHex(Arrays.copyOfRange(data, 0, 4)); 
 | 
                        strData.append(hex); 
 | 
                        strData.append(","); 
 | 
                        Log.i("NFCWreatActivity", "hex===" + hex); 
 | 
                    } 
 | 
                } 
 | 
                //获取卡片类型 
 | 
                isOpen = mfc.authenticateSectorWithKeyA(1, defauleKey); 
 | 
                if (!isOpen) { 
 | 
                    isOpen = mfc.authenticateSectorWithKeyA(1, companyKey); 
 | 
                } 
 | 
                if (isOpen) { 
 | 
                    int bIndex = mfc.sectorToBlock(1); 
 | 
                    byte[] data = mfc.readBlock(bIndex + 0); 
 | 
                    if (data != null && data.length > 0) { 
 | 
                        String hex = HexUtil.byteToHex(data[0]); 
 | 
                        strData.append(hex); 
 | 
                        Log.i("NFCWreatActivity", "hex===" + hex); 
 | 
                        return strData.toString().toUpperCase(); 
 | 
                    } 
 | 
                } else { 
 | 
                    Log.i("NFCWreatActivity", "isOpen===" + isOpen); 
 | 
                    return BaseCommon.CARD_TYPE_ERROR2; 
 | 
                } 
 | 
            } catch (IOException e) { 
 | 
                return BaseCommon.CARD_TYPE_ERROR1; 
 | 
            } finally { 
 | 
                try { 
 | 
                    mfc.close(); 
 | 
                } catch (IOException e) { 
 | 
                    e.printStackTrace(); 
 | 
                } 
 | 
            } 
 | 
        } 
 | 
        return ""; 
 | 
    } 
 | 
  
 | 
    /** 
 | 
     * 读取NFC卡的全部信息 
 | 
     * 
 | 
     * @param callback 
 | 
     */ 
 | 
    public void getAllData(final NFCCallMapback callback) { 
 | 
        Map<String, List<byte[]>> map = new HashMap<>(); 
 | 
        MifareClassic mfc = MifareClassic.get(tag); 
 | 
        if (null != mfc) { 
 | 
            try { 
 | 
                //链接NFC 
 | 
                mfc.connect(); 
 | 
                //获取扇区数量 
 | 
                int count = mfc.getSectorCount(); 
 | 
                //存储空间 
 | 
                int size = mfc.getSize(); 
 | 
                //用于判断时候有内容读取出来 
 | 
                boolean flag = false; 
 | 
                for (int i = 0; i < count; i++) { 
 | 
                    List<byte[]> list = new ArrayList<>(); 
 | 
                    //验证扇区密码,否则会报错(链接失败错误) 
 | 
                    boolean isOpen = mfc.authenticateSectorWithKeyA(i, defauleKey); 
 | 
                    if (!isOpen) { 
 | 
                        isOpen = mfc.authenticateSectorWithKeyA(i, companyKey); 
 | 
                    } 
 | 
                    if (isOpen) { 
 | 
                        //获取扇区里面块的数量 
 | 
                        int bCount = mfc.getBlockCountInSector(i); 
 | 
                        //获取扇区第一个块对应芯片存储器的位置(我是这样理解的,因为第0扇区的这个值是4而不是0) 
 | 
                        int bIndex = mfc.sectorToBlock(i); 
 | 
                        //String data1 = ""; 
 | 
                        for (int j = 0; j < bCount; j++) { 
 | 
                            //读取数据 
 | 
                            byte[] data = null; 
 | 
                            try { 
 | 
                                data = mfc.readBlock(bIndex); 
 | 
                                bIndex++; 
 | 
                                list.add(data); 
 | 
                            } catch (Exception e) { 
 | 
                                e.printStackTrace(); 
 | 
                            } 
 | 
                        } 
 | 
                        flag = true; 
 | 
                    } 
 | 
                    map.put(i + "", list); 
 | 
                } 
 | 
                if (flag) { 
 | 
                    callback.callBack(map); 
 | 
                } else { 
 | 
                    callback.error(CardCommon.ERROR); 
 | 
                } 
 | 
            } catch (IOException e) { 
 | 
                callback.error(CardCommon.ERROR_MOVE); 
 | 
                e.printStackTrace(); 
 | 
            } catch (Exception e) { 
 | 
                callback.error(CardCommon.ERROR); 
 | 
                e.printStackTrace(); 
 | 
            } finally { 
 | 
                try { 
 | 
                    mfc.close(); 
 | 
                } catch (Exception e) { 
 | 
                    e.printStackTrace(); 
 | 
                } 
 | 
            } 
 | 
        } 
 | 
    } 
 | 
  
 | 
  
 | 
    public List<byte[]> getOnesectorData() { 
 | 
        MifareClassic mfc = null; 
 | 
        try { 
 | 
            mfc = MifareClassic.get(tag); 
 | 
        } catch (Exception e) { 
 | 
            e.printStackTrace(); 
 | 
        } 
 | 
        List<byte[]> list = new ArrayList<>(); 
 | 
        if (null != mfc) { 
 | 
            try { 
 | 
                //链接NFC 
 | 
                mfc.connect(); 
 | 
                //用于判断时候有内容读取出来 
 | 
                boolean flag = false; 
 | 
  
 | 
                //验证扇区密码,否则会报错(链接失败错误) 
 | 
                boolean isOpen = mfc.authenticateSectorWithKeyA(1, companyKey); 
 | 
                if (!isOpen) { 
 | 
                    isOpen = mfc.authenticateSectorWithKeyA(1, defauleKey); 
 | 
                } 
 | 
                if (isOpen) { 
 | 
                    //获取扇区里面块的数量 
 | 
                    int bCount = mfc.getBlockCountInSector(1); 
 | 
                    //获取扇区第一个块对应芯片存储器的位置(我是这样理解的,因为第0扇区的这个值是4而不是0) 
 | 
                    int bIndex = mfc.sectorToBlock(1); 
 | 
                    //String data1 = ""; 
 | 
                    for (int j = 0; j < bCount; j++) { 
 | 
                        //读取数据 
 | 
                        byte[] data = null; 
 | 
                        try { 
 | 
                            data = mfc.readBlock(bIndex); 
 | 
                            bIndex++; 
 | 
                            list.add(data); 
 | 
                        } catch (Exception e) { 
 | 
                            e.printStackTrace(); 
 | 
                        } 
 | 
                    } 
 | 
                } 
 | 
  
 | 
            } catch (IOException e) { 
 | 
                e.printStackTrace(); 
 | 
            } catch (Exception e) { 
 | 
                e.printStackTrace(); 
 | 
            } finally { 
 | 
                try { 
 | 
                    mfc.close(); 
 | 
                    return list; 
 | 
                } catch (Exception e) { 
 | 
                    e.printStackTrace(); 
 | 
                } 
 | 
            } 
 | 
        } 
 | 
        return null; 
 | 
    } 
 | 
  
 | 
    /** 
 | 
     * 获取1扇区信息 
 | 
     * 
 | 
     * @param callback 
 | 
     */ 
 | 
    public void getOneSectorData(NFCCallListback callback) { 
 | 
  
 | 
  
 | 
        MifareClassic mfc = null; 
 | 
        try { 
 | 
            mfc = MifareClassic.get(tag); 
 | 
        } catch (Exception e) { 
 | 
            e.printStackTrace(); 
 | 
        } 
 | 
        if (null != mfc) { 
 | 
            try { 
 | 
                //链接NFC 
 | 
                mfc.connect(); 
 | 
                //用于判断时候有内容读取出来 
 | 
                boolean flag = false; 
 | 
                List<byte[]> list = new ArrayList<>(); 
 | 
                //验证扇区密码,否则会报错(链接失败错误) 
 | 
                boolean isOpen = mfc.authenticateSectorWithKeyA(1, companyKey); 
 | 
                if (!isOpen) { 
 | 
                    isOpen = mfc.authenticateSectorWithKeyA(1, defauleKey); 
 | 
                } 
 | 
                if (isOpen) { 
 | 
                    //获取扇区里面块的数量 
 | 
                    int bCount = mfc.getBlockCountInSector(1); 
 | 
                    //获取扇区第一个块对应芯片存储器的位置(我是这样理解的,因为第0扇区的这个值是4而不是0) 
 | 
                    int bIndex = mfc.sectorToBlock(1); 
 | 
                    //String data1 = ""; 
 | 
                    for (int j = 0; j < bCount; j++) { 
 | 
                        //读取数据 
 | 
                        byte[] data = null; 
 | 
                        try { 
 | 
                            data = mfc.readBlock(bIndex); 
 | 
                            bIndex++; 
 | 
                            list.add(data); 
 | 
                        } catch (Exception e) { 
 | 
                            e.printStackTrace(); 
 | 
                        } 
 | 
                    } 
 | 
                    flag = true; 
 | 
                } 
 | 
                if (flag) { 
 | 
                    callback.callBack(list); 
 | 
                } else { 
 | 
                    callback.error(CardCommon.ERROR); 
 | 
                } 
 | 
            } catch (IOException e) { 
 | 
                callback.error(CardCommon.ERROR_MOVE); 
 | 
                e.printStackTrace(); 
 | 
            } catch (Exception e) { 
 | 
                callback.error(CardCommon.ERROR); 
 | 
                e.printStackTrace(); 
 | 
            } finally { 
 | 
  
 | 
                try { 
 | 
                    mfc.close(); 
 | 
                } catch (Exception e) { 
 | 
                    e.printStackTrace(); 
 | 
                } 
 | 
            } 
 | 
        } 
 | 
    } 
 | 
  
 | 
  
 | 
    /** 
 | 
     * 读取NFC卡的特定扇区信息 
 | 
     * 
 | 
     * @param a        扇区 
 | 
     * @param b        块 
 | 
     * @param callback 
 | 
     */ 
 | 
    public void getData(final int a, final int b, final NFCCallByteback callback) { 
 | 
        new Thread(new Runnable() { 
 | 
            @Override 
 | 
            public void run() { 
 | 
                Map<String, List<String>> map = new HashMap<>(); 
 | 
                MifareClassic mfc = MifareClassic.get(tag); 
 | 
                if (null != mfc) { 
 | 
                    try { 
 | 
                        mfc.connect(); 
 | 
                        int count = mfc.getSectorCount(); 
 | 
                        if (a < 0 || a > count - 1) { 
 | 
                            callback.error(CardCommon.ERROR); 
 | 
                            return; 
 | 
                        } 
 | 
                        int bCount = mfc.getBlockCountInSector(a); 
 | 
                        if (b < 0 || b > bCount - 1) { 
 | 
                            callback.error(CardCommon.ERROR); 
 | 
                            return; 
 | 
                        } 
 | 
  
 | 
                        int type = mfc.getType();//获取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; 
 | 
                        } 
 | 
                        boolean isOpen = mfc.authenticateSectorWithKeyA(a, defauleKey); 
 | 
                        if (!isOpen) { 
 | 
                            isOpen = mfc.authenticateSectorWithKeyA(a, companyKey); 
 | 
                        } 
 | 
                        if (isOpen) { 
 | 
                            int bIndex = mfc.sectorToBlock(a); 
 | 
                            byte[] data = mfc.readBlock(bIndex + b); 
 | 
                            callback.callBack(data); 
 | 
                        } else { 
 | 
                            callback.error(CardCommon.ERROR); 
 | 
                        } 
 | 
                    } catch (IOException e) { 
 | 
                        callback.error(CardCommon.ERROR_MOVE); 
 | 
                        e.printStackTrace(); 
 | 
                    } catch (Exception e) { 
 | 
                        callback.error(CardCommon.ERROR); 
 | 
                    } finally { 
 | 
                        try { 
 | 
                            mfc.close(); 
 | 
                        } catch (IOException e) { 
 | 
                            e.printStackTrace(); 
 | 
                        } 
 | 
                    } 
 | 
                } 
 | 
            } 
 | 
        }).start(); 
 | 
    } 
 | 
  
 | 
    /** 
 | 
     * 返回监听类 
 | 
     */ 
 | 
    public interface NFCCallMapback { 
 | 
        /** 
 | 
         * 返回读取nfc卡的全部信息 
 | 
         * 
 | 
         * @param data 前面代表扇区 四个块的数据用#号隔开 
 | 
         */ 
 | 
        void callBack(Map<String, List<byte[]>> data); 
 | 
  
 | 
  
 | 
        void error(int code); 
 | 
    } 
 | 
  
 | 
    /** 
 | 
     * 返回监听类 
 | 
     */ 
 | 
    public interface NFCCallListback { 
 | 
        /** 
 | 
         * 返回读取nfc卡的全部信息 
 | 
         * 
 | 
         * @param data 前面代表扇区 四个块的数据用#号隔开 
 | 
         */ 
 | 
        void callBack(List<byte[]> data); 
 | 
  
 | 
  
 | 
        void error(int code); 
 | 
    } 
 | 
  
 | 
  
 | 
    public interface NFCCallByteback { 
 | 
        /** 
 | 
         * 返回读取nfc卡的全部信息 
 | 
         * 
 | 
         * @param data 前面代表扇区 四个块的数据用#号隔开 
 | 
         */ 
 | 
  
 | 
        void callBack(byte[] data); 
 | 
  
 | 
        void error(int code); 
 | 
    } 
 | 
  
 | 
} 
 |