1. 原理
说明:项目中使用的是标准的扫码枪,标准的意思就是它都不给开发文档。走的标准“输入事件”,和外接键盘是一样的。扫码枪扫描到的条形码每一位会触发一次onkeydown事件。比如扫描条码位‘1234567890’的条形码,会连续执行10次onkeydown事件,条码扫描到最后一位,会直接触发Enter(标准扫描枪扫描数据会触发KEYCODE_ENTER键)。
拓展:
扫码枪的种类有蓝牙、USB、串口等等,目前USB的扫码枪主流的就是以下两种:
- USB HID-KBW:支持 Android 热插拔USB扫描枪会在有EditText时,扫描枪扫描内容自动输入到编辑框了,即扫码器会将扫描出来的内容转化为键盘事件,就是Android中KeyEvent里面对应的常量(KeyEvent.KEYCODE_*)。但是有很多输入法兼容的问题,比如搜狗输入法识别到HID设备时会隐藏无法弹出,如果输入法切换成中文时会输入中文等等。
- USB 虚拟串口:通过串口的方式直接获取原始数据,不再跟输入法产生冲突。可使用android-serialport-api连接到UsbDevice进行通信,读取数据;但扫码枪设备要支持串口(扫码枪若是USB HID则不支持串口)。
2. 优缺点
(1) 优点:
- 不需要额外供电以及价格便宜
- 即插即用:实质其实就是相当于设备的外接键盘,也就是它必须在有光标的地方才能进行扫码,且是直接把扫到的内容自动输入到输入框中,并不受我们的控制
- 直接通过串口读取流里面的数据
(2) 缺点:需要知道每一款扫码器的型号以获取波特率及Android设备的串口地址。
备注:我的项目在实现获取扫码枪数据的过程中并未体现该缺点。
3. 监听扫码枪事件获取数据
备注:扫码枪就是 = 键盘 + 回车,即外接接盘。所以建个txt文本文档或者doc随便,打开,然后连接扫码枪,开始扫描,扫码结果就会自动填入你的文档。
- 方案一:监听键盘的keydown事件(监听js键盘事件)
分析:uniapp无document对象,无法获取keydown事件。无键盘事件,不支持键盘修饰符。 - 方案二:通过native.js调用安卓原生类库,通过广播方式实现扫码结果的接收。参考1、参考2、参考三
分析:需从厂商那里获取到android开发文档,查看扫码广播标识(意图action)
对应的字段。
var main,receiver,filter;
① 在过滤器中添加扫码广播标识(意图action)
var IntentFilter = plus.android.importClass('android.content.IntentFilter');
filter = new IntentFilter();
filter.addAction("com.se4500.onDecodeComplete"); //监听扫描
//filter.addAction("com.zkc.scancode");//监听扫描
注意
:不同厂商扫码广播标识action对应的字段不一样,这里以com.se4500.onDecodeComplete为例。
② 注册广播接受者BroadcastReceiver并重写onReceive()方法
receiver = plus.android.implements('io.dcloud.feature.internal.reflect.BroadcastReceiver',{
onReceive : function(context, intent) {
plus.android.importClass(intent); //通过intent实例引入intent类,方便以后的‘.’操作
/*这个se4500很坑,不同的手机或pda,这个值就不一样,要具体去查硬件api*/
var code = intent.getStringExtra("se4500");
// var code = intent.getStringExtra("code");
console.log('条码:',code);
}});
注意
:获取扫码数据时,此处key为se4500仅为示例,不同手机或pda,这个值不一样,具体要去查硬件api。
③ 注册监听
main = plus.android.runtimeMainActivity();//获取activity
main.registerReceiver(receiver,filter); //注册监听
④ 注销监听
main.unregisterReceiver(receiver); //取消监听
- 方案三:使用 5+ 的api监听键盘事件
分析:H5 和小程序不能监听键盘事件,但是app端可通过使用 5+ 的api监听键盘事件。经测试,app端使用 5+ 的api未能监听到键盘事件。
这种方案应该是最合适的,但是测试未成功,这里仅提供一个思路,可能我的实现方法错了,虚心求教有思路的小伙伴。
<template>
<view>
plus监听原生扩展事件:扫码结果{{resultValue}}
</view>
</template>
<script>
var _self;
export default {
data() {
return {
resultValue:""
}
},
methods: {
},
onLoad:function(){
_self = this;
// #ifdef APP-PLUS
/* plus.key.addEventListener('backbutton',function(KeyEvent){
console.log("点击了返回键:" + JSON.stringify(KeyEvent));
console.log("点击了返回键:" + KeyEvent.keyCode);
}); */
plus.key.addEventListener('keydown',function(KeyEvent){
console.log("按下了键:" + JSON.stringify(KeyEvent));
console.log("按下了键:" + KeyEvent.keyCode);
if(KeyEvent.keyCode == 9){
//plus.nativeUI.toast("Tab结束符");
plus.nativeUI.toast("resultValue:" + _self.resultValue);
_self.resultValue = "";
}else if(KeyEvent.keyCode == 10){
//plus.nativeUI.toast("换行结束符");
plus.nativeUI.toast("resultValue:" + _self.resultValue);
_self.resultValue = "";
}else if(KeyEvent.keyCode == 13){
//plus.nativeUI.toast("按下了回车键");
plus.nativeUI.toast("resultValue:" + _self.resultValue);
_self.resultValue = "";
}else if(KeyEvent.keyCode == 48){
_self.resultValue = _self.resultValue + "0";
}else if(KeyEvent.keyCode == 49){
_self.resultValue = _self.resultValue + "1";
}else if(KeyEvent.keyCode == 50){
_self.resultValue = _self.resultValue + "2";
}else if(KeyEvent.keyCode == 51){
_self.resultValue = _self.resultValue + "3";
}else if(KeyEvent.keyCode == 52){
_self.resultValue = _self.resultValue + "4";
}else if(KeyEvent.keyCode == 53){
_self.resultValue = _self.resultValue + "5";
}else if(KeyEvent.keyCode == 54){
_self.resultValue = _self.resultValue + "6";
}else if(KeyEvent.keyCode == 55){
_self.resultValue = _self.resultValue + "7";
}else if(KeyEvent.keyCode == 56){
_self.resultValue = _self.resultValue + "8";
}else if(KeyEvent.keyCode == 57){
_self.resultValue = _self.resultValue + "9";
}else if(KeyEvent.keyCode == 65){
_self.resultValue = _self.resultValue + "A";
}else if(KeyEvent.keyCode == 66){
_self.resultValue = _self.resultValue + "B";
}else if(KeyEvent.keyCode == 67){
_self.resultValue = _self.resultValue + "C";
}else if(KeyEvent.keyCode == 68){
_self.resultValue = _self.resultValue + "D";
}else if(KeyEvent.keyCode == 69){
_self.resultValue = _self.resultValue + "E";
}else if(KeyEvent.keyCode == 70){
_self.resultValue = _self.resultValue + "F";
}else if(KeyEvent.keyCode == 71){
_self.resultValue = _self.resultValue + "G";
}else if(KeyEvent.keyCode == 72){
_self.resultValue = _self.resultValue + "H";
}else if(KeyEvent.keyCode == 73){
_self.resultValue = _self.resultValue + "I";
}else if(KeyEvent.keyCode == 74){
_self.resultValue = _self.resultValue + "J";
}else if(KeyEvent.keyCode ==75){
_self.resultValue = _self.resultValue + "K";
}else if(KeyEvent.keyCode == 76){
_self.resultValue = _self.resultValue + "L";
}else if(KeyEvent.keyCode == 77){
_self.resultValue = _self.resultValue + "M";
}else if(KeyEvent.keyCode == 78){
_self.resultValue = _self.resultValue + "N";
}else if(KeyEvent.keyCode == 79){
_self.resultValue = _self.resultValue + "O";
}else if(KeyEvent.keyCode == 80){
_self.resultValue = _self.resultValue + "P";
}else if(KeyEvent.keyCode == 81){
_self.resultValue = _self.resultValue + "Q";
}else if(KeyEvent.keyCode == 82){
_self.resultValue = _self.resultValue + "R";
}else if(KeyEvent.keyCode == 83){
_self.resultValue = _self.resultValue + "S";
}else if(KeyEvent.keyCode == 84){
_self.resultValue = _self.resultValue + "T";
}else if(KeyEvent.keyCode == 85){
_self.resultValue = _self.resultValue + "U";
}else if(KeyEvent.keyCode == 86){
_self.resultValue = _self.resultValue + "V";
}else if(KeyEvent.keyCode == 87){
_self.resultValue = _self.resultValue + "W";
}else if(KeyEvent.keyCode == 88){
_self.resultValue = _self.resultValue + "X";
}else if(KeyEvent.keyCode == 89){
_self.resultValue = _self.resultValue + "Y";
}else if(KeyEvent.keyCode == 96){
_self.resultValue = _self.resultValue + "0";
}else if(KeyEvent.keyCode == 97){
_self.resultValue = _self.resultValue + "1";
}else if(KeyEvent.keyCode == 98){
_self.resultValue = _self.resultValue + "2";
}else if(KeyEvent.keyCode == 99){
_self.resultValue = _self.resultValue + "3";
}else if(KeyEvent.keyCode == 100){
_self.resultValue = _self.resultValue + "4";
}else if(KeyEvent.keyCode == 101){
_self.resultValue = _self.resultValue + "5";
}else if(KeyEvent.keyCode == 102){
_self.resultValue = _self.resultValue + "6";
}else if(KeyEvent.keyCode == 103){
_self.resultValue = _self.resultValue + "7";
}else if(KeyEvent.keyCode == 104){
_self.resultValue = _self.resultValue + "8";
}else if(KeyEvent.keyCode == 105){
_self.resultValue = _self.resultValue + "9";
}else if(KeyEvent.keyCode == 108){
//plus.nativeUI.toast("按下了回车键");
plus.nativeUI.toast("resultValue:" + _self.resultValue);
_self.resultValue = "0";
}else{
_self.resultValue = _self.resultValue + "y";
}
});
/* plus.key.addEventListener('keyup',function(KeyEvent){
console.log("松开了键:" + JSON.stringify(KeyEvent));
console.log("松开了键:" + KeyEvent.keyCode);
}); */
// #endif
},
}
</script>
<style>
</style>
监听设备键盘事件可参考:监听事件(系统事件+设备按键事件+自定义事件)。
- 方案四:参考原生Android外接USB扫码枪,生成插件在uniapp中使用。
分析:原生实现中是通过拦截dispatchKeyEvent(KeyEvent event)方法来自己处理键盘的输入事件。是否能封装成插件尚在研究中。 - 方案五:使用 input 输入框控件来接收
分析:输入框可直接接收扫码枪数据
方案:主要通过使用 input 的 @input 和 @confirm 事件来实现
备注:页面其实并不需要显示input控件,这里只作为接受数据的作用,所以尽可能在界面中隐藏该控件,从而达到既不影响用户体验又能实现我们的功能
<input v-if="isUseScanGun" class="jk-footer" style="width: 1px;" :value="inputValue" :focus="isFocus" maxlength="-1"
@input="onInput" @focus="onFocus" @blur="onBlur" @confirm="onConfirm"/>
说明:具体实现过程中有一些细节问题需要处理,详情见下问题汇总
。
4. 问题汇总
4.1 失焦导致无法获取扫码数据
说明:输入框聚焦后扫码枪才可以把内容输出到输入框中,失去焦点将导致不能获取到扫码数据,或者说是需手动聚焦后才能获取到扫码数据。
(1) 失焦描述1:虽然设置了输入框的聚焦属性,扫码一次后就会失去焦点
解决方案:输入框失焦时重新在 @blur 事件中重新设置焦点
注意:此时需在输入事件中设置焦点属性为false,之后 @blur 事件会自动被调用,从而获取到焦点。
onInput:function(e){
console.log("键盘输入:" + e.detail.value);
_self.isFocus = false;
},
onFocus:function(){
console.log("输入框聚焦");
},
onBlur:function(){
console.log("输入框失去焦点");
_self.isFocus = true;
},
(2) 失焦描述2:点击界面上除输入框的其他位置,也会导致输入框失去焦点
解决方案:给整个页面的根节点设置点击事件,重新获取焦点。
注意:此时需设置焦点属性为false,之后 @blur 事件会自动被调用,从而获取到焦点。
<template>
<view class="uni-flex uni-column" style="height: 100%;" @tap="setFocus()">
<view class="uni-flex uni-row jk-bg-blue uni-center" style="height: 12%;">
<input class="jk-footer" style="width: 1px;" :value="inputValue" :focus="isFocus" maxlength="-1" @input="input" @focus="focus" @blur="blur" @confirm="confirm"/>
</view>
<view class="uni-flex" style="height: 88%;">
<view class="uni-flex justify-center align-center uni-column" style="width: 100%;height: 100%;">
</view>
</view>
</view>
</template>
setFocus:function(){
console.log("setFocus-1: " + _self.isFocus + "");
_self.isFocus = false;
console.log("setFocus-2: " + _self.isFocus + "");
},
备注
:经验证,还需在manifest.json配置文件关闭沉浸式
,否则无法重新获取焦点(刚好项目之前因需去掉原生导航故关闭了沉浸式,所以开始的没发现需关闭沉浸式才能重新聚焦的问题)。原因未知,望知道的小伙伴告知一下。
/* 5+App特有相关 */
"app-plus": {
"statusbar" : {
"immersed" : false //关闭沉浸式:解决去掉原生导航后,主内容顶到状态栏的问题;扫码枪-输入框聚焦问题(原因未知)
},
},
拓展:窗体默认是沉浸式(即全屏可写内容)。若不启用原生导航,手机顶部状态栏区域会被页面内容覆盖;而系统导航栏会自动处理状态栏高度占位问题,不会出现手机顶部状态栏区域被页面内容覆盖的问题。参考自定义导航栏使用注意。
4.2 聚集导致屏幕弹出软键盘问题
描述:连接扫码枪后,每次聚焦操作都会引起页面弹出软键盘
尝试:使用官网的隐藏软键盘api并不能完全禁用软键盘
onFocus:function(){
console.log("输入框聚焦");
// 并不能完全禁用软键盘
setTimeout(function(){
uni.hideKeyboard();//隐藏软键盘:隐藏已经显示的软键盘,如果软键盘没有显示则不做任何操作
// plus.key.hideSoftKeybord();//隐藏软键盘:隐藏已经显示的软键盘,如果软键盘没有显示则不做任何操作
},250);
},
分析:系统设置中,连接到实体键盘时,虚拟键盘默认在屏幕上保持显示状态
解决方案:设置当连接到实体键盘时,关闭虚拟键盘(无实体键盘时才会弹出软键盘)
步骤:设置 -> 语言和输入法 -> 实体键盘 -> 关闭
显示虚拟键盘
说明:这种系统设置的方案,仅能解决在外接设备的情况下禁用软键盘,但是在没有外接设备的情况下,输入框聚焦还是会弹出软键盘,用户体验不好。
备注
:已找到解决软键盘弹出问题的办法,并替代上面的系统设置的方案。
4.3 输入法默认为中文导致扫码数据乱码问题
说明:系统默认输入法是谷歌拼音输入法(中文输入法),导致扫码扫出来中文,扫码数据不对
解决方案:切换输入法为英文输入法。
步骤:设置 -> 语言和输入法 -> 虚拟键盘 -> 管理键盘 -> 打开
Android键盘(英文输入法)
注意:虽然系统设置为英文输入法,但是若在登录输入时(或其他情况的输入)软键盘需要切换为中文进行手动输入,仍会导致之后的扫码乱码。解决办法就是输入后软键盘再切换为英文。
4.4 字符截取问题
说明:每次扫码数据都会拼接到输入框中(输入框默认最大输入长度maxlength为140),但是我们只需要每次的扫码数据。
解决方案1(双向绑定未成功):使用双向绑定,并监听每次扫码的完成事件 @confirm,获取当次扫码数据后清空输入框数据。
分析:在输入完成事件中清空输入框将导致下次扫码获取到错误数据,可能和输入框的输入事件@input 是一个字符一个字符读取有关。
解决方案2(扫码位数有局限性):设置不限制输入框的最大长度(maxlength = -1),在输入完成事件中截取最后约定的位数作为扫码结果。
分析:所要扫的有效二维码位数已固定。
onConfirm:function(e){
console.log("点击完成按钮");
var str = e.detail.value;
var result = str.substring(str.length-13);//截取后13位
uni.showToast({
title: result
});
},
解决方案3(成功截取每次扫码结果):通过当前扫码输入框字符串减去上次扫码输入框字符串,获取到每次扫码结果
data() {
return {
lastInputValue:"",
}
},
methods: {
onConfirm:function(e){
console.log("点击完成按钮");
var currentInputValue = e.detail.value;
var newValue = "";
if(_self.lastInputValue == ""){
newValue = currentInputValue;
}else{
//newValue = currentInputValue.replace(_self.lastInputValue,"");
newValue = currentInputValue.substring(_self.lastInputValue.length);
}
_self.lastInputValue = currentInputValue;
console.log("扫码结果:" + newValue);
uni.showToast({
title: newValue
});
},
},
4.5 应用重启问题
关注帖子:在APP上接入USB扫描枪到导致重启 (UNI-APP)
描述: 当应用打开时,插拔键盘或扫码枪会导致应用重启,连接扫码枪时扫码枪恢复出厂设置也会导致应用重启
分析:可能是检测到键盘类型改变引起的,类似android中屏幕旋转导致activity销毁又重建
解决方案:先接线,后打开应用
注意:接线时,若转接头和平板连接后再连接扫码枪,无法给扫码枪供电;正确的接线顺序为,转接头和扫码枪连接后再连接平板。
备注
:该方案仅能规避连接扫码枪时应用重启问题,尚未找到解决断开扫码枪时应用重启问题的方案。
更新HbuilderX版本后问题解决,经查证2.4.1.20191114版本修复了该问题。
拓展:热插拔
备注
:完整代码示例
<template>
<view class="uni-flex uni-column" style="height: 100%;" @tap="setFocus()">
<view class="uni-flex uni-row uni-bg-blue uni-center" style="height: 12%;">
<!-- <input style="width: 1px;font-size: 15px;align-self: center;" v-model="inputValue" :focus="isFocus" maxlength="-1" @input="input" @focus="focus" @blur="blur" @confirm="confirm"/> -->
<input style="width: 1px;font-size: 15px;align-self: center;" :value="inputValue" :focus="isFocus" maxlength="-1" @input="input" @focus="focus" @blur="blur" @confirm="confirm"/>
</view>
<view class="uni-flex" style="height: 88%;">
<view class="uni-flex justify-center align-center uni-column" style="width: 100%;height: 100%;">
</view>
</view>
</view>
</template>
<script>
var _self;
export default {
data() {
return {
isFocus:true,
inputValue:"",
lastInputValue:"",
}
},
methods: {
setFocus:function(){
console.log("setFocus-1: " + _self.isFocus + "");
_self.isFocus = false;
console.log("setFocus-2: " + _self.isFocus + "");
},
input:function(e){
console.log("键盘输入:" + e.detail.value);
_self.isFocus = false;
},
focus:function(){
console.log("输入框聚焦:" + _self.isFocus);
// 并不能完全禁用软键盘
setTimeout(function(){
uni.hideKeyboard();//隐藏软键盘:隐藏已经显示的软键盘,如果软键盘没有显示则不做任何操作
// plus.key.hideSoftKeybord();//隐藏软键盘:隐藏已经显示的软键盘,如果软键盘没有显示则不做任何操作
},250);
},
blur:function(){
console.log("输入框失去焦点:" + _self.isFocus);
_self.isFocus = true;
},
confirm:function(e){
console.log("点击完成按钮");
//(1)双向绑定来获取扫码结果:未成功
/* var ticketNo = _self.inputValue;
_self.inputValue = "";
uni.showModal({
title: ticketNo,
content: _self.inputValue + "h"
}); */
//(2)截取扫码结果:扫码位数固定,有局限性
/* var str = e.detail.value;
var result = str.substring(str.length-13);//截取后13位
console.log("扫码结果:" + newValue);
uni.showToast({
title: result
}); */
//(3)截取每次扫码结果:成功
var currentInputValue = e.detail.value;
var newValue = "";
if(_self.lastInputValue == ""){
newValue = currentInputValue;
}else{
//newValue = currentInputValue.replace(_self.lastInputValue,"");
newValue = currentInputValue.substring(_self.lastInputValue.length);
}
_self.lastInputValue = currentInputValue;
console.log("扫码结果:" + newValue);
uni.showToast({
title: newValue
});
},
},
onLoad:function(){
_self = this;
}
}
</script>
<style>
</style>
5. 使用插件—外接键盘扫描枪监听获取输入内容
(1) 在uniapp插件市场购买插件并绑定项目
(2) 在HBuilderX里找到项目,在manifest的app原生插件配置中勾选模块
(3) 在代码中引用插件并调用插件功能
<template>
<view>
<view class="c-hint margin-l-r" style="margin-top: 10rpx;margin-bottom: 50rpx;color: #ff0000;font-size: 24rpx;">Tips:返回结果在页尾打印展示。先点击设置监听,按下数组键
1 或者字母键 a,页面会打印返回数据,供查看数据结构。输入完成,点击 Enter 键,页面会显示拼接结果。</view>
<view class="c-hint margin-l-r" style="margin-top: 30rpx;">tag 字段,不用理会,固定 1 就好</view>
<input v-model="tag" class="margin-l-r" placeholder="请输入" />
<view class="button-sp-area">
<button type="primary" plain="true" @click="onBtn1()">设置监听</button>
</view>
<view class="button-sp-area">
<button type="primary" plain="true" @click="onBtn2()">取消某个监听</button>
</view>
<view class="button-sp-area">
<button type="primary" plain="true" @click="onBtn3()">获取所有监听的tag</button>
</view>
<view class="button-sp-area">
<button type="primary" plain="true" @click="onBtn4()">取消所有监听</button>
</view>
<view class="c-hint margin-l-r text-wrapper" style="margin-top: 30rpx;width: 700rpx;word-break:break-all;">以下打印监听内容。</view>
<view class="c-hint margin-l-r text-wrapper" style="margin-top: 30rpx;width: 700rpx;word-break:break-all;">拼接结果:{{resultStrFinal}}</view>
<view class="c-hint margin-l-r text-wrapper" style="margin-top: 30rpx;margin-bottom: 30rpx;width: 700rpx;word-break:break-all;">{{resultStr}}</view>
</view>
</template>
<script>
var longyoungKeyEventListen;
var preKeyCode = '';
var allKeyCodeTemp = '';
var KEY_MAP = {
"KEYCODE_GRAVE": {
"normalChar": "`",
"shiftChar": "~"
},
"KEYCODE_0": {
"normalChar": "0",
"shiftChar": ")"
},
"KEYCODE_1": {
"normalChar": "1",
"shiftChar": "!"
},
"KEYCODE_2": {
"normalChar": "2",
"shiftChar": "@"
},
"KEYCODE_3": {
"normalChar": "3",
"shiftChar": "#"
},
"KEYCODE_4": {
"normalChar": "4",
"shiftChar": "$"
},
"KEYCODE_5": {
"normalChar": "5",
"shiftChar": "%"
},
"KEYCODE_6": {
"normalChar": "6",
"shiftChar": "^"
},
"KEYCODE_7": {
"normalChar": "7",
"shiftChar": "&"
},
"KEYCODE_8": {
"normalChar": "8",
"shiftChar": "*"
},
"KEYCODE_9": {
"normalChar": "9",
"shiftChar": "("
},
"KEYCODE_MINUS": {
"normalChar": "-",
"shiftChar": "_"
},
"KEYCODE_EQUALS": {
"normalChar": "=",
"shiftChar": "+"
},
"KEYCODE_LEFT_BRACKET": {
"normalChar": "[",
"shiftChar": "{"
},
"KEYCODE_RIGHT_BRACKET": {
"normalChar": "]",
"shiftChar": "}"
},
"KEYCODE_BACKSLASH": {
"normalChar": "\\",
"shiftChar": "|"
},
"KEYCODE_SEMICOLON": {
"normalChar": ";",
"shiftChar": ":"
},
"KEYCODE_APOSTROPHE": {
"normalChar": "'",
"shiftChar": "\""
},
"KEYCODE_COMMA": {
"normalChar": ",",
"shiftChar": "<"
},
"KEYCODE_PERIOD": {
"normalChar": ".",
"shiftChar": ">"
},
"KEYCODE_SLASH": {
"normalChar": "/",
"shiftChar": "?"
},
"KEYCODE_A": {
"normalChar": "a",
"shiftChar": "A"
},
"KEYCODE_B": {
"normalChar": "b",
"shiftChar": "B"
},
"KEYCODE_C": {
"normalChar": "c",
"shiftChar": "C"
},
"KEYCODE_D": {
"normalChar": "d",
"shiftChar": "D"
},
"KEYCODE_E": {
"normalChar": "e",
"shiftChar": "E"
},
"KEYCODE_F": {
"normalChar": "f",
"shiftChar": "F"
},
"KEYCODE_G": {
"normalChar": "g",
"shiftChar": "G"
},
"KEYCODE_H": {
"normalChar": "h",
"shiftChar": "H"
},
"KEYCODE_I": {
"normalChar": "i",
"shiftChar": "I"
},
"KEYCODE_J": {
"normalChar": "j",
"shiftChar": "J"
},
"KEYCODE_K": {
"normalChar": "k",
"shiftChar": "K"
},
"KEYCODE_L": {
"normalChar": "l",
"shiftChar": "L"
},
"KEYCODE_M": {
"normalChar": "m",
"shiftChar": "M"
},
"KEYCODE_N": {
"normalChar": "n",
"shiftChar": "N"
},
"KEYCODE_O": {
"normalChar": "o",
"shiftChar": "O"
},
"KEYCODE_P": {
"normalChar": "p",
"shiftChar": "P"
},
"KEYCODE_Q": {
"normalChar": "q",
"shiftChar": "Q"
},
"KEYCODE_R": {
"normalChar": "r",
"shiftChar": "R"
},
"KEYCODE_S": {
"normalChar": "s",
"shiftChar": "S"
},
"KEYCODE_T": {
"normalChar": "t",
"shiftChar": "T"
},
"KEYCODE_U": {
"normalChar": "u",
"shiftChar": "U"
},
"KEYCODE_V": {
"normalChar": "v",
"shiftChar": "V"
},
"KEYCODE_W": {
"normalChar": "w",
"shiftChar": "W"
},
"KEYCODE_X": {
"normalChar": "x",
"shiftChar": "X"
},
"KEYCODE_Y": {
"normalChar": "y",
"shiftChar": "Y"
},
"KEYCODE_Z": {
"normalChar": "z",
"shiftChar": "Z"
}
};
export default {
data() {
return {
resultStr: "",
tag: "1", //不必理会,固定 1 就好
resultStrFinal: ""
}
},
onLoad() {
let that = this;
// #ifdef APP-PLUS
//引用插件
longyoungKeyEventListen = uni.requireNativePlugin('longyoung-KeyEventListen');
// //设置监听,可设置多个,回调按 tag 区分哪个监听返回。
// longyoungKeyEventListen.setOnKeyEventListenerLy({
// tag: that.tag
// }, result => {
// console.log('lygg.result=' + JSON.stringify(result));
// if (result && result.return_code == 'SUCCESS') {
// if (result.return_type == 'dataBack') {//return_type=dataBack是返回数据标识,返回的数据在此获取
// //页面只显示1,供查看数据结构
// if (result.keyCode == 'KEYCODE_1') {
// that.resultStr += '\n' + JSON.stringify(result) + '\n';
// }
// uni.showToast({
// title: '成功,' + JSON.stringify(result)
// });
// }
// }
// });
// #endif
},
onUnload() {
let that = this;
// #ifdef APP-PLUS
if (longyoungKeyEventListen) {
//取消所有监听
longyoungKeyEventListen.disableAllOnKeyEventListenerLy({}, result => {
console.log('lygg.result=' + JSON.stringify(result));
if (result && result.return_code == 'SUCCESS') {
uni.showToast({
title: '成功'
})
}
});
}
// #endif
},
methods: {
onBtn1() {
let that = this;
//设置监听,可设置多个,回调按 tag 区分哪个监听返回。
longyoungKeyEventListen.setOnKeyEventListenerLy({
tag: that.tag //不必理会,固定 1 就好
}, result => {
console.log('lygg.result=' + JSON.stringify(result));
if (!result.keyCode) {
that.resultStr += '\n' + JSON.stringify(result) + '\n';
}
if (result && result.return_code == 'SUCCESS') {
if (result.return_type == 'dataBack') { //return_type=dataBack是返回数据标识,返回的数据在此获取
//页面只显示1和a,供查看数据结构
if (result.keyCode == 'KEYCODE_1' || result.keyCode == 'KEYCODE_A') {
that.resultStr += '\n' + JSON.stringify(result) + '\n';
}
that.handleData(result);
}
}
});
},
onBtn2() {
let that = this;
//取消某个 tag 监听
longyoungKeyEventListen.disableOnKeyEventListenerLy({
tag: that.tag //不必理会,固定 1 就好
}, result => {
console.log('lygg.result=' + JSON.stringify(result));
that.resultStr += '\n' + JSON.stringify(result) + '\n';
if (result && result.return_code == 'SUCCESS') {
uni.showToast({
title: '成功'
})
}
});
},
onBtn3() {
let that = this;
//获取所有监听的tag
longyoungKeyEventListen.getAllKeyEventListenerTagLy({}, result => {
console.log('lygg.result=' + JSON.stringify(result));
that.resultStr += '\n' + JSON.stringify(result) + '\n';
if (result && result.return_code == 'SUCCESS') {
uni.showToast({
title: '成功'
})
}
});
},
onBtn4() {
let that = this;
//取消所有监听
longyoungKeyEventListen.disableAllOnKeyEventListenerLy({}, result => {
console.log('lygg.result=' + JSON.stringify(result));
that.resultStr += '\n' + JSON.stringify(result) + '\n';
if (result && result.return_code == 'SUCCESS') {
uni.showToast({
title: '成功'
})
}
});
},
handleData(result) {
let that = this;
console.log('lygg.handleData=' + JSON.stringify(result));
if (result.return_type == 'dataBack') {
if (result.action == 'ACTION_UP') { //只取弹起事件
let keyCode = result.keyCode;
if (keyCode == 'KEYCODE_ENTER') { //扫码结束
that.resultStrFinal = allKeyCodeTemp; //最终拼接的字符串赋值
allKeyCodeTemp = '';
preKeyCode = '';
} else if (keyCode == 'KEYCODE_SHIFT_LEFT' || keyCode == 'KEYCODE_SHIFT_RIGHT') { //转换键
preKeyCode = 'KEYCODE_SHIFT_RIGHT';
} else {
if (preKeyCode == 'KEYCODE_SHIFT_RIGHT') { //转换键,拿大写
if (keyCode && KEY_MAP[keyCode]) {
allKeyCodeTemp += KEY_MAP[keyCode].shiftChar;
}
} else {
if (keyCode && KEY_MAP[keyCode]) {
allKeyCodeTemp += KEY_MAP[keyCode].normalChar;
}
}
preKeyCode = '';
}
}
}
}
}
}
</script>
<style>
.content {
width: 100%;
/* padding: 20rpx; */
}
button {
margin-top: 30rpx;
margin-bottom: 30rpx;
}
.button-sp-area {
margin: 0 auto;
width: 60%;
}
.c-hint {
color: #808080;
}
.margin-l-r {
margin-left: 20rpx;
margin-right: 20rpx;
}
.uni-list-cell {
justify-content: flex-start
}
/* 列表 */
.uni-list {
background-color: #FFFFFF;
position: relative;
width: 100%;
display: flex;
flex-direction: column;
}
.uni-list:after {
position: absolute;
z-index: 10;
right: 0;
bottom: 0;
left: 0;
height: 1px;
content: '';
-webkit-transform: scaleY(.5);
transform: scaleY(.5);
background-color: #c8c7cc;
}
.uni-list::before {
position: absolute;
z-index: 10;
right: 0;
top: 0;
left: 0;
height: 1px;
content: '';
-webkit-transform: scaleY(.5);
transform: scaleY(.5);
background-color: #c8c7cc;
}
.uni-list-cell {
position: relative;
display: flex;
flex-direction: row;
justify-content: space-between;
align-items: center;
}
.uni-list-cell-hover {
background-color: #eee;
}
.uni-list-cell-pd {
padding: 22upx 30upx;
}
.uni-list-cell-left {
font-size: 28upx;
padding: 0 30upx;
}
.uni-list-cell-db,
.uni-list-cell-right {
flex: 1;
}
.uni-list-cell::after {
position: absolute;
z-index: 3;
right: 0;
bottom: 0;
left: 30upx;
height: 1px;
content: '';
-webkit-transform: scaleY(.5);
transform: scaleY(.5);
background-color: #c8c7cc;
}
.uni-list .uni-list-cell:last-child::after {
height: 0upx;
}
.uni-list-cell-last.uni-list-cell::after {
height: 0upx;
}
.uni-list-cell-divider {
position: relative;
display: flex;
color: #999;
background-color: #f7f7f7;
padding: 15upx 20upx;
}
.uni-list-cell-divider::before {
position: absolute;
right: 0;
top: 0;
left: 0;
height: 1px;
content: '';
-webkit-transform: scaleY(.5);
transform: scaleY(.5);
background-color: #c8c7cc;
}
.uni-list-cell-divider::after {
position: absolute;
right: 0;
bottom: 0;
left: 0upx;
height: 1px;
content: '';
-webkit-transform: scaleY(.5);
transform: scaleY(.5);
background-color: #c8c7cc;
}
.uni-list-cell-navigate {
font-size: 30upx;
padding: 22upx 30upx;
line-height: 48upx;
position: relative;
display: flex;
box-sizing: border-box;
width: 100%;
flex: 1;
justify-content: space-between;
align-items: center;
}
.uni-list-cell-navigate {
padding-right: 36upx;
}
.uni-navigate-badge {
padding-right: 50upx;
}
.uni-list-cell-navigate.uni-navigate-right:after {
font-family: uniicons;
content: '\e583';
position: absolute;
right: 24upx;
top: 50%;
color: #bbb;
-webkit-transform: translateY(-50%);
transform: translateY(-50%);
}
.uni-list-cell-navigate.uni-navigate-bottom:after {
font-family: uniicons;
content: '\e581';
position: absolute;
right: 24upx;
top: 50%;
color: #bbb;
-webkit-transform: translateY(-50%);
transform: translateY(-50%);
}
.uni-list-cell-navigate.uni-navigate-bottom.uni-active::after {
font-family: uniicons;
content: '\e580';
position: absolute;
right: 24upx;
top: 50%;
color: #bbb;
-webkit-transform: translateY(-50%);
transform: translateY(-50%);
}
.uni-collapse.uni-list-cell {
flex-direction: column;
}
.uni-list-cell-navigate.uni-active {
background: #eee;
}
.uni-list.uni-collapse {
box-sizing: border-box;
height: 0;
overflow: hidden;
}
.uni-collapse .uni-list-cell {
padding-left: 20upx;
}
.uni-collapse .uni-list-cell::after {
left: 52upx;
}
.uni-list.uni-active {
height: auto;
}
/*换行*/
.text-wrapper {
white-space: pre-wrap;
}
</style>
(4) 重新制作自定义基座,然后选择自定义基座运行调试
(5) 开发完毕后正式云打包