当前位置: 首页 > article >正文

Java写URI网址唤醒APP小程序等NDEF信息

本示例使用的发卡器:https://item.taobao.com/item.htm?spm=a21dvs.23580594.0.0.52de2c1bvCxCPM&ft=t&id=615391857885 

import com.sun.jna.Library ;
import com.sun.jna.Native;
import java.io.IOException;

interface CLibrary extends Library {
    //DLL绝对路径的地址获取,注意要去空格,特别坑
    //不同版本的读写器,接口DLL文件名称、函数名称是一样的,但内核代码不一样,请选用与读写器、操作系统一致的OUR_MIFARE.dll
    String filePath = CLibrary.class.getResource("").getPath().replaceFirst("/","").replaceAll("%20"," ")+"OUR_MIFARE";
    CLibrary sdtapi = (CLibrary) Native.loadLibrary(filePath, CLibrary.class);

    //动态链接库中的方法
    byte pcdbeep(int xms);                         //让设备发出声音
    byte pcdgetdevicenumber(byte[] devicenumber);  //读取设备编号
    byte piccreadex(byte ctrlword,byte[] serial,byte area,byte keyA1B0,byte[] picckey,byte[] piccdata0_2);             //轻松读M1卡
    byte piccinit_ntag(byte ctrlword,byte[] serial,byte[] oldkey,byte[] mypicdata);
    byte picclock_ntag(byte locktype,byte[] mypicclockdata);
    byte iso15693lockblock(byte flags,byte blockadd,byte[] uid);
    byte tagbuf_forumtype4_clear();    //清空NDEF记录缓冲
    byte tagbuf_clear();  //清空NDEF记录缓冲
    byte piccreadex_ntag(byte myctrlword,byte[] mypiccserial,byte[] mypicckey,byte myblockaddr,byte myblocksize,byte[] mypiccdata);    //轻松读ntag
    byte iso15693readex(byte ctrlword,byte afi,byte startblock,byte blocknum,byte[] mypiccserial,byte[] piccdata);    //轻松读15693
    byte forumtype4request(byte ctrlword,byte[] mypiccserial,byte[] mypiccseriallen);  //寻forumtype4
    byte tagbuf_addtext(byte[] languagecodestr,int languagecodestrlen,byte[] textstr,int textstrlen);
    byte tagbuf_adduri(byte[] languagecodestr,int languagecodestrlen,byte[] titlestr,int titlestrlen,int uriheaderindex,byte[] uristr,int uristrlen);
    byte tagbuf_addapp1(byte[] packagestr,int packagestrlen,byte[] typestr,int typestrlen);
    byte tagbuf_addwifi(byte[] ssidstr,int ssidstrlen,int authtype,int crypttype,byte[] keystr,int keystrlen);
    byte tagbuf_addbluetooth(byte[] blenamestr,int blenamestrlen,byte[] macbuf);
    byte tagbuf_addbusinesscard(byte[] infostr,int infostrlen);
    byte tagbuf_adddata(byte[] typestr,int typestrlen,byte[] datastr,int datastrlen);
    byte forumtype2_write_ndeftag(byte ctrlword,byte[] serial,byte[] oldpicckey);
    byte forumtype2_read_ndeftag(byte ctrlword,byte[] serial,byte[] oldpicckey);
    byte forumtype4_write_ndeftag(byte ctrlword,byte[] serial,byte[] mypiccseriallen,byte[] newpicckey);
    byte forumtype4_read_ndeftag(byte ctrlword,byte[] serial,byte[] mypiccseriallen,byte[] oldpicckey);
    byte forumtype5_write_ndeftag(byte ctrlword,byte afi,byte[] serial);
    byte forumtype5_read_ndeftag(byte ctrlword,byte afi,byte[] serial);
    byte piccwrite_ndeftag(byte ctrlword,byte[] serial,byte[] oldpicckey,byte[] newpicckey);
    byte piccread_ndeftag(byte ctrlword,byte[] serial,byte[] oldpicckey);
    byte tagbuf_read(byte[] tagdatabuf,byte[] buflen,byte[] recordnum);
}
public class JavaJnaNdef {
    public static byte[] tagoldkey={(byte)0x19,(byte)0x74,(byte)0x02,(byte)0x02,(byte)0x01,(byte)0x11};     //标签旧密钥
    public static byte[] tagnewkey={(byte)0x19,(byte)0x74,(byte)0x02,(byte)0x02,(byte)0x01,(byte)0x11};     //标签新密钥,可自行修改,修改后要记住,否则标签将报废,下次操作此标签的旧密钥需更换成此新密钥

    public static void main(String[] args) throws Exception {
        System.setProperty("jna.encoding", "gbk");

        int status;                       //存放返回值

        if (args.length == 0) {
            System.out.println("请先输入运行参数!");
            System.out.println("\n参数 0:驱动读卡器嘀一声");
            System.out.println("\n参数 1:读取设备编号");
            System.out.println("\n参数 2:清空NDEF数据缓冲");
            System.out.println("\n参数 3:生成写NDEF 文本记录缓冲");
            System.out.println("\n参数 4:生成写NDEF URI记录缓冲");
            System.out.println("\n参数 5:生成写NDEF 唤醒APP缓冲");
            System.out.println("\n参数 6:生成写NDEF 呼叫电话缓冲");
            System.out.println("\n参数 7:生成写NDEF 地图坐标缓冲");
            System.out.println("\n参数 8:生成写NDEF WIFI连接缓冲");
            System.out.println("\n参数 9:生成写NDEF 蓝牙连接缓冲");
            System.out.println("\n参数 10:生成写NDEF 电子名片缓冲");
            System.out.println("\n参数 11:生成写NDEF 数据类型缓冲");

            System.out.println("\n参数 12:将NDEF数据缓冲写入标签");
            System.out.println("\n参数 13:读取标签内NDEF记录");
            return;
        }

        //Java中只能使用string1.equals(string2)的方式来比较字符串
        if (args[0].equals("0")) {             //--------------------------------------------------------驱动读卡器发嘀一声
            System.out.print("\n\n0-驱动读卡器嘀一声\n");
            CLibrary.sdtapi.pcdbeep(50);
            System.out.print("结果:如果能听到读卡器嘀一声表示成功,否则请检查读卡器是否已连上线!\n\n");

        } else if (args[0].equals("1"))          //---------读取设备编号,可做为软件加密狗用,也可以根据此编号在公司网站上查询保修期限
        {
            byte[] devicenumber = new byte[4];//4字节设备编号
            status = (int) (CLibrary.sdtapi.pcdgetdevicenumber(devicenumber) & 0xff);//& 0xff用于转为无符号行数据
            System.out.print("\n\n1-读取设备编号\n");
            System.out.print("结果:");
            if (status == 0) {
                CLibrary.sdtapi.pcdbeep(38);
                System.out.print("读取成功!设备编号为" + (devicenumber[0] & 0xff) + "-" + (devicenumber[1] & 0xff) + "-" + (devicenumber[2] & 0xff) + "-" + (devicenumber[3] & 0xff));
                System.out.print("\n\n");
            } else {
                PrintErrInf(status);   //错误代码提示
            }

        } else if (args[0].equals("2")) { //--------------------------------------------------------------清空NDEF数据缓冲
            CLibrary.sdtapi.tagbuf_clear();
            CLibrary.sdtapi.tagbuf_forumtype4_clear();
            System.out.print("\n2-已清空NDEF写卡数据据缓冲!");

        } else if (args[0].equals("3")) { //-------------------------------------------------------------生成NDEF 文本缓冲
            String languagecodestr = "en";
            byte[] languagecodeBuf = languagecodestr.getBytes("gb2312");
            int languagecodestrlen = languagecodeBuf.length;

            String textstr = "轻轻的我走了,正如我轻轻的来;我轻轻的招手,作别西天的云彩。";   //要写入的文本信息
            byte[] textbuf =textstr.getBytes("gb2312");
            int textstrlen=textbuf.length;

            status = (int) (CLibrary.sdtapi.tagbuf_addtext(languagecodeBuf, languagecodestrlen, textbuf, textstrlen) & 0xff);  //可以用此函数连续生成多条记录缓冲 再一起写入标签
            if(status == 0) {
                System.out.print("\n3-生成NDEF文本缓冲数据成功,可以继续向缓冲区添加记录,也可以调用写函数将现有缓冲数据写入标签!");
                WriteDataBufToTag(false,false);   //将缓冲区数据写入标签,参数一标签是否已经加密,参数二写入数据后是否要对标签加密
            }else {
                System.out.print("\n3-生成NDEF文本缓冲数据失败,错误代码:" + Integer.toString(status));
            }

        } else if (args[0].equals("4")) { //----------------------------------------------------------生成NDEF URI记录缓冲
            String languagecodestr = "en";
            byte[] languagecodeBuf = languagecodestr.getBytes("gb2312");
            int languagecodestrlen = languagecodeBuf.length;

            String titlestr = "百度";   //标题,可以是空
            byte[] titlebuf =titlestr.getBytes("gb2312");
            int titlestrlen=titlebuf.length;

            //  无前缀:             0
            //  http://www.        1
            //  https//www.        2
            //  http://            3
            //  https://           4
            //  tel:               5
            //  mailto:            6        更多的前缀代号说明 请参看文档
            int uriheaderindex=2;  //前缀代号

            String uristr="baidu.com";  //uri域名,不要包前缀,
            byte[] uribuf=uristr.getBytes("gb2312");
            int uristrlen=uribuf.length;

            status = (int) (CLibrary.sdtapi.tagbuf_adduri(languagecodeBuf, languagecodestrlen, titlebuf, titlestrlen,uriheaderindex,uribuf,uristrlen) & 0xff);  //可以用此函数连续生成多条记录缓冲 再一起写入标签
            if(status == 0) {
                System.out.print("\n4-生成NDEF URI记录缓冲数据成功,可以继续向缓冲区添加记录,也可以调用写函数将现有缓冲数据写入标签!");
            }else {
                System.out.print("\n4-生成NDEF URI记录缓冲数据失败,错误代码:" + Integer.toString(status));
            }

        } else if (args[0].equals("5")) { //----------------------------------------------------------生成NDEF 唤醒APP缓冲
            String packagestr = "com.tencent.mm";       //APP包名称
            byte[] packageBuf = packagestr.getBytes("gb2312");
            int packagestrstrlen = packageBuf.length;

            String typestr = "android.com:pkg";          //APP类型 安卓android.com:pkg   鸿蒙ohos.com:pkg
            byte[] typebuf =typestr.getBytes("gb2312");
            int typestrlen=typebuf.length;

            status = (int) (CLibrary.sdtapi.tagbuf_addapp1(packageBuf, packagestrstrlen, typebuf, typestrlen) & 0xff);  //可以用此函数连续生成多条记录缓冲 再一起写入标签
            if(status == 0) {
                System.out.print("\n5-生成NDEF 唤醒APP缓冲数据成功,可以继续向缓冲区添加记录,也可以调用写函数将现有缓冲数据写入标签!");
            }else {
                System.out.print("\n5-生成NDEF 唤醒APP缓冲数据失败,错误代码:" + Integer.toString(status));
            }

        } else if (args[0].equals("6")) { //----------------------------------------------------------生成NDEF 呼叫电话缓冲
            String languagecodestr = "en";
            byte[] languagecodeBuf = languagecodestr.getBytes("gb2312");
            int languagecodestrlen = languagecodeBuf.length;

            String titlestr = "";         //标题为空
            byte[] titlebuf =titlestr.getBytes("gb2312");
            int titlestrlen=titlebuf.length;

            int uriheaderindex=5;         //呼叫电话固定前缀代号

            String uristr="13800138001";  //呼叫电话号,
            byte[] uribuf=uristr.getBytes("gb2312");
            int uristrlen=uribuf.length;

            status = (int) (CLibrary.sdtapi.tagbuf_adduri(languagecodeBuf, languagecodestrlen, titlebuf, titlestrlen,uriheaderindex,uribuf,uristrlen) & 0xff);  //可以用此函数连续生成多条记录缓冲 再一起写入标签
            if(status == 0) {
                System.out.print("\n6-生成NDEF 呼叫电话缓冲数据成功,可以继续向缓冲区添加记录,也可以调用写函数将现有缓冲数据写入标签!");
            }else {
                System.out.print("\n6-生成NDEF 呼叫电话缓冲数据失败,错误代码:" + Integer.toString(status));
            }

        } else if (args[0].equals("7")) { //----------------------------------------------------------生成NDEF 地图坐标缓冲
            String languagecodestr = "en";
            byte[] languagecodeBuf = languagecodestr.getBytes("gb2312");
            int languagecodestrlen = languagecodeBuf.length;

            String titlestr = "北京天安门广场";         //标题为空
            byte[] titlebuf =titlestr.getBytes("gb2312");
            int titlestrlen=titlebuf.length;

            int uriheaderindex=0;         //地图坐标固定前缀代号

            String uristr="geo:39.906922,116.389027";  //坐标的纬度,经度值,
            byte[] uribuf=uristr.getBytes("gb2312");
            int uristrlen=uribuf.length;

            status = (int) (CLibrary.sdtapi.tagbuf_adduri(languagecodeBuf, languagecodestrlen, titlebuf, titlestrlen,uriheaderindex,uribuf,uristrlen) & 0xff);  //可以用此函数连续生成多条记录缓冲 再一起写入标签
            if(status == 0) {
                System.out.print("\n7-生成NDEF 地图坐标缓冲数据成功,可以继续向缓冲区添加记录,也可以调用写函数将现有缓冲数据写入标签!");
            }else {
                System.out.print("\n7-生成NDEF 地图坐标缓冲数据失败,错误代码:" + Integer.toString(status));
            }

        } else if (args[0].equals("8")) { //----------------------------------------------------------生成NDEF WIFI连接缓冲
            String ssidstr = "Xiaomi_E467";                             //热点名称
            byte[] ssidBuf = ssidstr.getBytes("gb2312");
            int ssidstrstrlen = ssidBuf.length;

            int authtype=7;       //认证方式 代码
            // 无                            0
            // WPA个人                        1
            // SHARED                        2
            // WPA企业                        3
            // MIXED                         4
            // WPA2企业                       5
            // WPA2个人                       6
            // WPA+WPA2个人                   7

            int crypttype=4;      //加密算法  代码
            // 无                             0
            // WEP                            1
            // TKIP                           2
            // AES                            3
            // AES+TKIP                       4

            String keystr = "gzrs#82301718.";         //热点连接密钥
            byte[] keybuf =keystr.getBytes("gb2312");
            int keystrstrlen=keybuf.length;

            status = (int) (CLibrary.sdtapi.tagbuf_addwifi(ssidBuf, ssidstrstrlen, authtype, crypttype,keybuf,keystrstrlen) & 0xff);  //可以用此函数连续生成多条记录缓冲 再一起写入标签
            if(status == 0) {
                System.out.print("\n8-生成NDEF WIFI连接缓冲数据成功,可以继续向缓冲区添加记录,也可以调用写函数将现有缓冲数据写入标签!");
            }else {
                System.out.print("\n8-生成NDEF WIFI连接缓冲数据失败,错误代码:" + Integer.toString(status));
            }

        } else if (args[0].equals("9")) { //----------------------------------------------------------生成NDEF 蓝牙连接缓冲
            String blenamestr = "HP Printer";          //蓝牙设备名称
            byte[] blenameBuf = blenamestr.getBytes("gb2312");
            int blenamestrlen = blenameBuf.length;

            byte[] macbuf ={(byte)0x21,(byte)0xf4,(byte)0x76,(byte)0x78,(byte)0x3a,(byte)0xb6};  //蓝牙设备的MAC地址 21:f4:76:78:3a:b6

            status = (int) (CLibrary.sdtapi.tagbuf_addbluetooth(blenameBuf, blenamestrlen, macbuf) & 0xff);  //可以用此函数连续生成多条记录缓冲 再一起写入标签
            if(status == 0) {
                System.out.print("\n9-生成NDEF 蓝牙连接缓冲数据成功,可以继续向缓冲区添加记录,也可以调用写函数将现有缓冲数据写入标签!");
            }else {
                System.out.print("\n9-生成NDEF 蓝牙连接缓冲数据失败,错误代码:" + Integer.toString(status));
            }

        } else if (args[0].equals("10")) { //----------------------------------------------------------生成NDEF 电子名片缓冲
            String businesscardstr = "BEGIN:VCARD\n";          //名片信息
            businesscardstr=businesscardstr+"VERSION:3.0\n";
            businesscardstr=businesscardstr+"FN:张三丰\n";
            businesscardstr=businesscardstr+"TEL:13800138000\n";
            businesscardstr=businesscardstr+"ORG:广东省人民政府\n";
            businesscardstr=businesscardstr+"ADR:广东省广州市东风中路305号省政府大院\n";
            businesscardstr=businesscardstr+"EMAIL:12345678@qq.com\n";
            businesscardstr=businesscardstr+"URL:http://www.gd.gov.cn/\n";
            businesscardstr=businesscardstr+"END:VCARD\n";

            byte[] businesscardBuf = businesscardstr.getBytes("gb2312");
            int businesscardstrlen = businesscardBuf.length;

            status = (int) (CLibrary.sdtapi.tagbuf_addbusinesscard(businesscardBuf, businesscardstrlen) & 0xff);  //可以用此函数连续生成多条记录缓冲 再一起写入标签
            if(status == 0) {
                System.out.print("\n10-生成NDEF 电子名片缓冲数据成功,可以继续向缓冲区添加记录,也可以调用写函数将现有缓冲数据写入标签!");
            }else {
                System.out.print("\n10-生成NDEF 电子名片缓冲数据失败,错误代码:" + Integer.toString(status));
            }

        } else if (args[0].equals("11")) { //---------------------------------------------------------生成NDEF 数据标签缓冲
            String typestr = "text/plain";          //数据类型名称
            byte[] typeBuf = typestr.getBytes("gb2312");
            int typestrlen = typeBuf.length;

            String datastr = "0123456789ABCDEF";          //数据
            byte[] dataBuf = datastr.getBytes("gb2312");
            int datastrlen = dataBuf.length;

            status = (int) (CLibrary.sdtapi.tagbuf_adddata(typeBuf, typestrlen, dataBuf,datastrlen) & 0xff);  //可以用此函数连续生成多条记录缓冲 再一起写入标签
            if(status == 0) {
                System.out.print("\n11-生成NDEF 数据标签缓冲数据成功,可以继续向缓冲区添加记录,也可以调用写函数将现有缓冲数据写入标签!");
            }else {
                System.out.print("\n11-生成NDEF 数据标签缓冲数据失败,错误代码:" + Integer.toString(status));
            }

        } else if (args[0].equals("12")) { //将缓冲区内数据写入不同标签
            WriteDataBufToTag(false,false);   //将缓冲区数据写入标签,参数一标签是否已经加密,参数二写入数据后是否要对标签加密

        } else if (args[0].equals("13")) { //读取标签内的 NDEF记录
            ReadDataBufFromTag(false);  //标签是否已加密

        } else if (args[0].equals("14")) {
            String textinf="伟大的中华人民共和国万岁!1949 yes";
            byte[] byteArray = textinf.getBytes();
            String newstr= new String(byteArray, "GBK");
            System.out.print(newstr);
        }
    }

    //------------------------------------------------------------------------------------------------检测发卡器上的标签类型
    public static int checkcardtype(){
        int tagtype=0;
        byte status;
        byte[] tagdata=new byte[48];
        byte[] tagserial={0,0,0,0,0,0,0,0};
        byte myctrlword=0;
        byte myblockaddr=4;
        byte myblocksize=1;
        status= (byte) (CLibrary.sdtapi.piccreadex_ntag(myctrlword, tagserial, tagoldkey, myblockaddr, myblocksize, tagdata) & 0xff);
        if (status==0){
            tagtype=1;
        }else{
            byte afi = 0;                     //卡片应用标识
            status= (byte) (CLibrary.sdtapi.iso15693readex(myctrlword, afi, myblockaddr, myblocksize, tagserial, tagdata) & 0xff);
            if (status==0){
                tagtype=2;
            }else{
                myctrlword=23;
                byte[] m1key1={(byte)0xff,(byte)0xff,(byte)0xff,(byte)0xff,(byte)0xff,(byte)0xff};
                status = (byte) (CLibrary.sdtapi.piccreadex(myctrlword, tagserial, (byte)0, (byte)1, m1key1, tagdata) & 0xff);
                if (status==0){
                    tagtype=3;
                }else{
                    myctrlword=23;
                    byte[] m1key2={(byte)0xa0,(byte)0xa1,(byte)0xa2,(byte)0xa3,(byte)0xa4,(byte)0xa5};
                    status = (byte) (CLibrary.sdtapi.piccreadex(myctrlword, tagserial, (byte)0, (byte)1, m1key2, tagdata) & 0xff);
                    if (status==0) {
                        tagtype = 3;
                    }else{
                        myctrlword=0;
                        byte[] tagseriallen={0};
                        if ((byte) (CLibrary.sdtapi.forumtype4request(myctrlword, tagserial, tagseriallen)& 0xff)==0 || (byte) (CLibrary.sdtapi.forumtype4request(myctrlword, tagserial, tagseriallen)& 0xff)==52){
                            tagtype = 4;
                        }
                    }
                }
            }
        }
        return tagtype;
    }

    //-----------------------------------------------------------------------------将已存在缓冲区内的NDEF记录写入不同的NFC标签
    public static void WriteDataBufToTag(boolean tagislock,boolean taglocken){
        byte myctrlword;
        byte status;
        byte[] tagserial={0,0,0,0,0,0,0,0};
        String Dispinfo;
        int tagtype=checkcardtype();
        if (tagtype==1){
            if (tagislock){myctrlword=(byte)0x10;} else {myctrlword=(byte)0x00;}
            status=(byte)(CLibrary.sdtapi.forumtype2_write_ndeftag(myctrlword,tagserial,tagoldkey)& 0xff);
            if (status==0){
                CLibrary.sdtapi.pcdbeep(50);
                Dispinfo = "\nNtag2UID:";
                for (int i = 0; i < 7; i++) {
                    Dispinfo = Dispinfo + String.format("%02X",tagserial[i] & 0xff) ;
                }
                NtagKeyEn(tagislock,taglocken);    //开启或关ntag2x卡密码保护功能
                System.out.print(Dispinfo+",NDEF数据缓冲写入标签成功!");
            }else{
                PrintErrInf(status);   //错误代码提示
            }
        } else if (tagtype==2) {
            myctrlword=(byte)0x00;
            byte afi=(byte)0x00;
            status=(byte)(CLibrary.sdtapi.forumtype5_write_ndeftag(myctrlword,afi,tagserial)& 0xff);
            if (status==0){
                CLibrary.sdtapi.pcdbeep(50);
                Dispinfo = "\n15693UID:";
                for (int i = 0; i < 8; i++) {
                    Dispinfo = Dispinfo + String.format("%02X",tagserial[i] & 0xff) ;
                }
                //lock15693tag(tagserial);          //锁死15693标签块数据,锁后卡片数据无法再次修改!!请谨慎使用此功能!!
                System.out.print(Dispinfo+",NDEF数据缓冲写入标签成功!");
            }else{
                PrintErrInf(status);   //错误代码提示
            }
        } else if (tagtype==3) {
            if (tagislock){myctrlword=(byte)0xd0;} else {myctrlword=(byte)0x90;}
            if (taglocken){myctrlword=(byte)(myctrlword+4);}
            status=(byte)(CLibrary.sdtapi.piccwrite_ndeftag(myctrlword,tagserial,tagoldkey,tagnewkey)& 0xff);
            if (status==0){
                CLibrary.sdtapi.pcdbeep(50);
                Dispinfo = "\nMifareClassUID:";
                for (int i = 0; i < 4; i++) {
                    Dispinfo = Dispinfo + String.format("%02X",tagserial[i] & 0xff) ;
                }
                System.out.print(Dispinfo+",NDEF数据缓冲写入标签成功!");
            }else{
                PrintErrInf(status);   //错误代码提示
            }
        } else if (tagtype==4) {
            myctrlword=(byte)0x00;
            byte[] tagseriallen={0};
            status=(byte)(CLibrary.sdtapi.forumtype4_write_ndeftag(myctrlword,tagserial,tagseriallen,tagnewkey)& 0xff);
            if (status==0){
                CLibrary.sdtapi.pcdbeep(50);
                Dispinfo = "\nForumType4UID:";
                for (int i = 0; i < tagseriallen[0]; i++) {
                    Dispinfo = Dispinfo + String.format("%02X",tagserial[i] & 0xff) ;
                }
                System.out.print(Dispinfo+",NDEF数据缓冲写入标签成功!");
            }else{
                PrintErrInf(status);   //错误代码提示
            }
        } else {
            System.out.print("\nNDEF数据缓冲写入标签失败,未发现发卡器上有标签!");
        }
    }

    //--------------------------------------------------------------------开启或关闭ntag2x卡密码保护功能,推荐用此方法保护写入信息
    public static void NtagKeyEn(boolean tagislock,boolean taglocken){
        byte myctrlword;
        byte[] tagserial={0,0,0,0,0,0,0,0};
        byte[] mypiccdata=new byte[16];

        if (tagislock){myctrlword=(byte)0x10;} else {myctrlword=(byte)0x00;}  //标签是否已经有密码保护
        if (taglocken){            //开启标签密钥保护
            mypiccdata[0] = 0x00;
            mypiccdata[1] = 0x00;
            mypiccdata[2] = 0x00;
            mypiccdata[3] = 0x04;  //密钥保护起始块地址
            mypiccdata[4] = 0x00;  //允许密钥认证失败次数,取0表示不限制失败次数
            mypiccdata[5] = 0x00;  //计数器
            mypiccdata[6] = 0x00;
            mypiccdata[7] = 0x00;
            for (int i=0;i<4;i++){  //4字节卡片密钥
                mypiccdata[i+8]=tagnewkey[i];
            }
            mypiccdata[12] = 0x16;
            mypiccdata[13] = 0x16;
            mypiccdata[14] = 0x00;
            mypiccdata[15] = 0x00;
            myctrlword = (byte)(myctrlword + 0x04);
            myctrlword = (byte)(myctrlword + 0x01);
            myctrlword = (byte)(myctrlword + 0x02);
        }else{                    //关闭标签密钥
            for (int i=0;i<16;i++){
                mypiccdata[i]=0x00;
            }
            mypiccdata[3] = (byte)0xff;
            myctrlword = (byte)(myctrlword + 0x01);
            myctrlword = (byte)(myctrlword + 0x02);
        }
        byte status=(byte)(CLibrary.sdtapi.piccinit_ntag(myctrlword,tagserial,tagoldkey,mypiccdata)& 0xff);
    }

    //-----------------------------------------------------------锁死Ntag标签块数据,锁后卡片数据无法再次修改!!请谨慎使用此功能!!
    public static void NtagLock(){
        byte status;
        byte locktype=0x00;
        byte[] mypicclockdata=new byte[4];
        mypicclockdata[0] = 0x00;
        mypicclockdata[1] = 0x00;
        mypicclockdata[2] =(byte) 0xFF;
        mypicclockdata[3] =(byte) 0xFF;
        status=(byte)(CLibrary.sdtapi.picclock_ntag(locktype,mypicclockdata)& 0xff);  //静态锁,锁0-15块

        locktype=0x01;
        mypicclockdata[0] = (byte)0xFF;
        mypicclockdata[1] = (byte)0XFF;
        mypicclockdata[2] = (byte)0xFF;
        mypicclockdata[3] = (byte)0x00;
        status=(byte)(CLibrary.sdtapi.picclock_ntag(locktype,mypicclockdata)& 0xff);  //动态锁,锁16块以后
    }

    //----------------------------------------------------------锁死15693标签块数据,锁后卡片数据无法再次修改!!请谨慎使用此功能!!
    public static  void  lock15693tag(byte[] lockuid){
        byte flags=(byte)0x22;
        byte status;
        for (byte  blockadd=0; blockadd<10;blockadd++){
            status=(byte)(CLibrary.sdtapi.iso15693lockblock(flags,blockadd,lockuid)& 0xff);  //一块块循环锁定,直到最后一块
        }
    }
    //---------------------------------------------------------------------------------------读取不同类型的NFC标签内NDEF记录
    public static void ReadDataBufFromTag(boolean tagislock) throws Exception {
        byte myctrlword;
        byte status=8;
        byte[] tagserial={0,0,0,0,0,0,0,0};
        String Dispinfo="";

        int tagtype=checkcardtype();
        if (tagtype==1){        //forumtype2  Ntag
            if (tagislock){myctrlword=(byte)0x10;} else {myctrlword=(byte)0x00;}
            status=(byte)(CLibrary.sdtapi.forumtype2_read_ndeftag(myctrlword,tagserial,tagoldkey)& 0xff);
            Dispinfo = "读取 Ntag2UID:";
            for (int i = 0; i < 7; i++) {
                Dispinfo = Dispinfo + String.format("%02X",tagserial[i] & 0xff) ;
            }

        } else if (tagtype==2) {        //forumtype5  15693
            myctrlword=(byte)0x00;
            byte afi=(byte)0x00;
            status=(byte)(CLibrary.sdtapi.forumtype5_read_ndeftag(myctrlword,afi,tagserial)& 0xff);
            Dispinfo = "读取 15693UID:";
            for (int i = 0; i < 8; i++) {
                Dispinfo = Dispinfo + String.format("%02X",tagserial[i] & 0xff) ;
            }

        } else if (tagtype==3) {        //Mifareclass
            myctrlword=(byte)0x90;
            status=(byte)(CLibrary.sdtapi.piccread_ndeftag(myctrlword,tagserial,tagoldkey)& 0xff);
            Dispinfo = "读取 MifareClassUID:";
            for (int i = 0; i < 4; i++) {
                Dispinfo = Dispinfo + String.format("%02X",tagserial[i] & 0xff) ;
            }

        } else if (tagtype==4) {        //forumtype4
            myctrlword=(byte)0x00;
            byte[] tagseriallen={0};
            status=(byte)(CLibrary.sdtapi.forumtype4_read_ndeftag(myctrlword,tagserial,tagseriallen,tagoldkey)& 0xff);
            Dispinfo = "读取 ForumType4UID:";
            for (int i = 0; i < tagseriallen[0]; i++) {
                Dispinfo = Dispinfo + String.format("%02X",tagserial[i] & 0xff) ;
            }

        } else {
            System.out.print("\n读取NFC标签失败!");
        }

        if (status==0){
            CLibrary.sdtapi.pcdbeep(50);
            byte[] tagdatabuf=new byte[2048];
            byte[] databuflen=new byte[2];
            byte[] recordnum=new byte[1];
            CLibrary.sdtapi.tagbuf_read(tagdatabuf,databuflen,recordnum);
            String ndefstrgbk = new String(tagdatabuf, 0, (databuflen[0] & 0xff)-1,"gbk");
            Dispinfo=Dispinfo+"\n"+ndefstrgbk+"\n";
            System.out.print(Dispinfo);
        }
    }

    //------------------------------------------------------------------------------------------------函数返回的错误代码提示
    static void PrintErrInf(int errcode) {
        switch(errcode){
            case 1:
                System.out.print("错误代码:1,0~2块都没读出来,可能刷卡太块。但卡序列号已被读出来!");
                break;
            case 2:
                System.out.print("错误代码:2,第0块已被读出,但1~2块读取失败。卡序列号已被读出来!");
                break;
            case 3:
                System.out.print("错误代码:3,第0、1块已被读出,但2块读取失败。卡序列号已被读出来!");
                break;
            case 8:
                System.out.print("错误代码:8,未寻到卡,请重新拿开卡后再放到感应区!");
                break;
            case 9:
                System.out.print("错误代码:9,有多张卡在感应区,寻卡过程中防冲突失败,读序列吗错误!");
                break;
            case 10:
                System.out.print("错误代码:10,该卡可能已被休眠,无法选中卡片!");
                break;
            case 11:
                System.out.print("错误代码:11,密码装载失败!");
                break;
            case 12:
                System.out.print("错误代码:12,卡片密码认证失败!");
                break;
            case 13:
                System.out.print("错误代码:13,读本块失败,原因是刷卡太快或本块所对应的区还没通过密码认证!");
                break;
            case 14:
                System.out.print("错误代码:14,写本块失败,原因是刷卡太快或本块所对应的区还没通过密码认证!");
                break;
            case 21:
                System.out.print("错误代码:21,没有动态库!");
                break;
            case 22:
                System.out.print("错误代码:22,动态库或驱动程序异常!");
                break;
            case 23:
                System.out.print("错误代码:23,驱动程序错误或尚未安装!");
                break;
            case 24:
                System.out.print("错误代码:24,操作超时,一般是动态库没有反映!");
                break;
            case 25:
                System.out.print("错误代码:25,发送字数不够!");
                break;
            case 26:
                System.out.print("错误代码:26,发送的CRC错!");
                break;
            case 27:
                System.out.print("错误代码:27,接收的字数不够!");
                break;
            case 28:
                System.out.print("错误代码:28,接收的CRC错!");
                break;
            case 46:
                System.out.print("错误代码:46,标签存储空间不足或块已被锁定!");
            case 254:
                System.out.print("错误代码:254,标签存储空间不足或块已被锁定!");
                break;
            case 255:
                System.out.print("错误代码:255,暂不支持长度大于255字节的信息写入!");
                break;
            default:
                System.out.print("未知错误,错误代码:"+Integer.toString(errcode));
                break;
        }
    }

}

 


http://www.kler.cn/a/447267.html

相关文章:

  • html <a>设置发送邮件链接、打电话链接 <a href=“mailto:></a> <a href=“tel:></a>
  • Java实现贪吃蛇游戏
  • Windows中运行Linux(WSL)
  • 【C#】Ctrl+ 组合键的使用
  • netcore 集成Prometheus
  • 手眼标定工具操作文档
  • IP地址查询的背后②:IP地址(IPv4)的构成、类型以及子网划分
  • vscode的keil assistant 中搜索不到全局变量
  • RTOS之邮箱
  • JAVA学习-练习试用Java实现“使用Arrays.sort方法对整数数组进行排序”
  • SQL进阶技巧:如何计算商品需求与到货队列表进出计划?
  • 深度学习之超分辨率算法——SRGAN
  • 【ETCD】【源码阅读】深入分析 applierV3backend.Apply`方法源码
  • 设计模式之桥接模式:抽象与实现之间的分离艺术
  • C语言 排序
  • sqlite基础
  • 安卓native层抓trace
  • ASP.NET Core - 依赖注入 自动批量注入
  • gesp(三级)(8)洛谷:B3926:[GESP202312 三级] 单位转换
  • HarmonyOS(71) 自定义事件分发之TouchTestStrategy使用说明
  • 电脑提示ntdll.d缺失是什么原因?不处理的话会怎么样?ntdll.dll文件缺失快速解决方案来啦!
  • 数据云平台的可观测性
  • 【Leecode】Leecode刷题之路第87天之扰乱字符串
  • SKETCHPAD——允许语言模型生成中间草图,在几何、函数、图算法和游戏策略等所有数学任务中持续提高基础模型的性能
  • ip_output函数
  • 音视频学习(二十六):http-flv