最近、Java と対話するためのスキャナー システムを実装する必要がありました。
Honeywell Voyager MS9540 USB バーコード スキャナーを使用しました。
デフォルトでは、スキャナはデータをキーボード入力として直接送信します - ドライバは必要ありません。
しかし、キーボードフックを使用するのではなく、このモデルを Java と直接対話させるのは非常に簡単でした(前述のように、バーコードを Java の変数として使用するため)。
このモデルにはシリアル ポートをエミュレートする設定があり、javax.comm パッケージを使用してスキャンしたデータを読み取ることができます。私にとっては、これはバーコード データを取得するためのキーボード フックよりもはるかに優れていました。これは、プログラムがスキャンを解釈できるようになる前にフォーカスを必要としないためです (グローバル キーボード フックを作成したくありません)。
私の Java プログラムは、指定されたシリアル ポートからすべての入力を読み取り、バーコードをデータベースに書き込みます。また、認識されていないバーコード スキャンをキーボードに渡すようにプログラムをセットアップしました (アプリが作成しなかったバーコード - バーコードに個別の署名を使用しました)。キーボードからバーコードを読み取ります。
おそらく、集中的な JNI コーディングを行うことで、(このモデルに搭載されているシリアル ポート エミュレーションなしで) USB スキャナーから直接データを読み取ることができますが、私はネイティブ コードを作成する時間を取る準備ができていませんでした。
この特定のモデルをシリアル ポート エミュレーション用に構成するには、構成したいスキャナーでこのドキュメントの特定のバーコードをスキャンするだけです。「Serial Emulation Mode」というタイトルのバーコードです。
このスキャナには、シリアル ポート エミュレーション用のドライバが必要です。ここで実装手順と必要なドライバーを見つけました(「ソフトウェア」タブの下)。「Honeywell Scanning and Mobility (HSM) USB Serial Driver」というタイトルのパッケージをダウンロードします。「HSM USB Serial Driver Getting Started Guide」というタイトルの PDF に手順が記載されていました。
javax.comm API に慣れていない場合。Rick Proctor によるこの例のイントロを読んでください。jar を取得する場所とファイルを配置する場所が示されています (javax.comm は、ほとんどの Java パッケージに標準で付属していません)。
シリアル ポート エミュレーションを備えた他のスキャナ モデルがあることは確かです (私は Honeywell で働いていません)。
これは、私のバーコード リーダー クラスのやや簡略化されたバージョンです。
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);
}
};
}