一、扫码枪工具类

public class BarcodeScannerResolver {private static final String TAG = BarcodeScannerResolver.class.getSimpleName();/*** 若500ms之内无字符输入,则表示扫码完成. (若觉得时间还长,则可以设置成更小的值)*/private final static long MESSAGE_DELAY = 150;/*** 大写或小写*/private boolean mCaps;/*** 扫码内容*/private StringBuilder mResult = new StringBuilder();private OnScanSuccessListener mOnScanSuccessListener;private Handler mHandler = new Handler();private final Runnable mScanningEndRunnable = new Runnable() {@Overridepublic void run() {performScanSuccess();}};/*** 调用回调方法*/private void performScanSuccess() {String barcode = mResult.toString();Log.i(TAG, "performScanSuccess -> barcode: " + barcode);if (mOnScanSuccessListener != null) {mOnScanSuccessListener.onScanSuccess(barcode);}mResult.setLength(0);}/*** key事件处理** @param event*/public void resolveKeyEvent(KeyEvent event) {int keyCode = event.getKeyCode();//字母大小写判断checkLetterStatus(event);Log.w(TAG, "keyEvent:" + event + "keyCode: " + keyCode + "char: " + KeyEvent.keyCodeToString(keyCode));if (event.getAction() == KeyEvent.ACTION_DOWN) {char aChar = getInputCode(event);Log.w(TAG, "aChar: " + aChar);if (aChar != 0) {mResult.append(aChar);}if (keyCode == KeyEvent.KEYCODE_ENTER) {//若为回车键,直接返回mHandler.removeCallbacks(mScanningEndRunnable);mHandler.post(mScanningEndRunnable);} else {//延迟post,若500ms内,有其他事件mHandler.removeCallbacks(mScanningEndRunnable);mHandler.postDelayed(mScanningEndRunnable, MESSAGE_DELAY);}}}/*** 检查shift键** @param event*/private void checkLetterStatus(KeyEvent event) {int keyCode = event.getKeyCode();if (keyCode == KeyEvent.KEYCODE_SHIFT_RIGHT || keyCode == KeyEvent.KEYCODE_SHIFT_LEFT) {if (event.getAction() == KeyEvent.ACTION_DOWN) {//按着shift键,表示大写mCaps = true;} else {//松开shift键,表示小写mCaps = false;}}}/*** 获取扫描内容** @param event* @return*/private char getInputCode(KeyEvent event) {int keyCode = event.getKeyCode();char aChar;if (keyCode >= KeyEvent.KEYCODE_A && keyCode <= KeyEvent.KEYCODE_Z) {//字母aChar = (char) ((mCaps ? 'A' : 'a') + keyCode - KeyEvent.KEYCODE_A);} else if (keyCode >= KeyEvent.KEYCODE_0 && keyCode <= KeyEvent.KEYCODE_9) {//数字aChar = (char) ('0' + keyCode - KeyEvent.KEYCODE_0);} else {//其他符号switch (keyCode) {case KeyEvent.KEYCODE_PERIOD:aChar = '.';break;case KeyEvent.KEYCODE_MINUS:aChar = mCaps ? '_' : '-';break;case KeyEvent.KEYCODE_SLASH:aChar = '/';break;case KeyEvent.KEYCODE_BACKSLASH:aChar = mCaps ? '|' : '\\';break;default:aChar = 0;break;}}return aChar;}public interface OnScanSuccessListener {void onScanSuccess(String barcode);}public void setScanSuccessListener(OnScanSuccessListener onScanSuccessListener) {mOnScanSuccessListener = onScanSuccessListener;}public void removeScanSuccessListener() {mHandler.removeCallbacks(mScanningEndRunnable);mOnScanSuccessListener = null;}}

二、使用说明

  • 1. 在Activity中先创建BarcodeScannerResolver对象,并设置扫码成功监听器: setScanSuccessListener() [一般在onCreate()方法中初始化]
  • 2. 接着在Activity#dispatchKeyEvent() 或者 Activity#onKeyDown() 中调用本类中的resolveKeyEvent()方法。当扫码结束之后,会自动回调第一步设置的监听器中的方法
    

三、原理分析

  • 扫码枪就是一个外部的输入设备(和键盘一样)。扫码的时候,就是在极短的时间内输入了一系列的数字或字母
  • 这样就可以在键盘事件中抓捕这些输入的字符,但是又会产生一个问题(快速扫两次的情形):在键盘事件中应该抓捕多少个字符呢?即一个条码应该在哪个位置结束呢? (有的扫码枪会以一个回车或者换行作为一次扫码的结束符,但是有的就纯粹的是一系列的条码。这个得需要设置)所以为了兼容性,应当是当短时间内不再输入字符的时候,就表示扫码已结束。这样只能定性描述,不能定量,只能自己在程序中用一个具体的数字来表示这个“短时间”,eg:500ms。(如果每个条码结束的时候都有一个结束符那该多好,直接判断这个结束符,就可以知道当前扫码已完成)
    

四、核心原理

  • 在Activity的键盘监听事件中,每抓捕到一个字符的时候,就先向 Handler 一次一个runnable对象,再延迟500ms发送一个runnable. 这样若两个输入字符的间隔时间超过了500ms,则视为两次扫码

五、使用示例

  • 在activity中:
/*** 扫码枪工具类*/
private BarcodeScannerResolver mBarcodeScannerResolver;

在activity的onCreate方法中调用initScannerResolver();

/*** 初始化扫码监听*/
private void initScannerResolver() {mBarcodeScannerResolver = new BarcodeScannerResolver();mBarcodeScannerResolver.setScanSuccessListener(new BarcodeScannerResolver.OnScanSuccessListener() {@Overridepublic void onScanSuccess(String barcode) {Log.e("TAG", barcode);Toast.makeText(MainActivity.this, "扫码枪数据:" + barcode, Toast.LENGTH_SHORT).show();}});
}@Override
public boolean dispatchKeyEvent(KeyEvent event) {if (event.getKeyCode() != KeyEvent.KEYCODE_BACK) {mBarcodeScannerResolver.resolveKeyEvent(event);}return super.dispatchKeyEvent(event);
}
  • 给edt设置监听,可以不设置,也可以设置,设置动作监听,在输入完成之后可以直接执行接下来的逻辑
//这是扫码枪输入
edt.setOnEditorActionListener(new TextView.OnEditorActionListener() {@Overridepublic boolean onEditorAction(TextView v, int actionId, KeyEvent event) {/*** 当actionId == XX_SEND 或者 XX_DONE时都触发* 或者event.getKeyCode == ENTER 且 event.getAction == ACTION_DOWN时也触发* 注意,这是一定要判断event != null。因为在某些输入法上会返回null。*/if (actionId == EditorInfo.IME_ACTION_SEND|| actionId == EditorInfo.IME_ACTION_DONE|| (event != null && KeyEvent.KEYCODE_ENTER == event.getKeyCode() && KeyEvent.ACTION_DOWN == event.getAction())) {Log.e("TAG", "扫码结束");if (!TextUtils.isEmpty(edt.getText().toString())) {mStringBuilder.append(edt.getText().toString().trim() + "\n");text_view_scan.setText(mStringBuilder);edt.setText("");}}return false;}
});

硬件系列(七)----------USB扫码枪相关推荐

  1. 硬件系列(四)-------------Android标签打印机连接与打印位置调动方法总结

    一.获取连接的标签打印设备 private static List<UsbDevice> deviceList; private static String deviceArrayLisr ...

  2. ONNX系列七 --- 在Python中使用可移植的ONNX AI模型

    目录 安装和导入ONNX运行时 载入ONNX模型 使用ONNX运行时进行预测 摘要和后续步骤 参考文献 下载源547.1 KB 系列文章列表如下: ONNX系列一 --- 带有ONNX的便携式神经网络 ...

  3. Exchange Server2013 系列七:客户端访问服务器高可用性部署实战

    Exchange Server2013 系列七:客户端访问服务器高可用性部署实战 杜飞 在前面的文章中我们介绍了客户端访问服务器的高可用性技术,从这篇文章开始,我们就来看一个详细的高可用性部署方案. ...

  4. 硬件系列(五)-------------Android小票打印机连接 (已封装好,可直接使用)

    一.新建MyUsbPrinterUtil工具类,代码如下: import android.annotation.SuppressLint; import android.app.PendingInte ...

  5. USB扫码枪无焦点输入到指定页面、指定文件框中

    USB扫码枪无焦点输入到指定页面.指定文件框中 USB扫码枪无焦点输入到指定页面.指定文件框中 新建工程添一个MDIParent窗口,两个FORM窗口.第一步添加一个类(ScanerHook),代码如 ...

  6. usb扫描枪驱动下载 wince_WinCE系列全站仪USB驱动程序

    WinCE系列全站仪usb驱动程序是一款WinCE系列全站仪连接USB驱动同步软件,适合全系列Windows操作系统,支持早期的WIN9X和当前主流操作系统XP/WIN7,支持WINSERVER2K3 ...

  7. USB扫码枪获取数据流的实现方式

    硬件条件: OTG接口转换器(或者自带usb接口的设备(大头)) USB扫码枪(支持USB虚拟串口) 安卓设备 实现方式: 串口方式 USB方式 使用场景: 在扫码枪连接机器的时候,当扫码枪扫描到内容 ...

  8. 硬件系列(二)-------------wifi打印机之佳博wifi打印机踩坑之路

    一.前言 之前做过USB打印机,但是现在需求变了,不是使用收银台进行打印机的连接了,而是使用手机与打印机进行打印.手机又无法像收银机一样直接使用USB直接与打印机直接连接进行打印.所以只能使用蓝牙打印 ...

  9. [C#.Net]全局钩子实现USB扫码枪无焦点状态下扫入

    [C#.Net]全局钩子实现USB扫码枪无焦点状态下扫入 [C#.Net]全局钩子实现USB扫码枪无焦点状态下扫入 [C#.Net]全局钩子实现USB扫码枪无焦点状态下扫入 1.扫描枪获取数据原理基本 ...

  10. usb扫描枪驱动下载 wince_WinCE系列全站仪USB驱动程序(WinCE全站仪USB驱动) 最新中文版...

    WinCE系列全站仪USB驱动程序(WinCE全站仪USB驱动) 最新中文版 WinCE系列全站仪usb驱动程序是一款WinCE系列全站仪连接USB驱动同步软件,适合全系列Windows操作系统,支持 ...

最新文章

  1. 使用Python,OpenCV寻找图像中的轮廓
  2. mysql+翻页性能,mysql 翻页优化
  3. CCAI 2017 中国人工智能大会 6.4 折抢票倒计时!
  4. Linux下安装配置NTP时间同步服务器
  5. Linux 下, npm i 老是被killed 已杀死
  6. 【个人笔记】关于IO类中流的整理
  7. asp.net webapi bug : System.OperationCanceledException 异常处理
  8. 排序算法(3)----归并排序
  9. 1. max31855 热电偶至输出转换器 分析
  10. 关于Windows 10 企业版 LTSC重装系统后优化项目
  11. 验证集与测试集的区别
  12. python实现离职滤波_如何用Python预测员工离职率?
  13. 利用shrinkwrap锁定依赖版本
  14. 大专学数控技术是计算机一类的吗,学专科数控技术,出来后找什么工作呢?
  15. 使用范例调教ChatGPT
  16. 【DVB】采用DVB-T或DVB-T2的国家达166个
  17. Create WAP Push SMS Messages
  18. Python_对折多少次超过珠峰
  19. 为何 Linus 一个人就能写出这么强的系统?
  20. PHP开启magic扩展,php.ini中Magic_Quotes_Gpc开关设置

热门文章

  1. comfort说明书 tp1200_tp1200 comfort触摸屏用什么软件组态-工业支持中心-西门子中国...
  2. java使用GB28181协议访问海康硬盘录像机程序怎么写
  3. PMBOK(第六版) PMP笔记 —— 简介
  4. Webstorm是什么软件?你了解吗
  5. android 录像和拍照功能
  6. Node 非服务脚本调试
  7. 令数组中的对象根据数字大小进行排序
  8. 电脑如何设置开机自启软件?
  9. vivo分屏_在家办公效率低?vivo手机宅家攻略,善用分屏便签和Jovi
  10. 使用jxls分页导出excel