Java上的条码扫描器实现

好先生,我有一个问题。 我目前正在从事的学校Java项目需要我有一个USB条形码扫描器作为外部input连接到我的笔记本电脑。 我还没有买到USB扫描仪,因为这对学生来说相当昂贵。 所以我必须收集证据表明这个扫描仪将与我的程序工作。

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

另外,如果你可以发表你的经验与条码扫描仪,或给任何build议,如扫描仪购买,这将有助于很多。 干杯!

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

我使用了霍尼韦尔Voyager MS9540 USB条形码扫描仪。

默认情况下,扫描仪直接input数据作为键盘input – 不需要驱动程序。

但是很容易让这个模型直接与java进行交互,而不是像前面提到的那样使用键盘钩子(在java中使用条形码作为variables)。

这个模型有一个模拟串口的设置,然后你可以使用javax.comm包读取扫描的数据。 对于我来说,这比键盘钩获得条码数据好得多,因为程序在能够解释扫描之前不需要焦点(我不想创build全局键盘钩子)。

我的Java程序读取指定串行端口的所有input,并将条形码写入数据库。 我还设置了程序,将任何无法识别的条形码扫描传递到键盘(我的应用程序没有创build的任何条形码 – 我在我的条形码上使用了不同的签名),所以它可以作为常规的条形码扫描仪从键盘读取条形码。

你大概可以通过做一些密集的JNDI编码直接从任何USB扫描器读取数据(没有这个模型的串口模拟),但是我没有准备花时间去计算本地代码。

要为串行端口仿真configuration此特定型号,只需使用要configuration的扫描仪扫描文档中的特定条码。 这是标题为“串行仿真模式”的条形码。

此扫描程序确实需要用于串行端口仿真的驱动程序。 我在这里find了实施说明和所需的驱动程序(在“软件”选项卡下)。 下载标题为“霍尼韦尔扫描和移动(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); } }; } 

我用的bardcode扫描器就像一个键盘设备(它在操作系统中显示为一个HID键盘USB设备)。 当条形码被扫描时,它就像打字一样发送代码。 不需要特殊的API来与之交互。

我知道这是相当古老的线程,但search可以让你在那里。

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

对于Linux操作系统,不需要在串行仿真模式下安装条形码扫描器的驱动程序,因为USB串行端口具有本机支持。 我们使用多种types的霍尼韦尔扫描仪,所有这些扫描仪都是开箱即用的,那些串行仿真扫描仪在我们的系统中显示为/ dev / ttyACM0,/ dev / ttyACM1等。

最近我们从javax.comm切换到jssc作为java库来连接串行端口。 如果我记得很清楚,在Windows 7 64位系统下javax.comm库不能读/写/从串口和jssc有非常相似的api。

我意识到这是一个古老的问题,但认为我会添加一个额外的解决scheme,以模拟条码扫描器input。 此解决scheme仅适用于模拟键盘数据的扫描仪input。

由于扫描仪通常只是使用键盘input,我们可以使用AutoHotkey脚本来模拟这一点。 下面是一个脚本的例子:

 #NoEnv ; Recommended for performance and compatibility with future AutoHotkey releases. ; #Warn ; Enable warnings to assist with detecting common errors. SendMode Input ; Recommended for new scripts due to its superior speed and reliability. SetWorkingDir %A_ScriptDir% ; Ensures a consistent starting directory. ; Barcode 1 ; Hotkey = ctrl + alt + 1 ^!1:: SendInput [BC200015] Return ; Barcode 2 ; Hotkey = ctrl + alt + 2 ^!2:: SendInput [BC300013] Return 

只需用您期望的扫描仪inputreplace[BC300013][BC200015]