需求:刷卡机插在电脑上,使用java代码读取身份证信息
实现:使用java Swing开发java客户端小程序,并生成可执行的exe文件。
使用工具及需要的jar:因为刷卡机的开发包是dll文件,dll文件里写的刷卡机程序的初始化,读卡等接口,需要先调用dll文件,才能使用其接口。
jna.jar ----用来读取dll文件的jar
需要的dll文件:
这些文件需要放到jdk的jre的bin目录下,且只支持32位的jdk。
exe4j ---- 把java程序做成可执行的exe软件的工具。
#############################################代码部分#########################################
//身份证信息类
public class IdReadDomain {
private String Name;
private String Gender;
private String Folk;
private String BirthDay;
private String Code;
private String Address;
private String Agency;
private String ExpireStart;
private String ExpireEnd;
private String Photo;
//读取dll文件里接口
public class SDTIDread {
static{
System.loadLibrary("libSDTJNIidcard"); //libSDTJNIidcard位dll文件名称
}
public static native int InitComm(); //初始化方法
public static native int Authenticate(); //身份证认证方法 用来判断是否放置了身份证
public static native int CloseComm(); //关闭接口
public static native IdReadDomain idReadDomain();
}
所需的c++编写的jni脚本文件,里面定义了dll里接口的名称和调用位置
例:Java_com_zax_SDTIDread_InitComm --- com_zax为包名,SDTIDread接口类,InitComm接口名:
/* DO NOT EDIT THIS FILE - it is machine generated */
#include
/* Header for class com_zax_SDTIDread */
#ifndef _Included_com_zax_SDTIDread
#define _Included_com_zax_SDTIDread
#ifdef __cplusplus
extern "C" {
#endif
/*
* Class: com_zax_SDTIDread
* Method: InitComm
* Signature: ()I
*/
JNIEXPORT jint JNICALL Java_com_zax_SDTIDread_InitComm
(JNIEnv *, jclass);
/*
* Class: com_zax_SDTIDread
* Method: Authenticate
* Signature: ()I
*/
JNIEXPORT jint JNICALL Java_com_zax_SDTIDread_Authenticate
(JNIEnv *, jclass);
/*
* Class: com_zax_SDTIDread
* Method: CloseComm
* Signature: ()I
*/
JNIEXPORT jint JNICALL Java_com_zax_SDTIDread_CloseComm
(JNIEnv *, jclass);
/*
* Class: com_zax_SDTIDread
* Method: idReadDomain
* Signature: ()Lcom/zax/IdReadDomain;
*/
JNIEXPORT jobject JNICALL Java_com_zax_SDTIDread_idReadDomain
(JNIEnv *, jclass);
#ifdef __cplusplus
}
#endif
#endif
测试类:
public static void main(String[] args) {
String result = "";
//HttpRequest request = new HttpRequest();
//初始化端口检查机器是否存在
int init = SDTIDread.InitComm();
if (init <= 0) {
System.out.println("设备没连接不是有效设备");
return;
} else {
if (SDTIDread.Authenticate() > 0) {
//检查卡片 读取信息
IdReadDomain test = SDTIDread.idReadDomain();
System.out.println("姓名:" + test.getName());
System.out.println("性别:" + test.getGender());
System.out.println("民族:" + test.getFolk());
System.out.println("出生:" + test.getBirthDay());
System.out.println("身份证号码:" + test.getCode());
System.out.println("住址:" + test.getAddress());
System.out.println("签发单位:" + test.getAgency());
System.out.println("有效期开始:" + test.getExpireStart());
System.out.println("有效期结束:" + test.getExpireEnd());
//System.out.println(Base64.PhotoJpg());
//System.out.println(Base64.PhotoBmp());
// System.err.println(Base64.PhotoCardJpg());
// SDTIDread.CloseComm();//关闭端口
} else {
System.out.println("没有检测到卡片");
return;
}
}
}
结果会在控制台打印出身份证信息。
接下来,新建刷卡类:
public class StartShuaKa {
public static void main(String[] args) {
JFrame jf = new JFrame("刷卡程序");
jf.setSize(600, 600);
jf.setLocationRelativeTo(null);
jf.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
//布局
JPanel panel = new JPanel();
//文本显示
JLabel label = new JLabel("程序开启.....");
/**
* 启动线程
* */
StartThread startThread =new StartThread();
Thread thread =new Thread(startThread);
thread.start();
panel.add(label);
jf.setContentPane(panel);
jf.setVisible(true);
}
}
在main方法中使用swing布局,生成exe文件时候,启动的是main方法,所以把逻辑写在线程类里,在启动main方法时,线程自动调用StartThread类里的逻辑。
线程类:
public class StartThread implements Runnable {
@Override
public void run() {
String url ="*************"; //业务需要调用的接口
while (sdktest.Init()>0){ //定义的初始化方法
while (sdktest.auth()){
String param ="idnumber="+sdktest.getInfo().getCode();
String result = HttpRequest.sendPost(url,param);
JSONObject jsonObject = JSONObject.fromObject(result);
String msg = (String) jsonObject.get("msg");
System.err.println("身份证号:"+sdktest.getInfo().getCode() +" "+ msg);
}
}
}
}
结果:
开启后,只要刷卡就会展示刷卡信息。