背景介绍
最近老板又随便丢过来一个扫码枪让我研究快速上线,我心想着又是什么串口通信吗,结果发现是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) {// 后面可以添加更严格的判断// 发给menuuni.$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-PLUSinputCache.value += codeToStr(e.keyCode) || ''// #endif // #ifdef H5inputCache.value += e.key// #endif}}onLoad((options) => {console.log("index onLoad")// #ifdef APP-PLUSplus.key.addEventListener("keyup", keypress);// #endif // #ifdef H5document.addEventListener("keyup", keypress);// #endif})onUnload(() => {console.log("index onUnload")// #ifdef APP-PLUSplus.key.removeEventListener("keyup", keypress)// #endif// #ifdef H5document.removeEventListener("keyup", keypress)// #endif})
原生实现
override fun dispatchKeyEvent(event: KeyEvent?): Boolean {if (event?.action == KeyEvent.ACTION_DOWN) {val keyCode = event.keyCodeif (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);}
}