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;
}
}
}