java连接 ZKTeco/中控 -打卡机/考勤机

article/2025/6/28 23:44:38

 连接步骤:
1. jacob-1.19版本;
2. 在resources目录下新建lib文件夹, 将jacob.jar 放入项目ib导入;
3. maven里导入本地jar包;
4.将jacob-1.19-x64.dll 放入64位 jre/bin目录下;
5.将中控考勤机sdk 的dll文件全部放入 c:\windows\system32 目录下;
6.运行cmd 注册zkemkeeper.dll —>regsvr32 c:\windows\system32\zkemkeeper.dll (也可以使用 自动注册.bat,不行的话就要放在64位里面)
7.已经配置完毕,进行代码测试;

我看了很多的文章,在这里有一个坑就是zkemkeeper.dll文件没有,这个的话就需要你找客服去要,(客服有可能给的也是错的,就要找客服给技术人员,你就找技术人员去要)而且还没人分享出来,下面就是我分享出来的 jacob-1.19.jar下载和控考勤机sdk

链接:java链接考勤机https://wwtx.lanzout.com/b04w8t9ra
提取码:azss

开始教程

1.

将jacob-1.19.dll放入jdk1.8中的bin

 找到这个jar把他复制到

新建一个lib然后放进去

 这个代码是调用自己的lib中的jar包

        <dependency><groupId>com.zkem</groupId><artifactId>jacob</artifactId><version>1.19</version><scope>system</scope><systemPath>${project.basedir}/src/main/resources/lib/jacob.jar</systemPath></dependency>

这样就配置好了jacob.jar包了

1-1.

还有一个就是部署到服务器中就访问不到的一个问题

其他的不总要,只要吧enabled设置位true就可以了,说的就是访问自己的lib

            <releases><enabled>true</enabled></releases>

2

下面就是将文件复制到c:\windows\system32和c:\windows\system64中,最重要的是记得注册zkemkeeper.dll

注册方法 在 zkemkeeper.dll文件夹的路径输入cmd,在命令窗口输入  regsvr32 zkemkeeper.dll

就可以进行注册

 3.

下面就是主要的代码部分了

实体类

package com.ruoyi.web.attendanceMachine;import java.util.Map;/*** 获取缓存中的考勤数据。配合readGeneralLogData / readLastestLogData使用。*      **      * @return 返回的map中,包含以下键值:*      * "EnrollNumber"   人员编号*      * "Time"           考勤时间串,格式: yyyy-MM-dd HH:mm:ss*      * "VerifyMode"     验证方式  1:指纹 2:面部识别*      * "InOutMode"      考勤状态 0:上班 1:下班 2:外出 3:外出返回 4:加班签到 5:加班签退*      * "Year"          考勤时间:年*      * "Month"         考勤时间:月*      * "Day"           考勤时间:日*      * "Hour"            考勤时间:时*      * "Minute"        考勤时间:分*      * "Second"        考勤时间:秒**/
public class LogData {private String Year;private String Hour;private String InOutMode;private String Time;private String InOutMode1;private String Second;private String Minute;private String EnrollNumber;private String Day;private String Month;private String VerifyMode;private String Hms;public Map<String, Object> userInfo;public LogData(String year, String hour, String inOutMode, String time, String inOutMode1, String second, String minute, String enrollNumber, String day, String month, String verifyMode) {Year = year;Hour = hour;InOutMode = inOutMode;Time = time;InOutMode1 = inOutMode1;Second = second;Minute = minute;EnrollNumber = enrollNumber;Day = day;Month = month;VerifyMode = verifyMode;}public Map<String, Object>  getUserInfo() {return userInfo;}public void setUserInfo(Map<String, Object>  userInfo) {this.userInfo = userInfo;}public String getYear() {return Year;}public String getHms() {return Hms;}public void setHms(String hms) {Hms = hms;}public void setYear(String year) {Year = year;}public String getHour() {return Hour;}public void setHour(String hour) {Hour = hour;}public String getInOutMode() {return InOutMode;}public void setInOutMode(String inOutMode) {InOutMode = inOutMode;}public String getTime() {return Time;}public void setTime(String time) {Time = time;}public String getInOutMode1() {return InOutMode1;}public void setInOutMode1(String inOutMode1) {InOutMode1 = inOutMode1;}public String getSecond() {return Second;}public void setSecond(String second) {Second = second;}public String getMinute() {return Minute;}public void setMinute(String minute) {Minute = minute;}public String getEnrollNumber() {return EnrollNumber;}public void setEnrollNumber(String enrollNumber) {EnrollNumber = enrollNumber;}public String getDay() {return Day;}public void setDay(String day) {Day = day;}public String getMonth() {return Month;}public void setMonth(String month) {Month = month;}public String getVerifyMode() {return VerifyMode;}public void setVerifyMode(String verifyMode) {VerifyMode = verifyMode;}public LogData(){}
};

package com.ruoyi.web.attendanceMachine;import com.jacob.com.Variant;public class UserInfo {private String name;private Boolean Enabled;private String Password;private Integer Privilege;private String EnrollNumber;public Variant zw;public UserInfo(String name, Boolean enabled, String password, Integer privilege, String enrollNumber) {this.name = name;Enabled = enabled;Password = password;Privilege = privilege;EnrollNumber = enrollNumber;}public Variant getZw() {return zw;}public void setZw(Variant zw) {this.zw = zw;}public String getName() {return name;}public void setName(String name) {this.name = name;}public Boolean getEnabled() {return Enabled;}public void setEnabled(Boolean enabled) {Enabled = enabled;}public String getPassword() {return Password;}public void setPassword(String password) {Password = password;}public Integer getPrivilege() {return Privilege;}public void setPrivilege(Integer privilege) {Privilege = privilege;}public String getEnrollNumber() {return EnrollNumber;}public void setEnrollNumber(String enrollNumber) {EnrollNumber = enrollNumber;}public UserInfo(){};
}

 监听模块

package com.ruoyi.web.attendanceMachine;import com.jacob.com.Variant;
import com.ruoyi.common.annotation.DataSource;
import com.ruoyi.common.enums.DataSourceType;
import com.ruoyi.common.utils.DateUtils;
import com.ruoyi.common.utils.spring.SpringUtils;
import com.ruoyi.system.service.IUserinfoService;
import com.ruoyi.web.controller.mmt.UserinfoController;
import org.springframework.beans.factory.annotation.Autowired;
import com.ruoyi.system.domain.Userinfo;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
@DataSource(value = DataSourceType.MASTER)
public class SensorEvents {public IUserinfoService userinfoService;public void OnConnected(Variant[] arge){System.out.println("当成功连接机器时触发该事件,无返回值====");}public void OnDisConnected(Variant[] arge){System.out.println("当断开机器时触发该事件,无返回值====");}public void OnAlarm(Variant[] arge){System.out.println("当机器报警时触发该事件===="+arge);}public void OnAttTransactionEx(Variant[] arge){System.out.println("id:"+arge[0]);System.out.println("是否有效:0有效 1无效"+arge[1]);System.out.println("考勤状态:0 上班 1下班 2外出 3外出返回 4 加班签到 5 加班签退...."+arge[2]);System.out.println("验证方式 0:密码  1;指纹 15:刷脸认证"+arge[3]);System.out.println("验证时间"+arge[4]+"-"+arge[5]+"-"+arge[6]+"-"+arge[7]+":"+arge[8]+":"+arge[9]+" "+arge[10]);/*for (int i = 0; i < arge.length; i++) {System.out.println(arge[i]);}*///System.out.println(arge.toString());System.out.println("当验证通过时触发该事件====**"+arge);}public void OnEnrollFingerEx(Variant[] arge){System.out.println("登记指纹时触发该事件===="+arge.clone());}public void OnFinger(Variant[] arge){System.out.println("当机器上指纹头上检测到有指纹时触发该消息,无返回值");}public void OnFingerFeature(Variant[] arge){System.out.println("登记用户指纹时,当有指纹按下时触发该消息===="+arge);}public void OnHIDNum(Variant[] arge){System.out.println("当刷卡时触发该消息===="+arge);}
//添加新用户public void OnNewUser(Variant[] arge){}public void OnVerify(Variant[] arge){System.out.println("当用户验证时触发该消息===="+arge);}public void OnWriteCard(Variant[] arge){System.out.println("当机器进行写卡操作时触发该事件===="+arge);}public void OnEmptyCard(Variant[] arge){System.out.println("当清空 MIFARE 卡操作时触发该事件===="+arge);}public void OnEMData(Variant[] arge){System.out.println("当机器向 SDK 发送未知事件时,触发该事件===="+arge);}} 

实现代码

package com.ruoyi.web.attendanceMachine;import com.alibaba.fastjson2.JSON;
import com.jacob.activeX.ActiveXComponent;
import com.jacob.com.Dispatch;
import com.jacob.com.DispatchEvents;
import com.jacob.com.STA;
import com.jacob.com.Variant;
import com.ruoyi.common.utils.DateUtils;
import com.ruoyi.system.domain.Userinfo;
import com.ruoyi.system.service.IUserinfoService;
import com.ruoyi.web.controller.mmt.Main;import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.*;/*** 中控考勤机sdk函数调用类* @author wangchao**/
public class ZkemSDK {private static ActiveXComponent zkem = new ActiveXComponent("zkemkeeper.ZKEM.1");private Fingerprint fingerprint = null;/*** 链接考勤机** @param address 考勤机地址* @param port    端口号* @return*/public boolean connect(String address, int port) {boolean result = zkem.invoke("Connect_NET", address, port).getBoolean();return result;}/*** 断开考勤机链接*/public void disConnect() {zkem.invoke("Disconnect");}/*** 读取考勤记录到pc缓存。配合getGeneralLogData使用** @return*/public static boolean readGeneralLogData() {boolean result = zkem.invoke("ReadGeneralLogData", 4).getBoolean();return result;}/*** 读取该时间之后的最新考勤数据。 配合getGeneralLogData使用。//网上说有这个方法,但是我用的开发文档没有这个方法,也调用不到,我在controller中处理获取当天数据** @param lastest* @return*/public static boolean readLastestLogData(Date lastest) {boolean result = zkem.invoke("ReadLastestLogData", 2018 - 07 - 24).getBoolean();return result;}/*** 获取缓存中的考勤数据。配合readGeneralLogData / readLastestLogData使用。** @return 返回的map中,包含以下键值:* "EnrollNumber"   人员编号* "Time"           考勤时间串,格式: yyyy-MM-dd HH:mm:ss* "VerifyMode"     验证方式  1:指纹 2:面部识别* "InOutMode"      考勤状态 0:上班 1:下班 2:外出 3:外出返回 4:加班签到 5:加班签退* "Year"          考勤时间:年* "Month"         考勤时间:月* "Day"           考勤时间:日* "Hour"            考勤时间:时* "Minute"        考勤时间:分* "Second"        考勤时间:秒*/public static List<Map<String, Object>> getGeneralLogData() {Variant dwMachineNumber = new Variant(1, true);//机器号Variant dwEnrollNumber = new Variant("", true);Variant dwVerifyMode = new Variant(0, true);Variant dwInOutMode = new Variant(0, true);Variant dwYear = new Variant(0, true);Variant dwMonth = new Variant(0, true);Variant dwDay = new Variant(0, true);Variant dwHour = new Variant(0, true);Variant dwMinute = new Variant(0, true);Variant dwSecond = new Variant(0, true);Variant dwWorkCode = new Variant(0, true);List<Map<String, Object>> strList = new ArrayList<Map<String, Object>>();boolean newresult = false;do {Variant vResult = Dispatch.call(zkem, "SSR_GetGeneralLogData", dwMachineNumber, dwEnrollNumber, dwVerifyMode, dwInOutMode, dwYear, dwMonth, dwDay, dwHour, dwMinute, dwSecond, dwWorkCode);newresult = vResult.getBoolean();if (true) {String enrollNumber = dwEnrollNumber.getStringRef();//如果没有编号,则跳过。// if (enrollNumber == null || enrollNumber.trim().length() == 0)// continue;String month = dwMonth.getIntRef() + "";String day = dwDay.getIntRef() + "";if (dwMonth.getIntRef() < 10) {month = "0" + dwMonth.getIntRef();}if (dwDay.getIntRef() < 10) {day = "0" + dwDay.getIntRef();}String validDate = dwYear.getIntRef() + "-" + month + "-" + day;//String currentDate = DateUtils.getCurrentTime("yyyy-MM-dd");String currentDate = DateUtils.getDate();if (true) {Map<String, Object> m = new HashMap<String, Object>();//Map<String, Object> user = getUserInfoByNumber(enrollNumber);m.put("EnrollNumber", enrollNumber);m.put("Time", dwYear.getIntRef() + "-" + dwMonth.getIntRef() + "-" + dwDay.getIntRef() + " " + dwHour.getIntRef() + ":" + dwMinute.getIntRef() + ":" + dwSecond.getIntRef());m.put("VerifyMode", dwVerifyMode.getIntRef());m.put("InOutMode", dwInOutMode.getIntRef());m.put("Year", dwYear.getIntRef());m.put("Month", dwMonth.getIntRef());m.put("Day", dwDay.getIntRef());m.put("Hour", dwHour.getIntRef());m.put("Minute", dwMinute.getIntRef());m.put("Second", dwSecond.getIntRef());strList.add(m);}}} while (newresult == true);return strList;}/*** 获取用户信息** @return 返回的Map中,包含以下键值:* "EnrollNumber"  人员编号* "Name"          人员姓名* "Password"      人员密码* "Privilege"     特权 0位普通 3特权* "Enabled"       是否启用*/public static List<UserInfo> getUserInfo() {List<UserInfo> userInfoList = new LinkedList<>();List<Map<String, Object>> resultList = new ArrayList<Map<String, Object>>();//将用户数据读入缓存中。boolean result = zkem.invoke("ReadAllUserID", 1).getBoolean();Variant v0 = new Variant(1);Variant sdwEnrollNumber = new Variant("", true);Variant sName = new Variant("", true);Variant sPassword = new Variant("", true);Variant iPrivilege = new Variant(0, true);Variant bEnabled = new Variant(false, true);while (result) {//从缓存中读取一条条的用户数据result = zkem.invoke("SSR_GetAllUserInfo", v0, sdwEnrollNumber, sName, sPassword, iPrivilege, bEnabled).getBoolean();//如果没有编号,跳过。String enrollNumber = sdwEnrollNumber.getStringRef();if (enrollNumber == null || enrollNumber.trim().length() == 0)continue;//由于名字后面会产生乱码,所以这里采用了截取字符串的办法把后面的乱码去掉了,以后有待考察更好的办法。//只支持2位、3位、4位长度的中文名字。String name = sName.getStringRef();int index = name.indexOf("\0");String newStr = "";if (index > -1) {name = name.substring(0, index);}if (sName.getStringRef().length() > 4) {name = sName.getStringRef().substring(0, 4);}//如果没有名字,跳过。if (name.trim().length() == 0)continue;UserInfo userInfo = new UserInfo();userInfo.setEnrollNumber(enrollNumber);userInfo.setName(name);userInfo.setPassword(sPassword.getStringRef());userInfo.setPrivilege(iPrivilege.getIntRef());userInfo.setEnabled((Boolean) bEnabled.getBooleanRef());userInfoList.add(userInfo);}return userInfoList;}/*** 设置用户信息** @param number* @param name* @param password* @param isPrivilege 0為普通用戶,3為管理員;* @param enabled     是否啟用* @return*/public static boolean setUserInfo(String number, String name, String password, int isPrivilege, boolean enabled) {Variant v0 = new Variant(1);Variant sdwEnrollNumber = new Variant(number, true);Variant sName = new Variant(name, true);Variant sPassword = new Variant(password, true);Variant iPrivilege = new Variant(isPrivilege, true);Variant bEnabled = new Variant(enabled, true);boolean result = zkem.invoke("SSR_SetUserInfo", v0, sdwEnrollNumber, sName, sPassword, iPrivilege, bEnabled).getBoolean();return result;}/*** 获取用户信息** @param number 考勤号码* @return*/public static Map<String, Object> getUserInfoByNumber(String number) {Variant v0 = new Variant(1);Variant sdwEnrollNumber = new Variant(number, true);Variant sName = new Variant("", true);Variant sPassword = new Variant("", true);Variant iPrivilege = new Variant(0, true);Variant bEnabled = new Variant(false, true);boolean result = zkem.invoke("SSR_GetUserInfo", v0, sdwEnrollNumber, sName, sPassword, iPrivilege, bEnabled).getBoolean();if (result) {Map<String, Object> m = new HashMap<String, Object>();m.put("EnrollNumber", number);m.put("Name", sName.getStringRef());m.put("Password", sPassword.getStringRef());m.put("Privilege", iPrivilege.getIntRef());m.put("Enabled", bEnabled.getBooleanRef());return m;}return null;}/*** 获取用户信息** @param number 考勤号码* @return*/public static String getUserInfoByName(String number) {Variant v0 = new Variant(1);Variant sdwEnrollNumber = new Variant(number, true);Variant sName = new Variant("", true);Variant sPassword = new Variant("", true);Variant iPrivilege = new Variant(0, true);Variant bEnabled = new Variant(false, true);boolean result = zkem.invoke("SSR_GetUserInfo", v0, sdwEnrollNumber, sName, sPassword, iPrivilege, bEnabled).getBoolean();System.out.println(sName+"-"+sPassword+"-"+iPrivilege+"-"+bEnabled);return sName.getStringRef();}public static Userinfo getUserInfoByNames(Userinfo userinfo) {Variant v0 = new Variant(1);Variant sdwEnrollNumber = new Variant(userinfo.getEnrollNumber(), true);Variant sName = new Variant("", true);Variant sPassword = new Variant("", true);Variant iPrivilege = new Variant(0, true);Variant bEnabled = new Variant(false, true);boolean result = zkem.invoke("SSR_GetUserInfo", v0, sdwEnrollNumber, sName, sPassword, iPrivilege, bEnabled).getBoolean();userinfo.setEnrollNumber(String.valueOf(sdwEnrollNumber));userinfo.setName(String.valueOf(sName));userinfo.setPassword(String.valueOf(sPassword));return userinfo;}//获取指纹public static Variant GetUserTmpStr(String i) {Variant v0 = new Variant(1);byte temp = 0;Variant b = new Variant(i, true);Variant c = new Variant(1, true);Variant d = new Variant("", true);Variant e = new Variant(0, true);/*    Variant dwMachineNumber = new Variant(0, true);//机器号Variant dwEnrollNumber = new Variant(0, true);//用户号Variant dwFingerIndex = new Variant(0, true);//指纹索引号Variant TmpData = new Variant(0, true);//该参数返回指纹模板数据Variant TmpLength = new Variant(0, true);//该参数返回指纹模板长度*/boolean result = zkem.invoke("SSR_GetUserTmpStr",v0, b, c, d,e).getBoolean();System.out.println("1:"+d.toString());System.out.println("2:"+result);return d;}//上传指纹public static void SetUserTmpStr(String x,Variant d) {Variant v0 = new Variant(1);Variant a = new Variant(x, true);Variant b = new Variant(2, true);Variant c = d;
/*    Variant dwMachineNumber = new Variant(0, true);//机器号Variant dwEnrollNumber = new Variant(0, true);//用户号Variant dwFingerIndex = new Variant(0, true);//指纹索引号Variant TmpData = new Variant(0, true);//该参数返回指纹模板数据Variant TmpLength = new Variant(0, true);//该参数返回指纹模板长度*/boolean result = zkem.invoke("SSR_SetUserTmpStr", v0, a, b, c).getBoolean();System.out.println("3:"+c.toString());System.out.println("4:"+result);}//删除public static void ReadAllTemplate() {Variant v0 = new Variant(1);// Variant dwMachineNumber = new Variant(0, true);//机器号Variant dwEnrollNumber = new Variant("1", true);//用户号Variant dwFingerIndex = new Variant(6, true);//指纹索引号//  Variant TmpData = new Variant(0, true);//该参数返回指纹模板数据//  Variant TmpLength = new Variant(0, true);//该参数返回指纹模板长度boolean result = zkem.invoke("SSR_DelUserTmp", v0,dwEnrollNumber,dwFingerIndex).getBoolean();}/*** 查詢所有/指定ID的打卡信息;** @param userNumber* @return*/public static List<LogData> getUserOneDayInfo(Object userNumber) {ZkemSDK sdk = new ZkemSDK();Map<String, Object> userInfo = new HashMap<String, Object>();List<LogData> logDateList = new ArrayList<>();//连接考勤机;boolean connect = sdk.connect("192.168.1.189", 4370);if (connect) {List<Map<String, Object>> generalLogDataAll = ZkemSDK.getGeneralLogData();for (int i = 0; i < generalLogDataAll.size(); i++) {//System.out.println(generalLogDataAll.get(i));String Year = String.valueOf(generalLogDataAll.get(i).get("Year"));String Hour = String.valueOf(generalLogDataAll.get(i).get("Hour"));String InOutMode = String.valueOf(generalLogDataAll.get(i).get("InOutMode"));String Time = String.valueOf(generalLogDataAll.get(i).get("Time"));String Second = String.valueOf(generalLogDataAll.get(i).get("Second"));String Minute = String.valueOf(generalLogDataAll.get(i).get("Minute"));String EnrollNumber = String.valueOf(generalLogDataAll.get(i).get("EnrollNumber"));String Day = String.valueOf(generalLogDataAll.get(i).get("Day"));String Month = String.valueOf(generalLogDataAll.get(i).get("Month"));String VerifyMode = String.valueOf(generalLogDataAll.get(i).get("VerifyMode"));LogData logData = new LogData();logData.setYear(Year);logData.setHour(Hour);logData.setInOutMode1(InOutMode);logData.setTime(Time);logData.setSecond(Second);logData.setMinute(Minute);logData.setEnrollNumber(EnrollNumber);logData.setDay(Day);logData.setMonth(Month);logData.setVerifyMode(VerifyMode);if (EnrollNumber.equals(userNumber) && userNumber != null) {logDateList.add(logData);} else if (userNumber == null) {logDateList.add(logData);}}return logDateList;}return null;}/*** 删除用户;*/public static Boolean delectUserById(String dwEnrollNumber) {Variant v0 = new Variant(1);Variant sdwEnrollNumber = new Variant(dwEnrollNumber, true);/*** sdwBackupNumber:* 一般范围为 0-9,同时会查询该用户是否还有其他指纹和密码,如都没有,则删除该用户* 当为 10 是代表删除的是密码,同时会查询该用户是否有指纹数据,如没有,则删除该用户* 11 和 13 是代表删除该用户所有指纹数据,* 12 代表删除该用户(包括所有指纹和卡号、密码数据)*/Variant sdwBackupNumber = new Variant(12);/*** 删除登记数据,和 SSR_DeleteEnrollData 不同的是删除所有指纹数据可用参数 13 实现,该函数具有更高效率*/return zkem.invoke("SSR_DeleteEnrollDataExt", v0, sdwEnrollNumber, sdwBackupNumber).getBoolean();}/*** 考勤机链接测试** @author wangchao*/public static void main(String[] args) {ZkemSDK sdk = new ZkemSDK();/*172.31.136.170*/boolean connFlag = sdk.connect("192.168.1.201", 4370);System.out.println("conn:" + connFlag);boolean readGeneralLogData = sdk.readGeneralLogData();System.out.println("读取打卡机信息到缓存:" + readGeneralLogData);/*	sdk.getUserInfss(sdk.getUserInfs());*///如果连接打卡机和读取信息到缓存都没问题再去缓存中获取数据if (connFlag || readGeneralLogData) {//获取打卡机所有的用户信息List<UserInfo> userInfo = sdk.getUserInfo();//转化为JSON字符串String usersJsonString = JSON.toJSONString(userInfo);//反序列化对象List<UserInfo> userInfos = JSON.parseArray(usersJsonString, UserInfo.class);userInfos.forEach(System.out::println);for (UserInfo info : userInfos) {String name = info.getName();Boolean enabled = info.getEnabled();String pwd = info.getPassword();Integer privilege = info.getPrivilege();String enrollNumber = info.getEnrollNumber();Integer userId = Integer.valueOf(enrollNumber);System.out.println(name + "-" + enabled + "-" + pwd + "-" + privilege + "-" + userId + "");}
/*			List<Map<String, Object>> generalLogData = sdk.getGeneralLogData();
//            logger.info("考勤信息:{}",generalLogData);String logDataJsonString = JSON.toJSONString(generalLogData);List<LogData> logDatas = JSON.parseArray(logDataJsonString, LogData.class);logDatas.forEach(System.out::println);for (LogData data : logDatas) {//打卡机的时间String time = data.getTime();String enrollNumber = data.getEnrollNumber();*//*** data有很多的数据,可以根据自己的业务逻辑拿想要的数据* 我这里只取了打卡时间和enrollNumber**//*Map<String, Object> userInfoByNumber = getUserInfoByNumber(enrollNumber);System.out.println("时间:" + time + "            用户id:" + enrollNumber);}*/}}/*** 启动事件监听*/public void  regEvent(IUserinfoService userinfoService){zkem.invoke("RegEvent", new Variant(1), new Variant(65535));zkem.invoke("ReadRTLog", new Variant(1));zkem.invoke("GetRTLog", new Variant(1));SensorEvents sensorEvents = new SensorEvents();sensorEvents.userinfoService=userinfoService;new DispatchEvents(zkem.getObject(), sensorEvents);//开启监听方法new STA().doMessagePump();
//        new STA().doMessagePump();}
}

而这个是中控提供的方法 

好的,你已经完成了配置 考勤机/打卡机了

希望可以可怜可怜我给一个三连吧


http://chatgpt.dhexx.cn/article/7UBYii0M.shtml

相关文章

汉王考勤管理系统教程

&#x1f447;教程&#x1f447; 人脸识别考勤简介 汉王人脸识别考勤系统是由人脸识别考勤机、考勤管理软件两部分组成。电脑驱动程序就是考勤管理软件。 人脸识别考勤机可独立使用&#xff0c;无需连接电脑&#xff0c;即可完成人脸登记、刷脸考勤、存储记录等功能。 考勤机…

钉钉考勤报表生成工具

钉钉考勤报表生成工具---考勤助手 概述 考勤助手是一款针对钉钉考勤、企业微信考勤报表统计工具软件。用户导入钉钉考勤数据&#xff0c;自动生成企业组织结构图&#xff0c;自动生成员工每月考勤打卡明细表、月度考勤汇总表等。软件具有员工生日提醒、劳动合同续签到期提醒、…

java连接带通讯密码的中控考勤机 iface702

java连接带通讯密码的中控考勤机 iface702 java连接中控考勤机导入jacob.jar 1.19版本jacob-1.19-x86.dllzkemkeeper.dll考勤机连接代码iFace系列脱机通讯开发包开发手册 java连接中控考勤机 jdk1.8 32位 文章资源 https://download.csdn.net/download/weixin_47881155/161…

得力人脸识别考勤机密码设置_人脸指纹混合识别考勤机得力怎么使用

展开全部 具体步骤如下: ①安装好设备并给设备通电。 ②进32313133353236313431303231363533e59b9ee7ad9431333365666233入【设置】一栏就可以进行用户登记,人脸指纹登记、设置密码,分配权限。 ③然后进入进行用户验证,确认登记人脸、指纹、密码是否可用。 ④检查设备时间是…

得力考勤机excel密码_可以修改原始考勤记录数据的是哪种人脸指纹考勤机?

目前很多工厂、企业、机关单位、公司、酒店、餐厅、学校、医院、超市等行业都已经安装使用了指纹考勤机、指纹打卡机、以及人脸识别考勤机。指纹考勤机和人脸识别考勤机的使用,规范了公司考勤管理制度,提升了公司整体形象,体现了“公平”“公正”“平等”,提高了企业的工作…

得力考勤机excel密码_考勤机

一、考勤机盛图-T500 ◀点开我了解更多 人脸+指纹+密码三合一,指纹容量3000枚,人脸容量500张,超长兼容,识别速度快,操作简易 二、S600 指纹容量1000枚,记录容量100000条,采用高精度全反光学采集器,识别速度快,高清TFT彩屏,免安装软件,U盘数据上传下载,操…

Version 28 (intended for Android Pie and below) is the last version of the legacy support library, s

刚开始建项目 会出现 Version 28 (intended for Android Pie and below) is the last version of the legacy support library, so we recommend that you migrate to AndroidX libraries when using Android Q and moving forward. The IDE can help with this: Refactor &g…

三星s8android pie,三星修改Galaxy S8的Android Pie更新时间表,并添加M2

原标题&#xff1a;三星修改Galaxy S8的Android Pie更新时间表&#xff0c;并添加M2 玩懂手机网1月25日资讯&#xff0c;三星为Android 9.0 Pie的One UI新系统专有用户界面投入了大量的精力&#xff0c;这也同时表示三星将会为该系统带去更多好用和明显区别于别的系统的功能&am…

android 9 pie公司,谷歌Android 9 Pie,真正的安卓派

IT之家8月7日消息 今天谷歌正式宣布了Android 9 Pie正式版系统&#xff0c;此前的Android P终于定名为Android Pie&#xff0c;该更新首先面向谷歌Pixel设备和Essential Phone手机推送&#xff0c;索尼、小米、HMD、OPPO、vivo、一加等厂商将在今年秋季获得安卓9正式版。每一代…

android9 0正式版,安卓9.0系统正式版|Android Pie 9.0 正式版 - 天天游戏吧

谷歌Android P正式版&#xff0c;其实也是Android 9.0系统&#xff0c;代号为Android Pie&#xff0c;Pie意义为“馅饼”&#xff0c;这是Android的第九个大版本。 Android 9 Pie最大的更新亮点无疑就是原生手势操作和刘海屏深度优化&#xff0c;此外还有Adaptive Battery(自适…

android 5.0 pie,Android各版本份额占比出炉:Android Pie仍未知

据最新的数据显示&#xff0c;有19.2%的设备装载Android8.0 Oreo系统&#xff0c;相比起上个月的数据来说有了不错的提升达到4.6个百分点&#xff0c;甚至还要比去年的安卓7.0要高出3.4个百分点。2016发布Android 7.07.1 Nougat系统的安卓以29.3%占走了安卓Pie的大部分份额。 另…

三星s8android pie,三星更改Galaxy S8的Android Pie更新计划,添加Gala

原标题&#xff1a;三星更改Galaxy S8的Android Pie更新计划&#xff0c;添加Gala 毫无疑问&#xff0c;三星在其简化的安卓9.0版用户界面上投入了大量的精力&#xff0c;这自然意味着三星正式推送Android Pie的最新版本的时间明显迟于其他品牌高端手机的类似更新。 不过事情似…

安卓学习专栏——安卓报错Version 28 (intended for Android Pie and below) is the last version of the legacy suppor

步骤 系列文章前言1.报错效果2.修改方法 总结 系列文章 提示&#xff1a;转到安卓学习专栏&#xff0c;观看更多内容&#xff01; 点我直达–>安卓学习专栏 前言 com.android.support:appcompat-v7:24.2.1’飘红 报错Version 28 (intended for Android Pie and below) is …

2021-08-25 Android studio 编译提示Version 28 (intended for Android Pie and below) is the last version of

一、如下提示 Version 28 (intended for Android Pie and below) is the last version of the legacy support library, so we recommend that you migrate to AndroidX libraries when using Android Q and moving forward. The IDE can help with this: Refactor> Migr…

android 9 pie公司,Android 9.0正式推送 定名Android Pie

【IT168 手机讯】北京时间8月7日早间&#xff0c;谷歌率先面向Pixel系列手机推送了Android P正式版(Essential也第一时间升级)&#xff0c;代号“Pie”&#xff0c;这也是Android的第九代正式更新。 对于Android P的命名在正式发布之前众说纷纭&#xff0c;现在看来&#xff0c…

小米2s Android pie,抢先体验Android Pie 小米MIX 2s已收到推送

原标题&#xff1a;抢先体验Android Pie 小米MIX 2s已收到推送 [ 【IT168 手机讯】就在北京时间8月7日凌晨&#xff0c;谷歌推送了Android 9.0的正式版&#xff0c;并将其命名为“Pie”&#xff0c;首批适配的机型包含Pixel以及Essential Phone两大系列的手机&#xff0c;而在测…

联想z5 android pie,联想z5成功吃上安卓pie

昨天上了趟XDA论坛发现AOSP9.0的通刷包Phh-Treble出来了。(下载地址在最后面) 能吃上屁了 如丝滑般流畅&#xff0c;响应速度比以前快了。 1.网络老毛病 设置成4g只能上网&#xff0c;3g能打电话&#xff0c;发短信&#xff0c;上网(可能是国内外环境不一样) 2.无自动亮度(有通…

三星android pie,三星Galaxy系列Android 9.0 Pie

原标题&#xff1a;三星Galaxy系列Android 9.0 Pie IT之家10月8日消息 安卓9.0 Pie发布也有一段时间了&#xff0c;除了谷歌自家的Pixel系列之外&#xff0c;华为、小米、一加、诺基亚等都已经适配了对应的安卓9.0 Pie的测试版本&#xff0c;三星目前到还没有关于升级安卓9.0 P…

三星Android Pie软件,三星开始向欧洲Galaxy S9用户推送Android Pie稳定版更新包

在经过近两个月的测试后&#xff0c;三星终于开始向欧洲市场推送 Galaxy S9 / S9 的 Android 9.0 Pie 稳定版更新包。上个月&#xff0c;随着 Android Pie 公众测试的开启&#xff0c;这家韩国科技巨头为 Galaxy S9 系列带来了全新的 One UI 。今日的更新包容量超过了 1.7GB&am…

android pie华为更新,华为多款机型近期将迎来Android Pie系统更新,下列这几款肯定有你...

原标题&#xff1a;华为多款机型近期将迎来Android Pie系统更新&#xff0c;下列这几款肯定有你 近日华为正式宣布将会对面向于国际版的部分华为机型推送基于Android Pie的EMUI9.0系统更新。而推出的时间也是以用户收到为准&#xff0c;面向不同国家的机型&#xff0c;推出的时…