web-dev-qa-db-ja.com

Javaでのバーコードスキャナーの実装

良い先生、質問があります。学校Java私が現在取り組んでいるプロジェクトでは、ラップトップに接続するための外部入力としてUSBバーコードスキャナーが必要です。ですから、このスキャナーが私のプログラムで動作するという証拠を集めなければなりません。

スキャナーはバーコード(おそらくオンラインで印刷されたもの)から読み取り、変数に保存できますか?もしそうなら、スキャナーを押すためのアクションイベントがキーボードのキーを押すように正確に読み取られるのは本当ですか?もしそうなら、コード行はどのように見えるでしょうか?

また、バーコードスキャナーの使用経験を投稿したり、どのスキャナーを購入するかなどのアドバイスを提供することができれば、それは大いに役立ちます。乾杯!

24
user976123

最近、Javaとやり取りするためにスキャナーシステムを実装する必要がありました。

Honeywell Voyager MS9540 USBバーコードスキャナーを使用しました。

デフォルトでは、スキャナーはデータをキーボード入力として直接送信しました。ドライバーは不要です。

しかしこのモデルをと直接やり取りすることは非常に簡単でした。/Java前述のように、バーコードをJavaの変数として使用します)。

このモデルにはシリアルポートをエミュレートする設定があり、javax.commパッケージを使用してスキャンしたデータを読み取ることができます。私にとって、これはmuchスキャンを解釈する前にプログラムがフォーカスを必要としないため、バーコードデータを取得するキーボードフックよりも優れていました(グローバルキーボードフックを作成したくない) 。

My Javaプログラムは、指定されたシリアルポートからすべての入力を読み取り、バーコードをデータベースに書き込みます。認識できないバーコードスキャンをキーボードに渡すようにプログラムをセットアップしました。 create-バーコードに個別の署名を使用しました)これは、キーボードからバーコードを読み取る可能性のある他のアプリの通常のバーコードスキャナーとして機能するためです。

集中的なJNIコーディングを行うことで、USBスキャナーからデータを直接読み取ることができます(このモデルのシリアルポートエミュレーションなし)が、ネイティブコードを処理する時間をかける準備ができていませんでした。

この特定のモデルをシリアルポートエミュレーション用に設定するには、設定するスキャナーで this documentの特定のバーコードをスキャンするだけです。これは、「シリアルエミュレーションモード」というタイトルのバーコードです。

このスキャナーは does シリアルポートエミュレーション用のドライバーを必要とします。実装手順と必要なドライバーを見つけました here (「ソフトウェア」タブの下)。 「Honeywell Scanning and Mobility(HSM)USB Serial Driver」というタイトルのパッケージをダウンロードします。 PDF「HSM USBシリアルドライバースタートアップガイド」というタイトルの説明がありました。

Javax.comm APIに慣れていない場合。 this のイントロを読んでください。RickProctorの例-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);
        }
    };    
}
31
Geronimo

私が使用したバードコードスキャナーは、キーボードデバイスのように動作しました(オペレーティングシステムでHIDキーボードUSBデバイスとして表示されました)。バーコードがスキャンされると、入力されたかのようにコードを送信しました。対話するのに特別なAPIは必要ありませんでした。

9
prunge

私はそれがかなり古いスレッドであることを知っていますが、検索でそこに到達できます。

これは、Geronimoの答えへの追加として扱うことができます。

Linux OSの場合、USBシリアルポートのネイティブサポートがあるため、シリアルエミュレーションモードでバーコードスキャナーのドライバーをインストールする必要はありません。いくつかのタイプのHoneywellスキャナーを使用し、それらはすべてそのまま使用できます。シリアルエミュレーションのスキャナーは、システムでは/ dev/ttyACM0、/ dev/ttyACM1などとして表示されます。

最近、javax.commからjsscにJavaライブラリとしてシリアルポートをインターフェイスするように切り替えました。Windows7 64ビットシステムでは、javax.commライブラリはシリアルの読み書きができません。 portとjsscのAPIは非常に似ています。

7
Pavel Kucera

これは古い質問でしたが、バーコードスキャナーの入力をシミュレートするための追加のソリューションを追加すると考えました。このソリューションは、スキャナー入力をキーボードデータとしてシミュレートする場合にのみ機能します。

スキャナーはキーボード入力を使用することが多いため、 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

[BC300013]および[BC200015]予想されるスキャナー入力が何であれ。

0
philosowaffle