天天看點

Android 掃碼槍監聽封裝一、參考一、簡述三、解決

一、參考

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行不行,随時随地可以掃描?

怎麼搞啊!!沒思路,蛋疼!!廣大碼友,有推薦的解決方案可以貼出來。

 ̄へ ̄

繼續閱讀