uniapp外接USB掃碼槍并獲取掃碼數(shù)據(jù)

1. 原理

說明:項(xiàng)目中使用的是標(biāo)準(zhǔn)的掃碼槍,標(biāo)準(zhǔn)的意思就是它都不給開發(fā)文檔奸披。走的標(biāo)準(zhǔn)“輸入事件”谦秧,和外接鍵盤是一樣的鼠次。掃碼槍掃描到的條形碼每一位會(huì)觸發(fā)一次onkeydown事件。比如掃描條碼位‘1234567890’的條形碼邢笙,會(huì)連續(xù)執(zhí)行10次onkeydown事件啸如,條碼掃描到最后一位,會(huì)直接觸發(fā)Enter(標(biāo)準(zhǔn)掃描槍掃描數(shù)據(jù)會(huì)觸發(fā)KEYCODE_ENTER鍵)氮惯。

拓展
掃碼槍的種類有藍(lán)牙组底、USB、串口等等筐骇,目前USB的掃碼槍主流的就是以下兩種:

  • USB HID-KBW:支持 Android 熱插拔USB掃描槍會(huì)在有EditText時(shí)债鸡,掃描槍掃描內(nèi)容自動(dòng)輸入到編輯框了,即掃碼器會(huì)將掃描出來的內(nèi)容轉(zhuǎn)化為鍵盤事件铛纬,就是Android中KeyEvent里面對(duì)應(yīng)的常量(KeyEvent.KEYCODE_*)厌均。但是有很多輸入法兼容的問題,比如搜狗輸入法識(shí)別到HID設(shè)備時(shí)會(huì)隱藏?zé)o法彈出告唆,如果輸入法切換成中文時(shí)會(huì)輸入中文等等棺弊。
  • USB 虛擬串口:通過串口的方式直接獲取原始數(shù)據(jù),不再跟輸入法產(chǎn)生沖突擒悬∧K可使用android-serialport-api連接到UsbDevice進(jìn)行通信,讀取數(shù)據(jù)懂牧;但掃碼槍設(shè)備要支持串口(掃碼槍若是USB HID則不支持串口)侈净。

2. 優(yōu)缺點(diǎn)

(1) 優(yōu)點(diǎn):

  • 不需要額外供電以及價(jià)格便宜
  • 即插即用:實(shí)質(zhì)其實(shí)就是相當(dāng)于設(shè)備的外接鍵盤,也就是它必須在有光標(biāo)的地方才能進(jìn)行掃碼僧凤,且是直接把掃到的內(nèi)容自動(dòng)輸入到輸入框中畜侦,并不受我們的控制
  • 直接通過串口讀取流里面的數(shù)據(jù)

(2) 缺點(diǎn):需要知道每一款掃碼器的型號(hào)以獲取波特率及Android設(shè)備的串口地址。
備注:我的項(xiàng)目在實(shí)現(xiàn)獲取掃碼槍數(shù)據(jù)的過程中并未體現(xiàn)該缺點(diǎn)躯保。

3. 監(jiān)聽掃碼槍事件獲取數(shù)據(jù)

備注:掃碼槍就是 = 鍵盤 + 回車旋膳,即外接接盤。所以建個(gè)txt文本文檔或者doc隨便途事,打開验懊,然后連接掃碼槍擅羞,開始掃描,掃碼結(jié)果就會(huì)自動(dòng)填入你的文檔义图。

  • 方案一:監(jiān)聽鍵盤的keydown事件(監(jiān)聽js鍵盤事件)
    分析:uniapp無document對(duì)象祟滴,無法獲取keydown事件。無鍵盤事件歌溉,不支持鍵盤修飾符垄懂。
  • 方案二:通過native.js調(diào)用安卓原生類庫,通過廣播方式實(shí)現(xiàn)掃碼結(jié)果的接收痛垛。參考1草慧、參考2參考三
    分析:需從廠商那里獲取到android開發(fā)文檔匙头,查看掃碼廣播標(biāo)識(shí)(意圖action)對(duì)應(yīng)的字段漫谷。
var main,receiver,filter;  

① 在過濾器中添加掃碼廣播標(biāo)識(shí)(意圖action)

var IntentFilter = plus.android.importClass('android.content.IntentFilter');  
filter = new IntentFilter();  
filter.addAction("com.se4500.onDecodeComplete");  //監(jiān)聽掃描
//filter.addAction("com.zkc.scancode");//監(jiān)聽掃描  

注意:不同廠商掃碼廣播標(biāo)識(shí)action對(duì)應(yīng)的字段不一樣,這里以com.se4500.onDecodeComplete為例蹂析。
② 注冊(cè)廣播接受者BroadcastReceiver并重寫onReceive()方法

receiver = plus.android.implements('io.dcloud.feature.internal.reflect.BroadcastReceiver',{  
    onReceive : function(context, intent) {  
        plus.android.importClass(intent);  //通過intent實(shí)例引入intent類舔示,方便以后的‘.’操作  
       /*這個(gè)se4500很坑,不同的手機(jī)或pda电抚,這個(gè)值就不一樣惕稻,要具體去查硬件api*/  
        var code = intent.getStringExtra("se4500");  
       // var code = intent.getStringExtra("code");  
        console.log('條碼:',code); 
    }});  

注意:獲取掃碼數(shù)據(jù)時(shí),此處key為se4500僅為示例蝙叛,不同手機(jī)或pda俺祠,這個(gè)值不一樣,具體要去查硬件api借帘。
③ 注冊(cè)監(jiān)聽

main = plus.android.runtimeMainActivity();//獲取activity  
main.registerReceiver(receiver,filter);  //注冊(cè)監(jiān)聽

④ 注銷監(jiān)聽

main.unregisterReceiver(receiver);  //取消監(jiān)聽
  • 方案三:使用 5+ 的api監(jiān)聽鍵盤事件
    分析:H5 和小程序不能監(jiān)聽鍵盤事件蜘渣,但是app端可通過使用 5+ 的api監(jiān)聽鍵盤事件。經(jīng)測(cè)試肺然,app端使用 5+ 的api未能監(jiān)聽到鍵盤事件蔫缸。

這種方案應(yīng)該是最合適的,但是測(cè)試未成功际起,這里僅提供一個(gè)思路拾碌,可能我的實(shí)現(xiàn)方法錯(cuò)了,虛心求教有思路的小伙伴加叁。

<template>
    <view>
        plus監(jiān)聽原生擴(kuò)展事件:掃碼結(jié)果{{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("點(diǎn)擊了返回鍵:" + JSON.stringify(KeyEvent));
            console.log("點(diǎn)擊了返回鍵:" + 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結(jié)束符");
                plus.nativeUI.toast("resultValue:" + _self.resultValue);
                _self.resultValue = "";
            }else if(KeyEvent.keyCode == 10){
                //plus.nativeUI.toast("換行結(jié)束符");
                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>

監(jiān)聽設(shè)備鍵盤事件可參考:監(jiān)聽事件(系統(tǒng)事件+設(shè)備按鍵事件+自定義事件)倦沧。

  • 方案四:參考原生Android外接USB掃碼槍,生成插件在uniapp中使用它匕。
    分析:原生實(shí)現(xiàn)中是通過攔截dispatchKeyEvent(KeyEvent event)方法來自己處理鍵盤的輸入事件。是否能封裝成插件尚在研究中窖认。
  • 方案五:使用 input 輸入框控件來接收
    分析:輸入框可直接接收掃碼槍數(shù)據(jù)
    方案:主要通過使用 input 的 @input 和 @confirm 事件來實(shí)現(xiàn)
    備注:頁面其實(shí)并不需要顯示input控件豫柬,這里只作為接受數(shù)據(jù)的作用告希,所以盡可能在界面中隱藏該控件,從而達(dá)到既不影響用戶體驗(yàn)又能實(shí)現(xiàn)我們的功能
<input v-if="isUseScanGun" class="jk-footer" style="width: 1px;" :value="inputValue" :focus="isFocus" maxlength="-1" 
@input="onInput" @focus="onFocus" @blur="onBlur" @confirm="onConfirm"/>

說明:具體實(shí)現(xiàn)過程中有一些細(xì)節(jié)問題需要處理烧给,詳情見下問題匯總燕偶。

4. 問題匯總

4.1 失焦導(dǎo)致無法獲取掃碼數(shù)據(jù)

說明:輸入框聚焦后掃碼槍才可以把內(nèi)容輸出到輸入框中,失去焦點(diǎn)將導(dǎo)致不能獲取到掃碼數(shù)據(jù)础嫡,或者說是需手動(dòng)聚焦后才能獲取到掃碼數(shù)據(jù)指么。
(1) 失焦描述1:雖然設(shè)置了輸入框的聚焦屬性,掃碼一次后就會(huì)失去焦點(diǎn)
解決方案:輸入框失焦時(shí)重新在 @blur 事件中重新設(shè)置焦點(diǎn)
注意:此時(shí)需在輸入事件中設(shè)置焦點(diǎn)屬性為false榴鼎,之后 @blur 事件會(huì)自動(dòng)被調(diào)用伯诬,從而獲取到焦點(diǎn)。

onInput:function(e){
    console.log("鍵盤輸入:" + e.detail.value);
    _self.isFocus = false;          
},
onFocus:function(){
    console.log("輸入框聚焦");                   
},
onBlur:function(){
    console.log("輸入框失去焦點(diǎn)");
    _self.isFocus = true;
},

(2) 失焦描述2:點(diǎn)擊界面上除輸入框的其他位置巫财,也會(huì)導(dǎo)致輸入框失去焦點(diǎn)
解決方案:給整個(gè)頁面的根節(jié)點(diǎn)設(shè)置點(diǎn)擊事件盗似,重新獲取焦點(diǎn)。
注意:此時(shí)需設(shè)置焦點(diǎn)屬性為false平项,之后 @blur 事件會(huì)自動(dòng)被調(diào)用赫舒,從而獲取到焦點(diǎn)。

<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 + "");
},

備注:經(jīng)驗(yàn)證闽瓢,還需在manifest.json配置文件關(guān)閉沉浸式接癌,否則無法重新獲取焦點(diǎn)(剛好項(xiàng)目之前因需去掉原生導(dǎo)航故關(guān)閉了沉浸式,所以開始的沒發(fā)現(xiàn)需關(guān)閉沉浸式才能重新聚焦的問題)扣讼。原因未知扔涧,望知道的小伙伴告知一下。

/* 5+App特有相關(guān) */
    "app-plus": {
        "statusbar" : {
            "immersed" : false //關(guān)閉沉浸式:解決去掉原生導(dǎo)航后届谈,主內(nèi)容頂?shù)綘顟B(tài)欄的問題;掃碼槍-輸入框聚焦問題(原因未知)
        },
    },

拓展:窗體默認(rèn)是沉浸式(即全屏可寫內(nèi)容)枯夜。若不啟用原生導(dǎo)航,手機(jī)頂部狀態(tài)欄區(qū)域會(huì)被頁面內(nèi)容覆蓋艰山;而系統(tǒng)導(dǎo)航欄會(huì)自動(dòng)處理狀態(tài)欄高度占位問題湖雹,不會(huì)出現(xiàn)手機(jī)頂部狀態(tài)欄區(qū)域被頁面內(nèi)容覆蓋的問題。參考自定義導(dǎo)航欄使用注意曙搬。

4.2 聚集導(dǎo)致屏幕彈出軟鍵盤問題

描述:連接掃碼槍后摔吏,每次聚焦操作都會(huì)引起頁面彈出軟鍵盤
嘗試:使用官網(wǎng)的隱藏軟鍵盤api并不能完全禁用軟鍵盤

onFocus:function(){
    console.log("輸入框聚焦");
    // 并不能完全禁用軟鍵盤
    setTimeout(function(){
        uni.hideKeyboard();//隱藏軟鍵盤:隱藏已經(jīng)顯示的軟鍵盤,如果軟鍵盤沒有顯示則不做任何操作
        // plus.key.hideSoftKeybord();//隱藏軟鍵盤:隱藏已經(jīng)顯示的軟鍵盤纵装,如果軟鍵盤沒有顯示則不做任何操作
    },250);                     
},

分析:系統(tǒng)設(shè)置中征讲,連接到實(shí)體鍵盤時(shí),虛擬鍵盤默認(rèn)在屏幕上保持顯示狀態(tài)
解決方案:設(shè)置當(dāng)連接到實(shí)體鍵盤時(shí)橡娄,關(guān)閉虛擬鍵盤(無實(shí)體鍵盤時(shí)才會(huì)彈出軟鍵盤)
步驟:設(shè)置 -> 語言和輸入法 -> 實(shí)體鍵盤 -> 關(guān)閉顯示虛擬鍵盤

關(guān)閉軟鍵盤.png

說明:這種系統(tǒng)設(shè)置的方案诗箍,僅能解決在外接設(shè)備的情況下禁用軟鍵盤,但是在沒有外接設(shè)備的情況下挽唉,輸入框聚焦還是會(huì)彈出軟鍵盤滤祖,用戶體驗(yàn)不好筷狼。
備注:已找到解決軟鍵盤彈出問題的辦法,并替代上面的系統(tǒng)設(shè)置的方案匠童。

4.3 輸入法默認(rèn)為中文導(dǎo)致掃碼數(shù)據(jù)亂碼問題

說明:系統(tǒng)默認(rèn)輸入法是谷歌拼音輸入法(中文輸入法)埂材,導(dǎo)致掃碼掃出來中文,掃碼數(shù)據(jù)不對(duì)
解決方案:切換輸入法為英文輸入法汤求。
步驟:設(shè)置 -> 語言和輸入法 -> 虛擬鍵盤 -> 管理鍵盤 -> 打開Android鍵盤(英文輸入法)

切換為英文輸入法.png

注意:雖然系統(tǒng)設(shè)置為英文輸入法俏险,但是若在登錄輸入時(shí)(或其他情況的輸入)軟鍵盤需要切換為中文進(jìn)行手動(dòng)輸入,仍會(huì)導(dǎo)致之后的掃碼亂碼扬绪。解決辦法就是輸入后軟鍵盤再切換為英文竖独。
軟鍵盤輸入法.png

4.4 字符截取問題

說明:每次掃碼數(shù)據(jù)都會(huì)拼接到輸入框中(輸入框默認(rèn)最大輸入長(zhǎng)度maxlength為140),但是我們只需要每次的掃碼數(shù)據(jù)勒奇。
解決方案1(雙向綁定未成功):使用雙向綁定预鬓,并監(jiān)聽每次掃碼的完成事件 @confirm,獲取當(dāng)次掃碼數(shù)據(jù)后清空輸入框數(shù)據(jù)赊颠。
分析:在輸入完成事件中清空輸入框?qū)?dǎo)致下次掃碼獲取到錯(cuò)誤數(shù)據(jù)格二,可能和輸入框的輸入事件@input 是一個(gè)字符一個(gè)字符讀取有關(guān)。
解決方案2(掃碼位數(shù)有局限性):設(shè)置不限制輸入框的最大長(zhǎng)度(maxlength = -1)竣蹦,在輸入完成事件中截取最后約定的位數(shù)作為掃碼結(jié)果顶猜。
分析:所要掃的有效二維碼位數(shù)已固定。

onConfirm:function(e){
    console.log("點(diǎn)擊完成按鈕");
    var str = e.detail.value;
    var result = str.substring(str.length-13);//截取后13位
    uni.showToast({
        title: result
     });    
},

解決方案3(成功截取每次掃碼結(jié)果):通過當(dāng)前掃碼輸入框字符串減去上次掃碼輸入框字符串痘括,獲取到每次掃碼結(jié)果

data() {
    return {
        lastInputValue:"",
    }
},
methods: {
    onConfirm:function(e){
        console.log("點(diǎn)擊完成按鈕");
        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("掃碼結(jié)果:" + newValue);
        uni.showToast({
            title: newValue
        });
            
    },          
},

4.5 應(yīng)用重啟問題

關(guān)注帖子:在APP上接入U(xiǎn)SB掃描槍到導(dǎo)致重啟 (UNI-APP)
描述: 當(dāng)應(yīng)用打開時(shí)长窄,插拔鍵盤或掃碼槍會(huì)導(dǎo)致應(yīng)用重啟,連接掃碼槍時(shí)掃碼槍恢復(fù)出廠設(shè)置也會(huì)導(dǎo)致應(yīng)用重啟
分析:可能是檢測(cè)到鍵盤類型改變引起的纲菌,類似android中屏幕旋轉(zhuǎn)導(dǎo)致activity銷毀又重建
解決方案:先接線挠日,后打開應(yīng)用
注意:接線時(shí),若轉(zhuǎn)接頭和平板連接后再連接掃碼槍翰舌,無法給掃碼槍供電淹遵;正確的接線順序?yàn)檎痃裕D(zhuǎn)接頭和掃碼槍連接后再連接平板该抒。
備注:該方案僅能規(guī)避連接掃碼槍時(shí)應(yīng)用重啟問題窿祥,尚未找到解決斷開掃碼槍時(shí)應(yīng)用重啟問題的方案。

插拔重啟.png

更新HbuilderX版本后問題解決庇麦,經(jīng)查證2.4.1.20191114版本修復(fù)了該問題计技。

2.4.1.20191114版本解決插拔重啟問題.png

拓展:熱插拔
備注:完整代碼示例

<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();//隱藏軟鍵盤:隱藏已經(jīng)顯示的軟鍵盤,如果軟鍵盤沒有顯示則不做任何操作
                // plus.key.hideSoftKeybord();//隱藏軟鍵盤:隱藏已經(jīng)顯示的軟鍵盤山橄,如果軟鍵盤沒有顯示則不做任何操作
            },250); 
            
        },
        blur:function(){
            console.log("輸入框失去焦點(diǎn):" + _self.isFocus);
            _self.isFocus = true;
        },
        confirm:function(e){
            console.log("點(diǎn)擊完成按鈕");
            //(1)雙向綁定來獲取掃碼結(jié)果:未成功
            /* var ticketNo = _self.inputValue;
            _self.inputValue = "";
            uni.showModal({
                title: ticketNo,
                content: _self.inputValue + "h"
            }); */
            
            //(2)截取掃碼結(jié)果:掃碼位數(shù)固定垮媒,有局限性
            /* var str = e.detail.value;
            var result = str.substring(str.length-13);//截取后13位
            console.log("掃碼結(jié)果:" + newValue);
            uni.showToast({
                title: result
            }); */
            
            //(3)截取每次掃碼結(jié)果:成功
            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("掃碼結(jié)果:" + newValue);
            uni.showToast({
                title: newValue
            });
            
            
        },
    },
    onLoad:function(){
        _self = this;
    }
}
</script>

<style>

</style>

5. 使用插件—外接鍵盤掃描槍監(jiān)聽獲取輸入內(nèi)容

(1) 在uniapp插件市場(chǎng)購買插件并綁定項(xiàng)目
(2) 在HBuilderX里找到項(xiàng)目,在manifest的app原生插件配置中勾選模塊


插件配置.png

(3) 在代碼中引用插件并調(diào)用插件功能

<template>
    <view>

        <view class="c-hint margin-l-r" style="margin-top: 10rpx;margin-bottom: 50rpx;color: #ff0000;font-size: 24rpx;">Tips:返回結(jié)果在頁尾打印展示。先點(diǎn)擊設(shè)置監(jiān)聽涣澡,按下數(shù)組鍵
            1 或者字母鍵 a贱呐,頁面會(huì)打印返回?cái)?shù)據(jù)丧诺,供查看數(shù)據(jù)結(jié)構(gòu)入桂。輸入完成,點(diǎn)擊 Enter 鍵驳阎,頁面會(huì)顯示拼接結(jié)果抗愁。</view>

        <view class="c-hint margin-l-r" style="margin-top: 30rpx;">tag 字段,不用理會(huì)呵晚,固定 1 就好</view>
        <input v-model="tag" class="margin-l-r" placeholder="請(qǐng)輸入" />

        <view class="button-sp-area">
            <button type="primary" plain="true" @click="onBtn1()">設(shè)置監(jiān)聽</button>
        </view>

        <view class="button-sp-area">
            <button type="primary" plain="true" @click="onBtn2()">取消某個(gè)監(jiān)聽</button>
        </view>

        <view class="button-sp-area">
            <button type="primary" plain="true" @click="onBtn3()">獲取所有監(jiān)聽的tag</button>
        </view>

        <view class="button-sp-area">
            <button type="primary" plain="true" @click="onBtn4()">取消所有監(jiān)聽</button>
        </view>

        <view class="c-hint margin-l-r text-wrapper" style="margin-top: 30rpx;width: 700rpx;word-break:break-all;">以下打印監(jiān)聽內(nèi)容蜘腌。</view>

        <view class="c-hint margin-l-r text-wrapper" style="margin-top: 30rpx;width: 700rpx;word-break:break-all;">拼接結(jié)果:{{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", //不必理會(huì),固定 1 就好
                resultStrFinal: ""
            }
        },
        onLoad() {
            let that = this;
            // #ifdef APP-PLUS
            //引用插件
            longyoungKeyEventListen = uni.requireNativePlugin('longyoung-KeyEventListen');

            // //設(shè)置監(jiān)聽饵隙,可設(shè)置多個(gè)撮珠,回調(diào)按 tag 區(qū)分哪個(gè)監(jiān)聽返回。
            // 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是返回?cái)?shù)據(jù)標(biāo)識(shí)金矛,返回的數(shù)據(jù)在此獲取

            //          //頁面只顯示1芯急,供查看數(shù)據(jù)結(jié)構(gòu)
            //          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) {
                //取消所有監(jiān)聽
                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;
                //設(shè)置監(jiān)聽,可設(shè)置多個(gè)驶俊,回調(diào)按 tag 區(qū)分哪個(gè)監(jiān)聽返回娶耍。
                longyoungKeyEventListen.setOnKeyEventListenerLy({
                    tag: that.tag //不必理會(huì),固定 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是返回?cái)?shù)據(jù)標(biāo)識(shí)饼酿,返回的數(shù)據(jù)在此獲取

                            //頁面只顯示1和a榕酒,供查看數(shù)據(jù)結(jié)構(gòu)
                            if (result.keyCode == 'KEYCODE_1' || result.keyCode == 'KEYCODE_A') {
                                that.resultStr += '\n' + JSON.stringify(result) + '\n';
                            }

                            that.handleData(result);
                        }
                    }
                });
            },
            onBtn2() {
                let that = this;
                //取消某個(gè) tag 監(jiān)聽
                longyoungKeyEventListen.disableOnKeyEventListenerLy({
                    tag: that.tag //不必理會(huì),固定 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;
                //獲取所有監(jiān)聽的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;
                //取消所有監(jiān)聽
                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') { //掃碼結(jié)束
                            that.resultStrFinal = allKeyCodeTemp; //最終拼接的字符串賦值
                            allKeyCodeTemp = '';
                            preKeyCode = '';
                        } else if (keyCode == 'KEYCODE_SHIFT_LEFT' || keyCode == 'KEYCODE_SHIFT_RIGHT') { //轉(zhuǎn)換鍵
                            preKeyCode = 'KEYCODE_SHIFT_RIGHT';
                        } else {
                            if (preKeyCode == 'KEYCODE_SHIFT_RIGHT') { //轉(zhuǎn)換鍵故俐,拿大寫
                                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) 重新制作自定義基座想鹰,然后選擇自定義基座運(yùn)行調(diào)試
(5) 開發(fā)完畢后正式云打包

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市药版,隨后出現(xiàn)的幾起案子辑舷,更是在濱河造成了極大的恐慌,老刑警劉巖刚陡,帶你破解...
    沈念sama閱讀 218,525評(píng)論 6 507
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件惩妇,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡筐乳,警方通過查閱死者的電腦和手機(jī)歌殃,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,203評(píng)論 3 395
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來蝙云,“玉大人氓皱,你說我怎么就攤上這事。” “怎么了波材?”我有些...
    開封第一講書人閱讀 164,862評(píng)論 0 354
  • 文/不壞的土叔 我叫張陵股淡,是天一觀的道長(zhǎng)。 經(jīng)常有香客問我廷区,道長(zhǎng)唯灵,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,728評(píng)論 1 294
  • 正文 為了忘掉前任隙轻,我火速辦了婚禮埠帕,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘玖绿。我一直安慰自己敛瓷,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,743評(píng)論 6 392
  • 文/花漫 我一把揭開白布斑匪。 她就那樣靜靜地躺著呐籽,像睡著了一般。 火紅的嫁衣襯著肌膚如雪蚀瘸。 梳的紋絲不亂的頭發(fā)上狡蝶,一...
    開封第一講書人閱讀 51,590評(píng)論 1 305
  • 那天,我揣著相機(jī)與錄音苍姜,去河邊找鬼牢酵。 笑死,一個(gè)胖子當(dāng)著我的面吹牛衙猪,可吹牛的內(nèi)容都是我干的馍乙。 我是一名探鬼主播,決...
    沈念sama閱讀 40,330評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼垫释,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼丝格!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起棵譬,我...
    開封第一講書人閱讀 39,244評(píng)論 0 276
  • 序言:老撾萬榮一對(duì)情侶失蹤显蝌,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后订咸,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體曼尊,經(jīng)...
    沈念sama閱讀 45,693評(píng)論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,885評(píng)論 3 336
  • 正文 我和宋清朗相戀三年脏嚷,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了骆撇。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 40,001評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡父叙,死狀恐怖神郊,靈堂內(nèi)的尸體忽然破棺而出肴裙,到底是詐尸還是另有隱情,我是刑警寧澤涌乳,帶...
    沈念sama閱讀 35,723評(píng)論 5 346
  • 正文 年R本政府宣布蜻懦,位于F島的核電站,受9級(jí)特大地震影響夕晓,放射性物質(zhì)發(fā)生泄漏宛乃。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,343評(píng)論 3 330
  • 文/蒙蒙 一运授、第九天 我趴在偏房一處隱蔽的房頂上張望烤惊。 院中可真熱鬧乔煞,春花似錦吁朦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,919評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至空骚,卻和暖如春纺讲,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背囤屹。 一陣腳步聲響...
    開封第一講書人閱讀 33,042評(píng)論 1 270
  • 我被黑心中介騙來泰國打工熬甚, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人肋坚。 一個(gè)月前我還...
    沈念sama閱讀 48,191評(píng)論 3 370
  • 正文 我出身青樓乡括,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國和親智厌。 傳聞我的和親對(duì)象是個(gè)殘疾皇子诲泌,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,955評(píng)論 2 355

推薦閱讀更多精彩內(nèi)容

  • 前言 公司的設(shè)備以前接入的都是串口的掃碼頭,優(yōu)點(diǎn)是直接通過串口讀取流里面的數(shù)據(jù)就OK了铣鹏,缺點(diǎn)是你需要知道每一款掃碼...
    夕hl月閱讀 22,073評(píng)論 40 50
  • ¥開啟¥ 【iAPP實(shí)現(xiàn)進(jìn)入界面執(zhí)行逐一顯】 〖2017-08-25 15:22:14〗 《//首先開一個(gè)線程敷扫,因...
    小菜c閱讀 6,423評(píng)論 0 17
  • android單屏機(jī),通過掃碼槍掃描二維碼的場(chǎng)景非常多诚卸,掃碼槍的種類也有藍(lán)牙葵第、USB、串口等等 目前USB的掃碼槍...
    我不是耳機(jī)發(fā)燒友閱讀 9,622評(píng)論 4 21
  • ??JavaScript 與 HTML 之間的交互是通過事件實(shí)現(xiàn)的。 ??事件辫愉,就是文檔或?yàn)g覽器窗口中發(fā)生的一些特...
    霜天曉閱讀 3,493評(píng)論 1 11
  • 克制與忍讓 古今歷史波瀾壯闊栅受、風(fēng)起云涌,成大事者數(shù)不勝數(shù),他們都有諸多超乎尋常人的特殊本領(lǐng)屏镊,其中有的是共同擁有依疼,有...
    展翅翱翔飛向藍(lán)天閱讀 951評(píng)論 10 17