安卓扫码枪开发,拦截扫码事件
程序员文章站
2022-06-14 19:38:23
...
需求
普通的手机开发,可以做一个二维码扫码的页面,用zxing一类的可以轻松实现,但是,如果是大型的安卓系统的终端机的话,摄像头不方便使用。可以依靠扫码枪来实现类似的效果。
分析
大型安卓设备与安卓手机的开发区别还是比较大的,尤其是扫码枪部分,有以下特点。例如:
- 终端机的开发中,经常是Activity 数量比较少,Fragment比较多。
- 扫码枪需要全局响应。并不只局限于某一个Fragment。
- 大多数扫码枪的原理是模拟键盘进行输入,所以不支持包含有汉字的二维码
大多数扫码枪是模拟键盘进行输入,大多数时候需要使用获取焦点的 EditText 接收其扫描的信息。
显然这并不能满足我们的需求。那么,仔细想一下,我们可以认为是在短时间内,识别了二维码中的非汉字信息,并依次按键。我们可以在按键的时候进行按键事件 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
上一篇: 大文件排序求频率TOP问题