首先需要在Manifest文件中添加权限

<uses-permission android:name="android.permission.NFC" />

<uses-permission android:name="android.permission.NFC_PREFERRED_PAYMENT_INFO" />

NFC根据不同标签类型分为NfcA(操作14443-3A)、NfcB(操作14443-3B)、NfcF(操作JIS 6319-4)、NfcV(操作15693)。

下面主要介绍NfcV 15693的读写方法。

在activity页面中添加

    NfcV nfcV;
    NfcVUtil util;

    @Override
    protected void onNewIntent(Intent intent) {
       super.onNewIntent(intent);
       resolveIntent(intent);
    }

    private void resolveIntent(Intent intent) {
       Tag tag = intent.getParcelableExtra(NfcAdapter.EXTRA_TAG);
       if (tag != null) {
	    	//获取卡id这里即uid
		    byte[] aa = tag.getId();
    		String str = ByteArrayToHexString(aa);//
    		String UID = flipHexStr(str);
    		Toast.makeText(context,"RFID已经连接,可以开始读写 UID:" + ID,
                    Toast.LENGTH_SHORT).show();
    		try {
	    		nfcV = NfcV.get(tag);
		    	if(nfcV != null) {
			    	nfcV.connect();//建立连接
				    util = new NfcVUtil(nfcV);//创建工具类,操作连接
    			}

	    	} catch (Exception e) {
	    		e.printStackTrace();
	    	}
       }
    }

    /*
	 * 写入RFID卡数据,
	 *
	 * @param v
	 */
	public void write(){
		if(!isEnable()){
			return;
		}

		try {
			String info = etIdinput.getText().toString();

            String writeStr = //为a-f的8长度的字符串,转换成byte数组长度为4。
            //第一个参数为块索引,第二个参数为4长度的byte数组。如数据不够,需要补位
			util.writeBlock(0,util.hexStringToBytes(writeStr));
		} catch (IOException e) {
			e.printStackTrace();
		}
	}


    public void read(){
		if(!isEnable()){
			return;
		}
		try {
			String readOneBlockStr = util.readOneBlock(i);//读取block在1位置的内容
			//("读取结果 : " + result ,ctx);
		} catch (IOException e) {
			e.printStackTrace();
		}
	}



    private boolean isEnable(){
    	if(util == null){
            //请先连接RFID卡
    		return false;
		}
    	if(nfcV ==null){
            //请先连接RFID卡
    		return false;
		}
    	if(!nfcV.isConnected()){
            //接连中断,请重新连接
    		return false;
		}
    	return true;
	}

工具类NfcVUtil

import android.nfc.tech.NfcV;

import java.io.IOException;
import java.nio.charset.StandardCharsets;

public class NfcVUtil {

    private NfcV mNfcV;
    /**UID数组行式*/
    private byte[] ID;
    private String UID;
    private String DSFID;
    private String AFI;
    /**block的个数*/
    private int blockNumber;
    /**一个block长度*/
    private int oneBlockSize;
    /**信息*/
    private byte[] infoRmation;

    /**
     * 初始化
     * @param mNfcV NfcV对象
     * @throws IOException
     */
    public NfcVUtil(NfcV mNfcV) throws IOException{
        this.mNfcV = mNfcV;
        ID = this.mNfcV.getTag().getId();
        byte[] uid = new byte[ID.length];
        int j = 0;
        for(int i = ID.length - 1; i >=0; i-- ){
            uid[j] = ID[i];
            j++;
        }
        this.UID = printHexString(uid);
        getInfoRmation();//获取标签的信息
    }
    public String getUID() {
        return UID;
    }


    /**
     * 取得标签信息
     */
    private byte[] getInfoRmation() throws IOException{
        byte[] cmd = new byte[10];
        cmd[0] = (byte) 0x22; // flag
        cmd[1] = (byte) 0x2B; // command
        System.arraycopy(ID, 0, cmd, 2, ID.length); // UID
        infoRmation = mNfcV.transceive(cmd);
        blockNumber = infoRmation[12];//可使用的数据块数量,一般为27
        oneBlockSize = infoRmation[13];//每个块byte数组的长度,一般为4
        AFI = printHexString(new byte[]{infoRmation[11]});//AFI值在某些领域会需要使用
        DSFID = printHexString(new byte[]{infoRmation[10]});//DSFID值
        return infoRmation;
    }

    /**
     * 写入AFI数据
     * @param b
     * @return
     * @throws IOException
     */
    public boolean setAFIState(byte b) throws IOException {
        byte[] cmd = new byte[11];
        cmd[0] = (byte) 0x22; // flag
        cmd[1] = (byte) 0x27; // command
        System.arraycopy(ID, 0, cmd, 2, ID.length); // UID
        cmd[10] = b;
        byte[] res = mNfcV.transceive(cmd);
        if(res[0] == 0x00){
            byte[] cmdNew = new byte[10];
            cmdNew[0] = (byte) 0x22; // flag
            cmdNew[1] = (byte) 0x2B; // command
            System.arraycopy(ID, 0, cmdNew, 2, ID.length); // UID
            AFI = printHexString(new byte[]{infoRmation[11]});
            DSFID = printHexString(new byte[]{infoRmation[10]});

            return true;

            //千万不要锁定,不可逆
//            byte[] cmd2 = new byte[10];
//            cmd2[0] = (byte) 0x22; // flag
//            cmd2[1] = (byte) 0x28; // command
//            System.arraycopy(ID, 0, cmd2, 2, ID.length); // UID
//            byte[] res2 = mNfcV.transceive(cmd2);
//            if(res2[0] == 0x00){
//               return true;
//            }
        }
        return false;
    }

    /**
     * 写入DSFID数据
     * @param b
     * @return
     * @throws IOException
     */
    public boolean setDSFIDState(byte b) throws IOException {
        byte[] cmd = new byte[11];
        cmd[0] = (byte) 0x22; // flag
        cmd[1] = (byte) 0x29; // command
        System.arraycopy(ID, 0, cmd, 2, ID.length); // UID
        cmd[10] = b;
        byte[] res = mNfcV.transceive(cmd);
        if(res[0] == 0x00){
            byte[] cmdNew = new byte[10];
            cmdNew[0] = (byte) 0x22; // flag
            cmdNew[1] = (byte) 0x2B; // command
            System.arraycopy(ID, 0, cmdNew, 2, ID.length); // UID
            AFI = printHexString(new byte[]{infoRmation[11]});
            DSFID = printHexString(new byte[]{infoRmation[10]});
            return true;

            //千万不要锁定,不可逆
//            byte[] cmd2 = new byte[10];
//            cmd2[0] = (byte) 0x22; // flag
//            cmd2[1] = (byte) 0x2A; // command
//            System.arraycopy(ID, 0, cmd2, 2, ID.length); // UID
//            byte[] res2 = mNfcV.transceive(cmd2);
//            if(res2[0] == 0x00){
//                return true;
//            }
        }
        return false;
    }
    public String getDSFID() {
        return DSFID;
    }

    public String getAFI() {
        String temp = String.valueOf(mNfcV.getDsfId());
//        return AFI;
        return temp + AFI;
    }

    /**
     * 读取一个位置在position的block
     * @param position 要读取的block位置
     * @return 返回内容字符串
     * @throws IOException
     */
    public String readOneBlock(int position) throws IOException{
        byte cmd[] = new byte[12];
        cmd[0] = (byte) 0x22;
        cmd[1] = (byte) 0x23;//0x20
        System.arraycopy(ID, 0, cmd, 2, ID.length); // UID
        cmd[10] = (byte) position;
        cmd[11] = (byte) 0;
        byte res[] = mNfcV.transceive(cmd);
        if(res[0] == 0x00){
            byte block[] = new byte[res.length - 1];
            System.arraycopy(res, 1, block, 0, res.length - 1);
            return printHexString(block);
        }
        return null;
    }


    /**
     * String转Hex格式Byte[]
     * @param hexString
     * @return
     */
    public byte[] hexStringToBytes(String hexString) {
        if (hexString == null || hexString.equals("")) {
            return null;
        }
        hexString = hexString.toUpperCase();
        int length = hexString.length() / 2;
        char[] hexChars = hexString.toCharArray();
        byte[] d = new byte[length];
        for (int i = 0; i < length; i++) {
            int pos = i * 2;
            d[i] = (byte) (charToByte(hexChars[pos]) << 4 | charToByte(hexChars[pos + 1]));

        }
        return d;
    }
    private static byte charToByte(char c) {
        return (byte) "0123456789ABCDEF".indexOf(c);
    }
    /**
     * 将byte[]转换成16进制字符串
     * @param data 要转换成字符串的字节数组
     * @return 16进制字符串
     */
    private String printHexString(byte[] data) {
        StringBuffer s = new StringBuffer();;
        for (int i = 0; i < data.length; i++) {
            String hex = Integer.toHexString(data[i] & 0xFF);
            if (hex.length() == 1) {
                hex = '0' + hex;
            }
            s.append(hex);
        }
        return s.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 = inarray.length - 1; j >= 0 ; j--) {
            in = (int) inarray[j] & 0xff;
            i = (in >> 4) & 0x0f;
            out += hex[i];
            i = in & 0x0f;
            out += hex[i];
        }
        return out;
    }


    /**
     * 将数据写入到block,
     * @param position 要写内容的block位置
     * @param data 要写的内容,必须长度为blockOneSize
     * @return false为写入失败,true为写入成功
     * @throws IOException
     */
    public boolean writeBlock(int position, byte[] data) throws IOException{
        byte cmd[] = new byte[15];
        cmd[0] = (byte) 0x22;
        cmd[1] = (byte) 0x21;
        System.arraycopy(ID, 0, cmd, 2, ID.length); // UID
        //block
        cmd[10] = (byte) position;
        //value
        System.arraycopy(data, 0, cmd, 11, data.length);
        byte[]rsp = mNfcV.transceive(cmd);
        if(rsp[0] == 0x00)
            return true;
        return false;
    }

}

Logo

为开发者提供学习成长、分享交流、生态实践、资源工具等服务,帮助开发者快速成长。

更多推荐