Java用身份证阅读器读取身份证的基本信息,阅读器型号为华旭(HX-FDX3S HX-FDX5)。
产品自带了几个Demo,唯独没有Java的。用Java写了个Demo.基本思路,用JNA调取原生sdtapi.dll进行操作。
封装DLL的操作类
package com.ic;
import com.sun.jna.Library;
import com.sun.jna.Native;
import com.sun.jna.ptr.IntByReference;
/***
* 身份证识别器类库(采用JNA开发)
* @author zdw
*
*/
public interface ICDll extends Library
{
ICDll instance = (ICDll)Native.loadLibrary("D:\\workspace\\myecipse\\nmq-makingcard\\sdtapi.dll", ICDll.class);
/***
* 打开端口
* @param port 1001~1016(十进制)为 USB 口。 例如:1001: USB1,1002,USB2
* @return
*/
public int SDT_OpenPort(int port);
/***
* 寻找居民身份证
* @param port 端口
* @param byManaID 存储导卡数据
* @param iIfOpen 自动打开设备标志。如果设置为1,则在接口内部自动实现打开设备和关闭设备,无需调用者再添加
* @return 0x9f 找卡成功。0x80 找卡失败。
*/
public int SDT_StartFindIDCard(int port,byte[] byManaID,int iIfOpen);
/****
* 选卡
* @param port 端口
* @param byManaID 存储选卡数据
* @param iIfOpen 自动打开设备标志。如果设置为1,则在接口内部自动实现打开设备和关闭设备,无需调用者再添加
* @return
*/
public int SDT_SelectIDCard(int port,byte[] byManaID,int iIfOpen);
/***
* 读取身份证基本信息(文字信息采用GB 13000的UCS-2进行存储对应java的 StandardCharsets.UTF_16LE编码)
* @param iPort 端口
* @param pucCHMsg 存储基本文字信息
* @param puiCHMsgLen 读取文字长度 0为全部 最大256.
* @param pucPHMsg 存储照片信息
* @param puiPHMsgLen 读取照片长度 0为全部 最大256.
* @param iIfOpen 自动打开设备标志。如果设置为1,则在接口内部自动实现打开设备和关闭设备,无需调用者再添加
* @return
*/
public int SDT_ReadBaseMsg(int iPort, byte[] pucCHMsg, IntByReference puiCHMsgLen, byte[] pucPHMsg, IntByReference puiPHMsgLen, int iIfOpen);
}
封装的工具类(注意编码)
package com.ic;
import java.nio.charset.StandardCharsets;
import java.util.Arrays;
import com.sun.jna.ptr.IntByReference;
/**
* 读身份证信息
* (流程:寻卡--选卡--读卡)
* @author zdw
*
*/
public class ICSDK
{
//存储基本文字信息
private byte[] byCHMsg = new byte[256 + 1];
//存储照片信息
private byte[] byPHMsg = new byte[1024 + 1];
public ICSDK()
{
byte[] byManaID = new byte[8];
//寻卡
Integer result = ICDll.instance.SDT_StartFindIDCard(1001, byManaID, 1);
System.out.println(Integer.toHexString(result));
byManaID = new byte[8];
//选卡
result = ICDll.instance.SDT_SelectIDCard(1001, byManaID, 1);
System.out.println(Integer.toHexString(result));
//读卡
result = ICDll.instance.SDT_ReadBaseMsg(1001, byCHMsg, new IntByReference(0), byPHMsg, new IntByReference(0), 1);
System.out.println(Integer.toHexString(result));
}
public static ICSDK getInstance()
{
return new ICSDK();
}
/**
* 获取姓名
* @return
*/
public String getName()
{
return new String(Arrays.copyOf(byCHMsg, 30), StandardCharsets.UTF_16LE);
}
/***
* 获取性别
* @return
*/
public String getGener()
{
return new String(Arrays.copyOfRange(byCHMsg, 30, 32), StandardCharsets.UTF_16LE);
}
/***
* 获取民族
* @return
*/
public String getNation()
{
return new String( Arrays.copyOfRange(byCHMsg, 32, 36), StandardCharsets.UTF_16LE);
}
/***
* 获取民族
* @return
*/
public String getBirth()
{
return new String(Arrays.copyOfRange(byCHMsg, 36, 52), StandardCharsets.UTF_16LE);
}
/***
* 获取住址
* @return
*/
public String getAddress()
{
return new String(Arrays.copyOfRange(byCHMsg, 52, 122), StandardCharsets.UTF_16LE);
}
/***
* 获取身份证号码
* @return
*/
public String getIc()
{
return new String(Arrays.copyOfRange(byCHMsg, 122, 158), StandardCharsets.UTF_16LE);
}
/***
* 发证单位
* @return
*/
public String getStation()
{
return new String(Arrays.copyOfRange(byCHMsg, 158, 188), StandardCharsets.UTF_16LE);
}
/***
* 有效开始日期
* @return
*/
public String getBegindate()
{
return new String(Arrays.copyOfRange(byCHMsg, 188, 204), StandardCharsets.UTF_16LE);
}
/***
* 有效结束日期
* @return
*/
public String getEnddate()
{
return new String(Arrays.copyOfRange(byCHMsg, 204, 220), StandardCharsets.UTF_16LE);
}
/***
* 最新地址
* @return
*/
public String getLateAddress()
{
return new String(Arrays.copyOfRange(byCHMsg, 220, 290), StandardCharsets.UTF_16LE);
}
public String getBaseAll()
{
return new String(byCHMsg, StandardCharsets.UTF_16LE);
}
}
测试类:
public class Dlltest {
public static void main(String[] args) {
ICSDK icsdk = ICSDK.getInstance();
System.out.println(icsdk.getName());
System.out.println(icsdk.getBaseAll());
}
}