2011-11-16 53 views
19

Buenos señores, Tengo una pregunta. El proyecto escolar de Java en el que estoy trabajando actualmente requiere que tenga un escáner de código de barras USB como entrada externa para conectarme a mi computadora portátil. Realmente no compré el USB Scanner porque es bastante caro para un estudiante. Así que tengo que reunir pruebas de que este escáner funcionaría con mi programa.Implementación de Barcode Scanner en Java

¿El escáner podría leer un código de barras (presumiblemente impreso en línea) y almacenarlo en una variable? Si es así, ¿es cierto que el evento de acción para la presión del escáner se leerá exactamente como una pulsación de tecla del teclado? Si es así, ¿cómo se vería la línea de código?

Además, si pudiera publicar sus experiencias con Barcode Scanners, o dar algún consejo, como qué escáner comprar, eso ayudaría mucho. ¡Aclamaciones!

+3

Si su cursor está en un cuadro de texto o en un campo de entrada, el escáner simplemente 'escribirá' el código allí. No hay nada especial con el escáner. No obtendrías un evento. Sin embargo, si tiene una página web, puede intentar algo como el evento 'OnChange' de JS. – Nishant

Respuesta

8

El escáner bardcode que he usado funcionaba como un dispositivo de teclado (aparecía como un dispositivo USB de teclado HID en el sistema operativo). Cuando se escaneó el código de barras, envió el código como si hubiera sido escrito. No se necesitaron API especiales para interactuar con él.

+0

¿Puedo preguntar qué modelo obtuviste? – user976123

+0

@ user976123 Hace años en un trabajo anterior, lo siento, no puedo recordar cuál era el modelo. – prunge

26

Recientemente tuve que implementar un sistema de escáner para interactuar con Java.

He usado Honeywell Voyager MS9540 Escáner de código de barras USB.

De manera predeterminada, el escáner envió los datos directamente como entrada de teclado, no se requiere controlador.

Pero era muy fácil de conseguir este modelo de interactuar directamente con Java en lugar de utilizar un gancho de teclado (para usar los códigos de barras como variables en Java, como usted ha mencionado).

Este modelo tiene una configuración para emular un puerto en serie, luego puede leer los datos escaneados utilizando el paquete javax.comm. Para mí, esto fue mucho mejor que un gancho de teclado para obtener los datos del código de barras porque el programa no necesita el foco antes de poder interpretar un escaneo (no me gustaría crear un gancho de teclado global).

Mi programa Java lee todas las entradas del puerto serie especificado y escribe el código de barras en una base de datos. También configuré el programa para pasar cualquier escaneo de código de barras no reconocido al teclado (cualquier código de barras que mi aplicación no creó - utilicé una firma distintiva en mis códigos de barras) esto fue así que funcionaría como un escáner de código de barras normal para cualquier otra aplicación que pudiera lee los códigos de barras del teclado.

Probablemente podría leer los datos directamente desde cualquier escáner USB (sin la emulación del puerto serie que tiene este modelo) haciendo una codificación JNDI intensiva, pero no estaba dispuesto a tomarse el tiempo para descifrar el código nativo.

Para configurar este modelo en particular para la emulación de puertos serie, todo lo que hace es escanear un código de barras específico en el documento this con el escáner que desea configurar. Es el código de barras titulado "Modo de emulación serial".

Este escáner requiere requiere un controlador para la emulación del puerto serie. Encontré las instrucciones de implementación y los controladores necesarios here (en la pestaña "software"). Descargue el paquete titulado: "Honeywell Scanning and Mobility (HSM) USB Serial Driver". El PDF titulado "Guía de inicio del controlador serie USB HSM" tenía las instrucciones.

Si no está familiarizado con la API de javax.comm.Lea la introducción en el ejemplo this de Rick Proctor: le indica dónde obtener el tarro y dónde colocar los archivos (javax.comm no viene de serie con la mayoría de los paquetes java).

Estoy seguro de que hay otros modelos de escáneres que tienen emulación de puerto en serie (no trabajo para Honeywell).

Aquí es una versión algo simplificada de mi código de barras lector de clase:

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); 
     } 
    };  
} 
+0

Parece que esos controladores son solo para Windows, por lo que no podrá usar su programa en otros sistemas operativos que Windows si lo hace de esta manera. –

+0

Puede ser cierto, solo necesitaba esto para Windows. No he buscado profundamente, pero debería haber algo que convierta un puerto USB a COM para Linux o MAC – Geronimo

+0

@Geronimo: ¿De dónde puedo encontrar este archivo config.properties? –

4

Sé que es bastante viejo hilo, pero la búsqueda puede llegar hasta allí.

Esto puede ser tratado como una adición a la respuesta de Geronimo:

Para el sistema operativo Linux no hay necesidad de instalar controladores para los escáneres de códigos de barras en modo de emulación de serie, ya que es el soporte nativo para los puertos serie USB. Utilizamos varios tipos de escáneres Honeywell y todos funcionan de inmediato, los escáneres en emulación serial se muestran en nuestros sistemas como/dev/ttyACM0,/dev/ttyACM1 etc.

Recientemente hemos cambiado de javax.comm a jssc como una biblioteca java para interfaz puertos serie. Si recuerdo bien, en Windows 7 el sistema de 64 bits javax.comm la biblioteca no puede leer o escribir desde/a puerto serie y jssc tiene una API muy similar.

+0

Bienvenido a stackoverflow. Intente formatear su respuesta del editor. – Daenarys

0

Me di cuenta de que esta era una vieja pregunta, pero pensé que agregaría una solución adicional para simular la entrada del Barcode Scanner. Esta solución solo funciona para simular la entrada del escáner como datos del teclado.

Dado que el escáner a menudo solo utiliza la entrada del teclado, podemos simular esto usando un script AutoHotkey. A continuación se muestra un ejemplo de una secuencia de comandos:

#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 

basta con sustituir [BC300013] y [BC200015] con lo que su entrada de escáner es de esperar.