睿豐厚德堅(jiān)果手持機(jī)終端本身自帶掃描插件,可以把掃描的一維碼,二維碼輸出到焦點(diǎn)編輯框或者焦點(diǎn)輸入框中,并附加回車事件(Enter)作為結(jié)束符,所以開發(fā)者無論用UNI-app還是其他工具進(jìn)行開發(fā),都可以通過監(jiān)聽回車事件進(jìn)行操作判斷。
攝像頭掃碼兼容性最高,也是一種軟解的解決方案,理論上只要帶有光學(xué)攝像頭的終端設(shè)備都可以實(shí)現(xiàn)解碼過程,但是其解碼過程很依賴終端性能,有些低端設(shè)備搭載的攝像頭在對焦上需要花費(fèi)更多的時(shí)候,這對一些高度依賴效率的工作內(nèi)容產(chǎn)生一定的阻礙,比如大批量的工單掃碼。
因此,使用攝像頭掃碼方案也是可以達(dá)到可以使用的層級,如果需要應(yīng)付一些追求效率的內(nèi)容就顯得相對困難。
uni.scanCode({
//成功回調(diào)
success: function (res) {
//條碼類型
console.log(res.scanType);
//條碼的值
console.log(res.result);
},
//失敗回調(diào)
fail: function (res) {},
//完成回調(diào)
complete: function (res) {},
});復(fù)制代碼
這是硬解的方案,掃碼的速度遠(yuǎn)高于需要喚醒過程的攝像頭掃碼方式,激光掃碼幾乎可以實(shí)時(shí)返回結(jié)果。不過其依賴Android 8以上的版本才可以通過廣播的方式被應(yīng)用監(jiān)聽,因此在開發(fā)的過程中會(huì)造成一些阻礙。無論是原生的Android開發(fā)方式,還是像uni-app的跨平臺(tái)解決方案,都需要在激光掃描模塊獲取到結(jié)果后向系統(tǒng)發(fā)出一條廣播,接著可以通過應(yīng)用監(jiān)聽廣播的方式來獲取掃碼結(jié)果。
在一些設(shè)備上,需要手動(dòng)設(shè)置廣播:
設(shè)置 -> 掃描 -> Default -> 關(guān)閉1復(fù)制代碼
在另一些設(shè)備上,系統(tǒng)是沒有廣播設(shè)置的,不過一般廠家都會(huì)帶上自己的硬解掃碼工具供用戶配置,具體的細(xì)節(jié)可以咨詢對應(yīng)的廠家。
然后,我們需要確定 2 個(gè)變量的值:
廣播動(dòng)作和廣播標(biāo)簽,你可以簡單的將這兩個(gè)變量理解為key-value,這兩者都可以在設(shè)備上進(jìn)行自定義設(shè)置,如果沒有設(shè)置項(xiàng),需要向廠家了解。
創(chuàng)建一個(gè)激光掃碼的組件,我們在這里是project_root/components/scan/scan.vue,并寫入以下代碼:
<template>
<view></view>
</template>
<script>
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內(nèi)改為自己的廣播動(dòng)作
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內(nèi)改為自己的廣播標(biāo)簽
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
})
}
}
}
</script>復(fù)制代碼
處理完組件后,在需要使用激光掃碼的頁面中引入該組件進(jìn)行使用,在這里我以index.vue頁面為例:
<template>
<view>我是index頁面</view>
<!-- 還要記得這里加上組件 -->
<scan></scan>
</template>
<script>
//記得引入組件
import scan from "@/components/scan/scan.vue";
export default {
//引入組件
components: {
scan
},
data() {
return {
code: ''
}
},
onShow: function() {
let that = this
uni.$off('scan') // 每次進(jìn)來先 移除全局自定義事件監(jiān)聽器
uni.$on('scan', function(data) {
//掃碼成功后的回調(diào),你可以寫自己的邏輯代碼在這里
console.log('掃碼結(jié)果:', data.code);
})
},
methods: {
}
}
</script>復(fù)制代碼
到這里,在應(yīng)用里跳轉(zhuǎn)到打開index.vue頁面后,直接按激光掃碼的按鍵就能夠取得結(jié)果,再針對自己的操作邏輯,在回調(diào)中補(bǔ)充自己的邏輯代碼即可。
在之前,我無法使用軟件的方式調(diào)用激光掃描模塊,只能使用物理鍵來打開掃描頭,現(xiàn)在已經(jīng)有了解決方案。
同樣以index.vue頁面為例(這里我出于方便用單頁面舉例,把所有的掃描相關(guān)方法寫在一起)。
<template>
<view>
<button>已綁定工號(hào){{userCode}}</button>
</view>
</template>
<script>
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');
//實(shí)例化意圖
let intent = new Intent();
//定義意圖,模擬按下L鍵,L鍵實(shí)際上是打開激光的物理鍵映射,由廠商提供
intent.setAction("com.android.action.keyevent.KEYCODE_KEYCODE_SCAN_L_DOWN");
//廣播這個(gè)意圖
that.main.sendBroadcast(intent);
//獲取Android意圖過濾類
let IntentFilter = plus.android.importClass('android.content.IntentFilter');
//實(shí)例化意圖過濾
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");
//成功輸出掃碼內(nèi)容
console.log(code);
}
});
},
startScan() {
this.main.registerReceiver(this.receiver, this.filter);
}
}
}
</script>復(fù)制代碼