手持终端厂商扫码支持:键盘模式输出扫描结果、广播模式调用,API方式调用,uni-app由于是混合开发,无法使用原生api方式调用,键盘模式会导致结果随意输出,广播模式成为首选,uni-app是支持自定义广播发送和接收的
首先确定广播消息的两个参数,广播名称和广播标签
创建一个激光扫码的组件,我们在这里是project_root/components/scan/scan.vue,并写入以下代码:
var main, receiver, filter;
var _codeQueryTag = false;
export default {
data() {
return {
scanCode: ''
}
},
created: function(option) {
this.initScan()
this.startScan();
},
onHide: function() {
this.stopScan();
},
destroyed: function() {
this.stopScan();
},
methods: {
initScan() {
let _this = this;
main = plus.android.runtimeMainActivity();
var IntentFilter = plus.android.importClass('android.content.IntentFilter');
filter = new IntentFilter();
//下面的addAction内改为自己的广播动作
filter.addAction("com.android.serial.BARCODEPORT_RECEIVEDDATA_ACTION");
receiver = plus.android.implements('io.dcloud.feature.internal.reflect.BroadcastReceiver', {
onReceive: function(context, intent) {
plus.android.importClass(intent);
//下面的getStringExtra内改为自己的广播标签
let code = intent.getStringExtra("DATA");
_this.queryCode(code);
}
});
},
startScan() {
main.registerReceiver(receiver, filter);
},
stopScan() {
main.unregisterReceiver(receiver);
},
queryCode: function(code) {
if (_codeQueryTag) return false;
_codeQueryTag = true;
setTimeout(function() {
_codeQueryTag = false;
}, 150);
var id = code
console.log('id:', id)
uni.$emit('scan', {
code: id
})
}
}
}
处理完组件后,在需要使用激光扫码的页面中引入该组件进行使用,在这里我以index.vue
页面为例:
我是index页面
//记得引入组件
import scan from "@/components/scan/scan.vue";
export default {
//引入组件
components: {
scan
},
data() {
return {
code: ''
}
},
onShow: function() {
let that = this
uni.$off('scan') // 每次进来先 移除全局自定义事件监听器
uni.$on('scan', function(data) {
//扫码成功后的回调,你可以写自己的逻辑代码在这里
console.log('扫码结果:', data.code);
})
},
methods: {
}
}
到这里,在应用里跳转到打开index.vue
页面后,直接按激光扫码的按键就能够取得结果,再针对自己的操作逻辑,在回调中补充自己的逻辑代码即可。
同样以index.vue
页面为例
export default {
data() {
return {
userCode: '',
main: '',
receiver: '',
filter: '',
}
},
methods: {
//打开扫描头的方法
bindUserCode() {
this.initScan();
this.startScan();
},
initScan() {
let that = this;
//获取Android主Activity
that.main = plus.android.runtimeMainActivity();
//获取Android意图类
let Intent = plus.android.importClass('android.content.Intent');
//实例化意图
let intent = new Intent();
//定义意图,模拟按下L键,L键实际上是打开激光的物理键映射,由厂商提供
intent.setAction("com.android.action.keyevent.KEYCODE_KEYCODE_SCAN_L_DOWN");
//广播这个意图
that.main.sendBroadcast(intent);
//获取Android意图过滤类
let IntentFilter = plus.android.importClass('android.content.IntentFilter');
//实例化意图过滤
that.filter = new IntentFilter();
//获取扫码成功的意图广播
that.filter.addAction("com.android.serial.BARCODEPORT_RECEIVEDDATA_ACTION");
that.receiver = plus.android.implements('io.dcloud.feature.internal.reflect.BroadcastReceiver', {
onReceive: function(context, intent) {
plus.android.importClass(intent);
let code = intent.getStringExtra("DATA");
//成功输出扫码内容
console.log(code);
}
});
},
startScan() {
this.main.registerReceiver(this.receiver, this.filter);
}
}
}