安卓扫码枪开发,拦截扫码事件

需求

普通的手机开发,可以做一个二维码扫码的页面,用zxing一类的可以轻松实现,但是,如果是大型的安卓系统的终端机的话,摄像头不方便使用。可以依靠扫码枪来实现类似的效果。

分析

大型安卓设备与安卓手机的开发区别还是比较大的,尤其是扫码枪部分,有以下特点。例如:

  • 终端机的开发中,经常是Activity 数量比较少,Fragment比较多。
  • 扫码枪需要全局响应。并不只局限于某一个Fragment。
  • 大多数扫码枪的原理是模拟键盘进行输入,所以不支持包含有汉字的二维码

我这边使用是USB HID的扫码枪,即插即用,只需要在界面上有带有焦点的EditText ,就可以获取扫码枪扫描的内容。大多数扫码枪是模拟键盘进行输入,大多数时候需要使用获取焦点的 EditText 接收其扫描的信息。
显然这并不能满足我们的需求。那么,仔细想一下,我们可以认为是在短时间内,识别了二维码中的非汉字信息,并依次按键。我们可以在按键的时候进行按键事件 onKeyDown 的拦截。等全部扫描完毕之后,再去执行其它操作。

USB HID扫码枪会将扫描出来的内容转化为键盘事件,对应的就是Android中的KeyEvent事件,所以我们只需要在我们的activity中重写onKeyDown方法,即可获取相应事件。

实现

找规律

既然我们要进行按键事件拦截,那么就得有一个明确的拦截开始时间和结束时间。可以先通过打印所有的keycode,来观察扫码后都执行了哪些按键。
例如我的扫码枪,在真正内容开始前和结束后,会按下一个keycode 值为 143 的按键。即 KEYCODE_NUM_LOCK 小键盘锁 。
那么可以设置一个布尔值,标识当前是否是扫描状态。并在结束的时候进行下一步操作。即:

怎么进行下一步操作?方法太多了,EventBus,接口回调,方法,……

  var isScan = false;  // 当前是否是扫描状态
  ···
  if (keyCode == KeyEvent.KEYCODE_NUM_LOCK) {
            if (isScan) {
                LogUtils.e("String ==>" + ScanString)
                ScanString = ""
            } else {
                LogUtils.e("String ==>" + "开始扫描……")
            }
            isScan = !isScan
            return true;
        }
        if (isScan) {
            ScanString += getInputCode(event).toString()
            return true;
        }

拼接字符串

只获取到了 keycode 值不行,还需要将keycode值转为具体的内容。

    //获取扫描内容
    private fun getInputCode(event: KeyEvent): Char {
        val keyCode = event.keyCode
        val aChar: Char
        if (keyCode >= KeyEvent.KEYCODE_A && keyCode <= KeyEvent.KEYCODE_Z) {
            //字母
            aChar = (('a').toInt() + keyCode - KeyEvent.KEYCODE_A).toChar()
        } else if (keyCode >= KeyEvent.KEYCODE_0 && keyCode <= KeyEvent.KEYCODE_9) {
            //数字
            aChar = ('0' + keyCode - KeyEvent.KEYCODE_0).toChar()
        } else if (keyCode == KeyEvent.KEYCODE_ENTER) {
            aChar = 0.toChar()
        } else {
            //其他符号
            aChar = event.unicodeChar.toChar()
        }
        return aChar
    }

代码

    var isScan = false;  // 当前是否是扫描状态
    var ScanString = "";  // 扫描出的内容

    override fun onKeyDown(keyCode: Int, event: KeyEvent): Boolean {
        if (keyCode == KeyEvent.KEYCODE_NUM_LOCK) {
            if (isScan) {
                LogUtils.e("String ==>" + ScanString)
                ScanString = ""
            } else {
                LogUtils.e("String ==>" + "开始扫描……")
            }
            isScan = !isScan
            return true;
        }
        if (isScan) {
            ScanString += getInputCode(event).toString()
            return true;
        }
        return super.onKeyDown(keyCode, event)
    }

    //获取扫描内容
    private fun getInputCode(event: KeyEvent): Char {
        val keyCode = event.keyCode
        val aChar: Char
        if (keyCode >= KeyEvent.KEYCODE_A && keyCode <= KeyEvent.KEYCODE_Z) {
            //字母
            aChar = (('a').toInt() + keyCode - KeyEvent.KEYCODE_A).toChar()
        } else if (keyCode >= KeyEvent.KEYCODE_0 && keyCode <= KeyEvent.KEYCODE_9) {
            //数字
            aChar = ('0' + keyCode - KeyEvent.KEYCODE_0).toChar()
        } else if (keyCode == KeyEvent.KEYCODE_ENTER) {
            aChar = 0.toChar()
        } else {
            //其他符号
            aChar = event.unicodeChar.toChar()
        }
        return aChar
    }

安卓keycode列表

详细列表 见 https://blog.csdn.net/feizhixuan46789/article/details/16801429
此处简单总结一下keycode列表。

  • 0-9 对应的是 KEYCODE_0 - KEYCODE_9,真实的值为 7 - 16
  • A-Z 对应的是 KEYCODE_A - KEYCODE_Z ,值为 29 - 54
  • 上下左右中 对应 19-23,
  • 功能键如下:
    KEYCODE_ENTER 回车键 66
    KEYCODE_ESCAPE ESC键 111
    KEYCODE_DPAD_CENTER 导航键 确定键 23
    KEYCODE_DPAD_UP 导航键 向上 19
    KEYCODE_DPAD_DOWN 导航键 向下 20
    KEYCODE_DPAD_LEFT 导航键 向左 21
    KEYCODE_DPAD_RIGHT 导航键 向右 22
    KEYCODE_MOVE_HOME 光标移动到开始键 122
    KEYCODE_MOVE_END 光标移动到末尾键 123
    KEYCODE_PAGE_UP 向上翻页键 92
    KEYCODE_PAGE_DOWN 向下翻页键 93
    KEYCODE_DEL 退格键 67
    KEYCODE_FORWARD_DEL 删除键 112
    KEYCODE_INSERT 插入键 124
    KEYCODE_TAB Tab键 61
    KEYCODE_NUM_LOCK 小键盘锁 143
    KEYCODE_CAPS_LOCK 大写锁定键 115
    KEYCODE_BREAK Break/Pause键 121
    KEYCODE_SCROLL_LOCK 滚动锁定键 116
    KEYCODE_ZOOM_IN 放大键 168
    KEYCODE_ZOOM_OUT 缩小键 169
发布了70 篇原创文章 · 获赞 176 · 访问量 31万+

猜你喜欢

转载自blog.csdn.net/zheng_weichao/article/details/94008791