公司因业务需要采购了几台身份证读卡器,方便用户刷卡入园,机器一到立马去官网找sdk、找demo,找了一圈都没有看见,后面只好找销售联系技术支持拿到了一份工具包。
使用他们提供的多浏览器版本的话后端基本不需要做什么操作,直接安装一个驱动,前端直接打开他们提供的html文件就可以读取到信息,并显示到页面上,驱动如图
这个是他们提供读取页面的案例
一点读取信息就ok,现在只需要前端通过websocket将数据传递给后台就OK了,但是存在一个问题,人流一多,一直让用户点也不是个事,后面让前端改成循环读取的按钮,表面上看着万事大吉了,其实暗藏了一个隐患,当开启循环读取的时候,没过多久就读取不出来了,出现假死状态,显示繁忙,最后咨询他们技术有没有好的解决办法,说去掉自动循环读取,改为手动点一次读取一次
<( ̄ ﹌  ̄)>
最后没辙了,只好通过他们提供的动态库,利用java来加载动态库读取身份信息,然后再将读取到身份信息通过websocket推送给前端展示。
首先先安装他们提供的usb驱动(这个是定制的驱动,不安装识别不到连接电脑的ID180机器)
然后新建一个普通的springboot 项目,项目结构如下
DLL文件夹用来放置动态库(建议,测试的时候可以放在该目录下,等打包运行的时候最好放到一个指定的根目录下,方便加载,不然会报加载不到)
zkteco.id100com.jni
这个包名一定不能变,因为生成jni的时候是这个包名,如果发生变化,一定会loadclass失败(切记,不要问为什么,因为在这上面栽了跟头)
id100sdk的核心代码如下
package zkteco.id100com.jni;
public class id100sdk {
/**
* <code>id100sdk</code> 身份证阅读器接口类
*/
static
{
System.load("G:\\bowu\\ZhongKong\\DLL\\x64\\termb.dll");
}
/**
* 获取文件目录
* @return 文件目录
*/
public native static String getPath();
/**
* 连接身份证阅读器
*
* @param nPort 设备端口(串口:1~16;USB:1001~1016)
* @return
* 成功返回设备端口
* 失败返回0
*/
public native static int InitComm(int nPort);
/**
* 自动搜索并连接身份证阅读器
*
* @return
* 成功返回设备端口(串口:1~16;USB:1001~1016)
* 失败返回0
*/
public native static int InitCommExt();
/**
* 断开与身份证阅读器连接
* @return
* 成功返回1
* 失败返回0
*/
public native static int CloseComm();
/**
* 认证卡(寻卡&选卡)
* @return
* 成功返回1
* 失败返回0
*/
public native static int Authenticate();
/**
* 读卡操作,信息文件保存在dll所在目录
* @param nActive 1读基本信息(文字&照片&指纹);2读文字照片;3读最新地址
* @return 1 居民身份证读取成功;2 外国人永居证读取成功;3 港澳台居住证读取成功;-11无效参数;0其他错误
*/
public native static int ReadContent(int nActive);
/**
* 获取SAM模块编号
* @return 成功返回SAM模块编号;失败返回空字符串
*/
public native static String GetSAMID();
/**
* 设置临时文件生成的目录;空目录,则不保存临时文件
*/
public native static void SetTemDir(String FileName);
/**
* 获取SAM模块编号(10位编号)
* @return 成功返回SAM模块编号;失败返回空字符串
*/
public native static String GetSAMIDEx();
/**
* 解析(xp.wlt)身份证照片
* @param FileName xp.wlt全路径名
* @return 成功返回1;失败返回0
*/
public native static int GetBmpPhoto(String FileName);
/**
* 解析(dll目录下的xp.wlt)身份证照片
* @return 成功返回1;失败返回0
*/
public native static int GetBmpPhotoExt();
/**
* 重置sam模块
* @return 成功返回1;失败返回0
*/
public native static int ResetSAM();
/**
* 获取SAM模块状态
* @return 状态正常返回1;异常返回0
*/
public native static int GetSAMStatus();
/**
* 获取姓名
* @return 返回姓名
*/
public native static String getName();
/**
* 获取性别
* @return 返回性别
*/
public native static String getSex();
/**
* 获取性别编号
* @return 返回性别编号
*/
public native static int getSexCode();
/**
* 获取民族
* @return 返回民族
*/
public native static String getNation();
/**
* 获取民族编号
* @return 返回毛南族编号
*/
public native static int getNationCode();
/**
* 获取生日(YYYYMMDD)
* @return 返回生日
*/
public native static String getBirthdate();
/**
* 获取地址
* @return 返回地址
*/
public native static String getAddress();
/**
* 获取身份证号码
* @return 返回身份证号码
*/
public native static String getIDNum();
/**
* 获取签发机关
* @return 返回签发机关
*/
public native static String getIssue();
/**
* 获取有效期起始日期(YYYYMMDD)
* @return 返回有效期起始日期
*/
public native static String getEffectedDate();
/**
* 获取有效期截止日期
* @return 返回有效期截止日期
*/
public native static String getExpireDate();
/*
* 获取bmp图片base64编码
* @return 返回bmp图片base64编码
*/
public native static String getBMPPhotoBase64();
/**
* 获取JPG头像Base64编码
* @return 返回JPG头像Base64编码
*/
public native static String getJPGPhotoBase64();
/**
* 语音提示
* @param nVoice 语音类型
* 0:
* @return 成功返回1;失败返回0
*/
public native static int HIDVoice(int nVoice);
/**
* 设置发卡器序列号
* @param iPort 串口号
* @param data 发卡器序列号
* @return 成功返回1;失败返回0
*/
public native static int ICSetDevNum(int iPort, String data);
/**
* 获取发卡器序列号
* @param iPort 串口号
* @return 成功返回发卡器序列号;失败返回空字符串
*/
public native static String ICGetDevNum(int iPort);
/**
* 获取发卡器版本
* @param iPort 串口号
* @return 成功返回发卡器版本(HexString),失败返回空字符串
*/
public native static String ICGetDevVersion(int iPort);
/**
* 发卡
* @param iPort 串口号
* @param keyMode keyA/KeyB
* @param Sector 扇区号
* @param idx //块索引
* @param key //密钥
* @param data //数据
* @param snr //返回卡号
* @return 成功返回1;失败返回0
*/
public native static int ICWriteData(int iPort, int keyMode, int Sector, int idx, String key, String data, int[] snr);
/**
* 读卡
* @param iPort 串口号
* @param keyMode keyA/KeyB
* @param Sector 扇区号
* @param idx //块索引
* @param key //密钥
* @param snr //返回卡号
* @return 成功返回卡数据(HexString);失败返回空串
*/
public native static String ICReadData(int iPort, int keyMode, int Sector, int idx, String key, int[] snr);
/**
* 读取IC卡物理卡号
* @param iPort 串口号
* @param snr 返回IC卡物理卡号
* @return 成功返回1;失败返回0
*/
public native static int ICGetICSnr(int iPort, int[] snr);
/**
* 获取ID卡物理卡号
* @param iPort 串口号
* @return 成功返回ID卡物理卡号(HexString);失败返回空串
*/
public native static String ICGetIDSnr(int iPort);
/**
* 修改扇区密码
* @param iPort 串口号
* @param keyMode keyA/KeyB
* @param Sector 扇区号(0~15)
* @param oldKey keyA/KeyB原始密码
* @param newKey 新密码
* @return 成功返回1;失败返回0
*/
public native static int ICChangeSectorPassword(int iPort, int keyMode, int Sector, String oldKey, String newKey);
/**
* 设置身份证头像透明阀值(RGB),3值均大于设置值透明
* @param R Red
* @param g green
* @param b blue
*/
public native static void SetTransparentThreshold(byte R, byte g, byte b);
/**
* 获取身份证指纹模板
* @return 返回横版身份证指纹模板Base64编码
*/
public native static String getFPDataBase64();
/**
* 获取证件类型
* @return 返回证件类型(1 二代证; 2 外国人永居证,3 港澳台居住证)
*/
public native static int getCardType();
/**
* 获取银行卡卡号
* @param iPort 串口号
* @return 成功返回ID卡银行卡卡号;失败返回空串
*/
public native static String ICGetBankCardNum(int iPort);
/**
* 获取港澳台居住证签证次数
* @return 签证次数
*/
public native static int getVisaTimes();
/**
* 获取港澳台居住证通行证号
* @return 返回港澳台居住证通行证号
*/
public native static String getPassNum();
/**
* 获取外国人英文名
* @return 返回外国人英文名
*/
public native static String getEnName();
/**
* 获取外国人中文名
* @return 返回外国人中文名
*/
public native static String getCnName();
}
至此就可以使用了,留下一点足迹