Java上的条形码扫描器实现

use*_*123 26 java events action scanning barcode-scanner

好先生,我有一个问题.我目前正在研究的学校Java项目要求我将USB条形码扫描仪作为外部输入连接到我的笔记本电脑.我还没有买过USB扫描仪,因为它对学生来说相当昂贵.因此,我必须收集证据证明此扫描程序可以与我的程序一起使用.

扫描仪是否能够读取条形码(可能是在线打印)并将其存储到变量中?如果是这样,扫描仪按下的动作事件是否真的像键盘按键一样被读取?如果是这样,代码行会是什么样的?

此外,如果您可以发布条形码扫描仪的经验,或提供任何建议,例如购买哪种扫描仪,这将有所帮助.干杯!

Aci*_*ier 32

我最近不得不实现一个扫描系统来与java交互.

我使用了霍尼韦尔Voyager MS9540 USB条码扫描器.

默认情况下,扫描仪将数据作为键盘输入直接发送 - 无需驱动程序.

但是很容易让这个模型直接与java 交互而不是使用键盘钩子(如你所提到的那样,将条形码用作java中的变量).

此模型具有模拟串行端口的设置,然后您可以使用javax.comm包读取扫描的数据.对我来说,这是很多比一个键盘钩子获取条形码数据,因为程序不能够解释扫描(我不想创建一个全局键盘钩子)之前,需要重点更好.

我的java程序读取指定串行端口的所有输入,并将条形码写入数据库.我还设置程序将任何无法识别的条形码扫描传递到键盘(我的应用程序没有创建的任何条形码 - 我在我的条形码上使用了不同的签名)这样它就可以作为常规条形码扫描仪用于任何其他可能的应用程序从键盘上读取条形码.

您可以通过执行一些密集的JNI编码直接从任何USB扫描仪读取数据(没有此模型具有的串行端口仿真),但我不准备花时间计算本机代码.

要为串行端口仿真配置此特定模型,您只需使用要配置的扫描仪扫描文档中的特定条形码.这是标题为"串行仿真模式"的条形码.

此扫描器确实需要驱动程序进行串行端口仿真.我在这里找到了实施说明和所需的驱动程序(在"软件"选项卡下).下载标题为"霍尼韦尔扫描与移动(HSM)USB串行驱动程序"的软件包.标题为"HSM USB串行驱动程序入门指南"的PDF有说明.

如果您不熟悉javax.comm API.请阅读Rick Proctor 在这个例子中的介绍- 它告诉你在哪里获取jar以及放置文件的位置(javax.comm不是大多数java软件包的标准).

我确定周围有其他扫描仪型号有串口仿真(我不适用于霍尼韦尔).

这是我的条形码阅读器类的一个有点精简版:

package scanhandler;


import java.awt.AWTException;
import java.awt.Robot;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.sql.Connection;
import java.util.Enumeration;
import java.util.Properties;
import java.util.TooManyListenersException;
import javax.comm.CommPortIdentifier;
import javax.comm.PortInUseException;
import javax.comm.SerialPort;
import javax.comm.SerialPortEvent;
import javax.comm.SerialPortEventListener;
import javax.comm.UnsupportedCommOperationException;

public class ScanHandler implements Runnable, SerialPortEventListener {

    private static CommPortIdentifier   myCommPortIdentifier;
    private static Enumeration          portList;
    private static String               TimeStamp;
    private static String               driverClass;
    private static String               connectionString;
    private static String               comPort;    

    private Connection                  myConnection;
    private InputStream                 myInputStream;
    private Robot                       myRobot;
    private SerialPort                  mySerialPort;
    private Thread                      myThread;


    public ScanHandler() {

        // open serial port
        try {
            TimeStamp = new java.util.Date().toString();
            mySerialPort = (SerialPort) myCommPortIdentifier.open("ComControl", 2000);
            //System.out.println(TimeStamp + ": " + myCommPortIdentifier.getName() + " opened for scanner input");
        } catch (PortInUseException e) {
            e.printStackTrace();
        }

        // get serial input stream
        try {
            myInputStream = mySerialPort.getInputStream();
        } catch (IOException e) {
            e.printStackTrace();
        }

        // add an event listener on the port
        try {
            mySerialPort.addEventListener(this);
        } catch (TooManyListenersException e) {
            e.printStackTrace();
        }
        mySerialPort.notifyOnDataAvailable(true);

        // set up the serial port properties
        try {
            mySerialPort.setSerialPortParams(9600,
                SerialPort.DATABITS_8,
                SerialPort.STOPBITS_1,
                SerialPort.PARITY_NONE);
            mySerialPort.setDTR(false);
            mySerialPort.setRTS(false);

        } catch (UnsupportedCommOperationException e) {
            e.printStackTrace();
        }

        // make a robot to pass keyboard data
        try {
            myRobot = new Robot();
        } catch (AWTException e) {
            e.printStackTrace();
        }

        // create the thread
        myThread = new Thread(this);
        myThread.start();
    }

    public void run() {
        try {
            Thread.sleep(100);
        } catch (InterruptedException e) {}
    }

    // on scan
    public void serialEvent(SerialPortEvent event) {

        if (event.getEventType() == SerialPortEvent.DATA_AVAILABLE) {

            StringBuilder myStringBuilder = new StringBuilder();
            int c;
            try {

                // append the scanned data onto a string builder
                while ((c = myInputStream.read()) != 10){
                   if (c != 13)  myStringBuilder.append((char) c);
                }               

                // send to keyboard buffer if it the barcode doesn't start with '5'
                if (myStringBuilder.charAt(0) != '5') {

                    for (int i = 0; i < myStringBuilder.length(); i++) {
                        myRobot.keyPress((int) myStringBuilder.charAt(i));
                        myRobot.keyRelease((int) myStringBuilder.charAt(i));
                    }

                // here's the scanned barcode as a variable!
                } else {
                    TimeStamp = new java.util.Date().toString();
                    System.out.println(TimeStamp + ": scanned input received:" + myStringBuilder.toString());                    
                }

                // close the input stream
                myInputStream.close();

            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

    public static void main(String[] args) {

        // read ScanHandler properties
        Properties myProperties = new Properties();
        try {
            myProperties.load(new FileInputStream("config.properties"));
            comPort             = myProperties.getProperty("ScanHandler.comPort");
        } catch (IOException e) {
            e.printStackTrace();
        }              

        try {

            // get our pre-defined COM port
            myCommPortIdentifier = CommPortIdentifier.getPortIdentifier(comPort);
            ScanHandler reader = new ScanHandler();

        } catch (Exception e) {
            TimeStamp = new java.util.Date().toString();
            System.out.println(TimeStamp + ": " + comPort + " " + myCommPortIdentifier);
            System.out.println(TimeStamp + ": msg1 - " + e);
        }
    };    
}
Run Code Online (Sandbox Code Playgroud)


pru*_*nge 9

我使用的bardcode扫描仪就像一个键盘设备(它在操作系统中显示为HID键盘USB设备).扫描条形码时,它会像输入一样发送代码.不需要特殊的API来与它进行交互.


Pav*_*era 7

我知道这是一个很老的线程,但搜索可以让你到那里.

这可以作为Geronimo答案的补充:

对于Linux OS,无需在串行仿真模式下安装条形码扫描仪的驱动程序,因为本机支持USB串行端口.我们使用几种类型的霍尼韦尔扫描仪,所有这些都是开箱即用的,串行仿真中的扫描仪在我们的系统中显示为/ dev/ttyACM0,/ dev/ttyACM1等.

最近我们已经从javax.comm切换到jssc作为java库来连接串口.如果我记得很清楚,在Windows 7 64bit系统下,javax.comm库无法读取或写入串口,而jssc也有非常相似的api.