java读取IC卡设备

有几个项目都用到IC卡设备,IC卡供应商提供的例程里没有java的例子,调试过程发现各种问题,总算是测试通过了,mark一下.

       基本思路:通过JNative.jar包调用dll方式,读取IC卡的序列号.

       代码:

       

package com.test;

import org.xvolks.jnative.JNative;
import org.xvolks.jnative.Type;
import org.xvolks.jnative.exceptions.NativeException;
import org.xvolks.jnative.misc.basicStructures.HANDLE;
import org.xvolks.jnative.pointers.Pointer;
import org.xvolks.jnative.pointers.memory.MemoryBlockFactory;

public class TestConn {

	static Pointer pointer;

	/**
	 *打开连接
	 * 
	 * @param port
	 *            串口号,取值为0~3
	 * @param baud
	 *            通讯波特率9600~115200
	 * @return 通讯设备标识符
	 * @throws NativeException
	 * @throws IllegalAccessException
	 */
	private static final int TestConnect(int port, long baud)
			throws NativeException, IllegalAccessException {
		JNative n = null;
		try {
			n = new JNative("iccrf.dll", "rf_init"); // 加载函数对象
			n.setRetVal(Type.INT); // 设置函数返回值类型
			int i = 0; // 设置参数顺序
			n.setParameter(i++, Type.INT, "" + port); // 设值
			n.setParameter(i++, Type.INT, "" + baud); // 设置
			System.out.println("调用的DLL文件名为:" + n.getDLLName());
			System.out.println("调用的方法名为:" + n.getFunctionName());

			n.invoke(); // 调用函数

			// System.out.println(n.getRetVal());

		} finally {
			if (n != null)
				n.dispose(); // 关闭
		}
		return Integer.parseInt(n.getRetVal()); // 函数返回值
	}

	/**
	 * 创建指针,用于接收调用函数的返回值
	 * 
	 * @return
	 * @throws NativeException
	 */
	public Pointer creatPointer() throws NativeException {

		pointer = new Pointer(MemoryBlockFactory.createMemoryBlock(10000));// 分配的内存大小
		return pointer;

	}

	/**
	 * 蜂鸣控制
	 * 
	 * @param icdev
	 *            通讯设备标识符
	 * @param msec
	 *            蜂鸣时间,单位10毫秒
	 * @return
	 * @throws NativeException
	 * @throws IllegalAccessException
	 */
	private String testBeep(int icdev, int msec) throws NativeException,
			IllegalAccessException {
		JNative n = null;
		try {
			n = new JNative("iccrf.dll", "rf_beep"); // 加载函数对象
			n.setRetVal(Type.INT); // 设置函数返回值类型
			int i = 0; // 设置参数顺序
			n.setParameter(i++, icdev);
			n.setParameter(i++, msec); // 设值
			System.out.println("调用的DLL文件名为:" + n.getDLLName());
			System.out.println("调用的方法名为:" + n.getFunctionName());

			n.invoke(); // 调用函数
		} finally {
			if (n != null)
				n.dispose(); // 关闭
		}
		return n.getRetVal(); // 函数返回值
	}

	/**
	 * 退出,恢复串口
	 * 
	 * @param icdev
	 * @return
	 * @throws Exception
	 */
	private String exit(int icdev) throws Exception {
		JNative n = null;
		try {
			n = new JNative("iccrf.dll", "rf_exit"); // 加载函数对象
			n.setRetVal(Type.INT); // 设置函数返回值类型
			int i = 0; // 设置参数顺序
			n.setParameter(i++, icdev);
			// n.setParameter(i++, msec); // 设值
			System.out.println("调用的DLL文件名为:" + n.getDLLName());
			System.out.println("调用的方法名为:" + n.getFunctionName());

			n.invoke(); // 调用函数
		} finally {
			if (n != null)
				n.dispose(); // 关闭
		}
		return n.getRetVal(); // 函数返回值
	}

	/**
	 * @param handle
	 * @param Mode
	 *            寻卡模式(0为对一张卡操作,1为对多张卡caozu)
	 * @return
	 * @throws NativeException
	 * @throws IllegalAccessException
	 */
	private long card(int handle, int Mode) throws NativeException,
			IllegalAccessException {
		JNative n = null;
		System.gc();
		String aa ;
		try {
			// 1.创建JNative对象
			n = new JNative("iccrf.dll", "rf_card");
			// 2.设置函数返回值类型
			n.setRetVal(Type.INT);
			// 3.设置参数类型
			// 声明指定内存空间
			Pointer NKey = new Pointer(MemoryBlockFactory
					.createMemoryBlock(100));
			n.setParameter(0, handle);
			n.setParameter(1, Mode);
			n.setParameter(2, NKey);
			// 4.执行函数
			n.invoke();
			aa = n.getRetVal();
			System.out.println(aa);
		} finally {
			if (n != null) {
				extracted(n);
			}
		}
		return Long.parseLong(aa);
	}

	private void extracted(JNative n) throws NativeException,
			IllegalAccessException {
		n.dispose();
	}

	public String readICCard() throws Exception {
		TestConn tc = new TestConn();
		Pointer po = tc.creatPointer();
		int icdev = TestConn.TestConnect(3, 9600);
		System.out.println("handle===" + icdev);
		long a = 0l;
		for (int i = 0; i < 60; i++) {
			a = tc.card(icdev, 1);
			System.out.println("a==" + a);
			if (a != 1l)
				break;
			Thread.sleep(200);
		}

		String beep = tc.testBeep(icdev, 500);
		System.out.println("beep==" + beep);
		if ("0".equals(beep)) {
			System.out.println("蜂鸣成功!");
		} else {
			System.out.println("蜂鸣失败!");
		}
		String exit = tc.exit(icdev);
		System.out.println("exit=" + exit);
		return String.valueOf(a);

	}

	public static void main(String[] args) throws Exception {
		TestConn tc = new TestConn();
		Pointer po = tc.creatPointer();
		int icdev = TestConn.TestConnect(3, 9600);
		System.out.println("handle===" + icdev);
		long a = 0l;
		for (int i = 0; i < 60; i++) {
			a = tc.card(icdev, 1);
			System.out.println("a==" + a);
			if (a != 1l)
				break;
			Thread.sleep(200);
		}

		String beep = tc.testBeep(icdev, 500);
		System.out.println("beep==" + beep);
		if ("0".equals(beep)) {
			System.out.println("蜂鸣成功!");
		} else {
			System.out.println("蜂鸣失败!");
		}
		String exit = tc.exit(icdev);
		System.out.println("exit=" + exit);

	}
}

         

        可能会遇到的问题:

        1.dll文件调用问题,有些dll文件提供的方法需要一些入口参数,除了指针类型,还会有一些其他类型的,我测试过程发现,java代码里传一个int型的1进去,dll文件的方法接收到的却是49了,这个如果没有dll文件源码做调试,估计累死也调不出来.

         2.读卡器.我使用的读卡器是通过USB口和电脑连接的,后台原理是模拟com口,测试过程一直使用的是com4口,客户使用中发现也会使用别的com口,如果不通的时候,也需要在设备管理器里去看看,到底使用的是哪个com口,不对的话,改一下.

你可能感兴趣的:(java基础)