本文介绍如何从Android端获取扫码枪的二维码数据,扫码枪应用场景多,特别是在终端设备上,如:扫码付款,扫码取票,扫码开门等,一般实时监听扫码。扫码枪的相关设置这里不多说,都有对应的文档说明,不同扫码枪大同小异。
Android端获取扫码枪数据一般有如下三种获取方式:
-
USB键盘模式,自感模式(出厂默认):大多数扫码枪是模拟键盘进行输入(不支持包含有汉字的二维码),大多数时候需要使用带焦点的 EditText 接收其扫描的信息。设置一个带焦点的EditText进行接收,此方式容易漏读扩展的ASCII码数据,除非二维码是标准的ASCII码(1-128),此外使用EditText不方便且焦点控制不好导致扫码不到数据。由于扫码枪会将扫描出来的内容转化为键盘事件,对应的就是Android中的KeyEvent事件,所以我们只需要在我们的activity中重写dispatchKeyEvent方法,即可获取相应事件。
-
通过 USB COM连接扫码:发送扫码开关指令进行扫码,即基于Usb相关类控制扫码开关,控制不好容易出问题
特别地:使用此模式前提是先对扫码枪配置USB COM模式,再配置指令触发 -
USB串口自感模式:即串口连接(当扫码枪使用 USB 通讯接口,但主机应用程序是采用串口通讯方式接收数据),客户端只负责监听读取数据,无须控制扫码枪指令,需要依赖usb串口传输数据的第三方库:https://github.com/mik3y/usb-serial-for-android
特别地:使用此模式前提是先对扫码枪配置USB 虚拟串口通讯方式
注意:上面三种方式均需要进行配置好模式,再操作,建议使用方式1和3.
此外,扫码枪usb插拔时,会造成Activity重新加载,说明对Activity生命周期有影响,需要处理一下。
可在Activity配置:
android:configChanges="orientation|keyboard|keyboardHidden"
USB键盘模式使用
**
* usb键盘模式扫码示例,无需EditText接收,推荐
* @author song
*/
public class ScannerUsbKeyboardActivity extends AppCompatActivity {
UsbKeyboardAutoScan usbKeyboardAutoScan;
EditText et_barcode;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.scanner_usb_keyboard_activity);
et_barcode = findViewById(R.id.et_barcode);
usbKeyboardAutoScan = new UsbKeyboardAutoScan();
usbKeyboardAutoScan.setOnScanListener(new OnScanListener() {
@Override
public void onScanSuccess(String barcode) {
//扫码接收
et_barcode.setText(barcode);
}
});
}
@Override
public boolean dispatchKeyEvent(KeyEvent event) {
if (usbKeyboardAutoScan.isIntercept()
&& event.getKeyCode() != KeyEvent.KEYCODE_BACK) {//不处理返回键
usbKeyboardAutoScan.analysisKeyEvent(event);
return true;//防止输入框接收事件
}
return super.dispatchKeyEvent(event);
}
@Override
protected void onDestroy() {
super.onDestroy();
usbKeyboardAutoScan.cancel();
}
}
USB串口自感模式使用
package com.sjl.test;
import android.hardware.usb.UsbDevice;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.view.View;
import android.widget.EditText;
import com.sjl.scanner.BaseUsbScan;
import com.sjl.scanner.UsbComAutoScan;
import com.sjl.scanner.UsbConfig;
import com.sjl.scanner.listener.OnScanListener;
import java.util.List;
/**
* 基于usb扫码
*
* @author song
*/
public class ScannerUsbActivity extends AppCompatActivity {
BaseUsbScan usbScan;
EditText et_barcode;
UsbConfig usbConfig = new UsbConfig();
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.scanner_usb_activity);
et_barcode = findViewById(R.id.et_barcode);
usbConfig.setProductId(1233);
usbConfig.setVendorId(1234);
// usbScan = new UsbCmdScan(this); //通过usb连接扫码, 发送命令扫码
UsbConfig.SerialPortConfig serialPortConfig = new UsbConfig.SerialPortConfig();
usbConfig.setSerialPortConfig(serialPortConfig);
usbScan = new UsbComAutoScan(this);//通过usb转串口,自感模式,推荐
usbScan.setOnScanListener(new OnScanListener() {
@Override
public void onScanSuccess(String barcode) {
}
});
}
public void listUsbDevice(View view) {
//找到设备插入的usb孔对应UsbDevice
List<UsbDevice> usbDevices = usbScan.getUsbDevices(this);
for (UsbDevice device : usbDevices) {
et_barcode.setText(et_barcode.getText() + "\n" + device.getDeviceName() + ",vendorID:" + device.getVendorId() + ",ProductId:" + device.getProductId());
}
}
public void openUsbScan(View view) {
int ret = usbScan.openScan(usbConfig);
if (ret != 0) {
showMsg("打开usb扫码失败,ret" + ret);
} else {
showMsg("打开usb扫码成功");
}
}
private void showMsg(String s) {
et_barcode.setText(s);
}
public void closeUsbScan(View view) {
usbScan.closeScan();
}
public void loopScan(View view) {
usbScan.startReading();
}
public void stopLoopScan(View view) {
usbScan.stopReading();
}
@Override
protected void onDestroy() {
super.onDestroy();
usbScan.closeScan();
}
}