背景介绍
最近老板又随便丢过来一个扫码枪让我研究快速上线,我心想着又是什么串口通信吗,结果发现是usb的,我想着是不是有什么协议,结果直接插上电脑或者手机 均可在输入框直接输入,不用任何的代码编写
但结合了一下实际场景,我们需要一个全局的没有编辑框的输入监听才能满足的我们的需求,比如一扫就跳转一扫就去支付等处理业务
基本概念
1.条形码和二维码都对应固定文本也就是字符串,本身没有业务逻辑是我们程序赋予此业务逻辑
2.扫码枪本质原理是识别条形码和二维码后进行外接键盘输入
监听输入
uniapp实现
const onConfirm = (code : string) => {
console.log('拿到的code', code);
// 此处写我们自己的逻辑 这里我只是举例 具体根据你们自己业务如何解析
let str = code;
// 使用 split 方法根据冒号分割字符串
let parts = str.split(":");
// 检查是否至少有 3 个部分(两个冒号)
if (parts.length >= 3) {
// 提取第二个部分(索引为 1,因为索引从 0 开始)
let extracted = parts[1];
console.log(extracted); // 输出: DD240531143948587
// 给相关页面页发消息进行切换
if (extracted) {
// 后面可以添加更严格的判断
// 发给menu
uni.$emit('scanCode', extracted);
// 发给发给子页面
uni.$emit('scanCodeDetail', extracted);
return
}
} else {
console.log("字符串格式不正确,没有足够的冒号");
}
uni.showToast({
title: "非本应用格式暂不支持",
icon: "none",
duration: 2e3
});
}
const keypress = (e : any) => {
console.log('keypress e', JSON.stringify(e), codeToStr(e.keyCode));
if (e.keyCode === 66 || e.key == 'Enter') {
inputString.value = inputCache.value;
onConfirm(inputString.value)
inputCache.value = '';
} else {
// #ifdef APP-PLUS
inputCache.value += codeToStr(e.keyCode) || ''
// #endif
// #ifdef H5
inputCache.value += e.key
// #endif
}
}
onLoad((options) => {
console.log("index onLoad")
// #ifdef APP-PLUS
plus.key.addEventListener("keyup", keypress);
// #endif
// #ifdef H5
document.addEventListener("keyup", keypress);
// #endif
})
onUnload(() => {
console.log("index onUnload")
// #ifdef APP-PLUS
plus.key.removeEventListener("keyup", keypress)
// #endif
// #ifdef H5
document.removeEventListener("keyup", keypress)
// #endif
})
原生实现
override fun dispatchKeyEvent(event: KeyEvent?): Boolean {
if (event?.action == KeyEvent.ACTION_DOWN) {
val keyCode = event.keyCode
if (mScanGun?.isMaybeScanning(keyCode, event) == true) {
return true
}
}
return super.dispatchKeyEvent(event)
}
实际过程中都能得到event,但直接获取code又有问题,下面给个我目前使用支持中文和数字的转化,我也一直没有找到完整的,感觉像asicll码偏移了,只能限制业务逻辑中只有数字英文和固定字符,如果有字符需求 ,直接自己生成一个二维码然后去扫出来看看是什么
uniapp
// keymap.js 以下来源网络收集,不同的设备对应的keyCode可能不同
// 随手给的设备没有文档只能自己苦逼研究解码 发现少了就自己加,目前为安卓平台测试结果
// 大概率是ASCII偏移了
let keyMap = {
"7": "0",
"8": "1",
"9": "2",
"10": "3",
"11": "4",
"12": "5",
"13": "6",
"14": "7",
"15": "8",
"16": "9",
"29": "A",
"30": "B",
"31": "C",
"32": "D",
"33": "E",
"34": "F",
"35": "G",
"36": "H",
"37": "I",
"38": "J",
"39": "K",
"40": "L",
"41": "M",
"42": "N",
"43": "O",
"44": "P",
"45": "Q",
"46": "R",
"47": "S",
"48": "T",
"49": "U",
"50": "V",
"51": "W",
"52": "X",
"53": "Y",
"54": "Z",
"55": ",",
"56": ".",
"59": "",
"69": "-",
"70": "=",
"81": "+",
"74": ":",
}
export function codeToStr(code: keyof typeof keyMap) : String {
return keyMap[code]
}
我这边直接就把keyCode 转化成字符串拼接完事了
其他人的工具类
//
// Source code recreated from a .class file by IntelliJ IDEA
// (powered by FernFlower decompiler)
//
package com.chice.scangun;
import android.view.KeyEvent;
public class ScanGun {
public static final int MAX_KEYS_INTERVAL_DEFAULT = 20;
private long currentTime = 0L;
private boolean isKeySHIFT = false;
private StringBuilder stringBuilder = new StringBuilder();
private ScanGunCallBack callBack = null;
private static int maxKeysInterval = 20;
public static void setMaxKeysInterval(int interval) {
maxKeysInterval = interval;
}
public ScanGun(ScanGunCallBack callBack) {
this.callBack = callBack;
}
public boolean isMaybeScanning(int keyCode, KeyEvent event) {
if (event.getFlags() != 8) {
return false;
} else {
if (this.currentTime == 0L) {
if (this.stringBuilder.length() > 0) {
this.stringBuilder = this.stringBuilder.delete(0, this.stringBuilder.length());
}
this.currentTime = System.currentTimeMillis();
} else {
if (System.currentTimeMillis() - this.currentTime > (long)maxKeysInterval && this.stringBuilder.length() > 0) {
this.stringBuilder = this.stringBuilder.delete(0, this.stringBuilder.length());
}
this.currentTime = System.currentTimeMillis();
}
if (keyCode == 59) {
this.isKeySHIFT = true;
}
if (keyCode == 66) {
this.isKeySHIFT = false;
this.currentTime = 0L;
if (this.callBack != null) {
this.callBack.onScanFinish(this.stringBuilder.toString());
}
return true;
} else {
if (keyCode >= 7 && keyCode <= 16) {
this.handleTopNumKeys(keyCode);
} else if (keyCode >= 29 && keyCode <= 54) {
this.checkShift((char)(keyCode + 68), (char)(keyCode + 36));
} else {
if (keyCode < 144 || keyCode > 158) {
switch (keyCode) {
case 55:
this.checkShift(',', '<');
break;
case 56:
this.checkShift('.', '>');
break;
case 57:
case 58:
case 59:
case 60:
case 61:
case 63:
case 64:
case 65:
case 66:
case 67:
default:
return false;
case 62:
this.stringBuilder.append(' ');
break;
case 68:
this.checkShift('`', '~');
break;
case 69:
this.checkShift('-', '_');
break;
case 70:
this.checkShift('=', '+');
break;
case 71:
this.checkShift('[', '{');
break;
case 72:
this.checkShift(']', '}');
break;
case 73:
this.checkShift('\\', '|');
break;
case 74:
this.checkShift(';', ':');
break;
case 75:
this.checkShift('\'', '"');
break;
case 76:
this.checkShift('/', '?');
}
return true;
}
this.handleNumPadKeys(keyCode);
}
return true;
}
}
}
private void checkShift(char ascallNoShift, char ascallOnShift) {
if (this.isKeySHIFT) {
this.stringBuilder.append(ascallOnShift);
this.isKeySHIFT = false;
} else {
this.stringBuilder.append(ascallNoShift);
}
}
private void handleNumPadKeys(int keyCode) {
if (keyCode <= 153) {
this.stringBuilder.append((char)(keyCode - 96));
} else if (keyCode == 154) {
this.stringBuilder.append('/');
} else if (keyCode == 155) {
this.stringBuilder.append('*');
} else if (keyCode == 156) {
this.stringBuilder.append('-');
} else if (keyCode == 157) {
this.stringBuilder.append('+');
} else if (keyCode == 158) {
this.stringBuilder.append('.');
}
}
private void handleTopNumKeys(int keyCode) {
if (keyCode >= 7 && keyCode <= 16) {
switch (keyCode) {
case 7:
this.checkShift('0', ')');
break;
case 8:
this.checkShift('1', '!');
break;
case 9:
this.checkShift('2', '@');
break;
case 10:
this.checkShift('3', '#');
break;
case 11:
this.checkShift('4', '$');
break;
case 12:
this.checkShift('5', '%');
break;
case 13:
this.checkShift('6', '^');
break;
case 14:
this.checkShift('7', '&');
break;
case 15:
this.checkShift('8', '*');
break;
case 16:
this.checkShift('9', '(');
}
}
}
public interface ScanGunCallBack {
void onScanFinish(String var1);
}
}