Android掃碼槍監聽封裝

kandy_aliyq發表於2018-04-19

一、參考

1、常用keycode

一、簡述

1、裝置:掃碼槍其實相當於一個物理輸入裝置,如果軟鍵盤開啟的話能明顯感覺到其內容在輸入
2、問題:
2.1、不能掃出中文來(可能和掃碼槍裝置,配置有關係)
2.2、在游標放到輸入框有軟鍵盤彈出的時候,掃碼出來的字元順序是混亂的(估計和硬體有關係)
2.3、沒有合適的監聽掃碼結果的api

三、解決

為了解決以上問題另加上實現各種業務,故而研究下,有這麼幾點:
1、一定需要一個EditText(充當掃碼槍輸入的容器)
2、有彈出軟鍵盤的,掃碼內容可能會順序不對和亂碼,需要關閉軟鍵盤,內容正確
3、掃碼出來後,一般掃碼槍是有識別符號結束的,一般是鍵盤上的
keyCode == KeyEvent.KEYCODE_ENTER && event.getAction()==KeyEvent.ACTION_DOWN
返回當前掃碼內容
4、最後會有KeyEvent.KEYCODE_DPAD_DOWN,到其他view上去
5、還沒能解決如何設定timeout問題,讓介面提示掃碼失敗  ̄□ ̄||
程式碼
/**
 * Created by wujn on 2018/4/19.
 * Version : v1.0
 * Function: android hardware device - Scanner
 *
 * 掃碼槍:相當於軟鍵盤使用的
 * 1、一定需要一個EditText(充當掃碼槍輸入的容器)
 * 2、有彈出軟鍵盤的,掃碼內容可能會順序不對和亂碼,需要關閉軟鍵盤,內容正確
 * 3、掃碼出來後,一般掃碼槍是有識別符號結束的,一般是鍵盤上的
 *    keyCode == KeyEvent.KEYCODE_ENTER && event.getAction()==KeyEvent.ACTION_DOWN
 *    返回當前掃碼內容
 * 4、最後會有KeyEvent.KEYCODE_DPAD_DOWN,到其他view上去
 * 5、還沒能解決如何設定timeout問題,讓介面提示掃碼失敗
 */
public class Scanner {

    private Activity activity;

    public Scanner(Activity activity){
        this.activity = activity;
    }

    /**
     * 顯示的/隱藏的 EditText 獲得游標,準備掃碼
     * */
    public void scan(final EditText editText){
        //獲得游標
        editText.setFocusable(true);
        editText.setFocusableInTouchMode(true);
        editText.requestFocus();

        //關閉軟鍵盤:防止順序亂碼
        InputMethodManager manager = (InputMethodManager) activity.getSystemService(Activity.INPUT_METHOD_SERVICE);
        //View focus = act.getCurrentFocus();
        manager.hideSoftInputFromWindow(
                //focus == null ? null : focus.getWindowToken(),
                editText == null ? null : editText.getWindowToken(),
                InputMethodManager.HIDE_NOT_ALWAYS);

        //增加軟鍵盤監聽,掃出來內容會自己填充到editText中去的
        editText.setOnKeyListener(new View.OnKeyListener() {
            //on scan finish , last 3 KeyEvent log
            //keycode=66,event.getAction()=0  -> 66=KeyEvent.KEYCODE_ENTER=換行 , 1=KeyEvent.ACTION_DOWN=按下
            //keycode=66,event.getAction()=1  -> 66=KeyEvent.KEYCODE_ENTER=換行 , 1=KeyEvent.ACTION_UP=抬起
            //keycode=20,event.getAction()=0  -> 20=KeyEvent.KEYCODE_DPAD_DOWN=按鍵按下 , 1=KeyEvent.ACTION_DOWN=按下
            @Override
            public boolean onKey(View v, int keyCode, KeyEvent event) {
                //LogUtil.i("keycode="+keyCode+",event.getAction()="+event.getAction());
                if(keyCode == KeyEvent.KEYCODE_ENTER && event.getAction()==KeyEvent.ACTION_DOWN){
                    onScanResultCallBack.OnScanSucccess(editText.getText().toString());//返回結果值,看需要使用了
                    return true;
                }
                return false;
            }
        });


    }


    /**
     * 掃碼槍介面:有timeout設定,當然游標移除的時候關閉計時
     * 成功 返回掃碼結果
     * 失敗 返回錯誤資訊
     * */
    public interface OnScanResultCallBack{
        public void OnScanSucccess(String result);
        public void OnScanFail(String errorMsg);
    }


    private OnScanResultCallBack onScanResultCallBack = new OnScanResultCallBack(){
        @Override
        public void OnScanSucccess(String result) {}
        @Override
        public void OnScanFail(String errorMsg) {}
    };

    /**
     * 子類實現回撥函式
     * */
    public void setOnScanResultCallBack(Scanner.OnScanResultCallBack onScanResultCallBack) {
        if (onScanResultCallBack == null) throw new IllegalArgumentException("empty onScanResultCallBack");
        this.onScanResultCallBack = onScanResultCallBack;
    }

}
對實際業務其實根本不用掃出來的結果,結果是個url,需要訪問後獲得infobean才是最後有效的資訊,這個業務可以用個0dp的EditText當做容器,掃出結果後返回到callback裡,然後後續就xxx。

大家有好的方法做timeout麼,是EditText獲得游標後開始計時?萬一客戶就是不掃描呢?不用EditText行不行,隨時隨地可以掃描?
怎麼搞啊!!沒思路,蛋疼!!廣大碼友,有推薦的解決方案可以貼出來。
 ̄へ ̄


相關文章