安卓開發實現獲取掃碼槍掃碼二維碼、條形碼后的內容


掃碼槍是如何工作的,安卓如何怎么獲取掃碼槍的內容。本文將介紹安卓獲取和處理商米收銀機掃碼槍掃描后的內容。包括:“安卓開發獲取掃碼槍掃描后的內容”、“處理掃碼槍掃描后的內容”、“在Fragment中使用ScanGun類”。

1、安卓開發獲取掃碼槍掃描后的內容。

掃碼槍會將掃描出來的內容轉化為鍵盤事件KeyEvent,所以我們在fragment類中重寫onKeyDownChild方法,就可以捕獲掃碼事件,進而獲取掃碼內容:

public void onKeyDownChild(int keyCode, KeyEvent event) {
    log.info("---------------------------------onKeyDown:    KeyCode:" + keyCode + "------event:" + event + "------------------------------------");
    scanGun.isMaybeScanning(keyCode, event);
}

2、處理掃碼槍掃描后的內容。

SanGun類定義一個isMayBeScanning方法,掃碼槍掃描后觸發鍵盤事件,在鍵盤事件中調用isMayBeScanning方法,進而解析獲取掃碼內容:

查看代碼
package com.bx.erp.helper;

import android.view.KeyEvent;

import org.apache.log4j.Logger;

public class ScanGun {
    private Logger log = Logger.getLogger(this.getClass());
    /**
     * 默認按鍵之間時間間隔
     */
    public final static int MAX_KEYS_INTERVAL_DEFAULT = 200;

    private long currentTime = 0;
    private boolean isKeySHIFT = false;
    private StringBuilder stringBuilder = new StringBuilder();
    private ScanGunCallBack callBack = null;

    private static int maxKeysInterval = MAX_KEYS_INTERVAL_DEFAULT;

    /**
     * 設置按鍵事件的最大時間間隔(部分掃描槍稍大,建議范圍20--100)
     *
     * @param interval 時間間隔
     */
    public static void setMaxKeysInterval(int interval) {
        maxKeysInterval = interval;
    }

    public ScanGun(ScanGunCallBack callBack) {
        this.callBack = callBack;
    }

    public ScanGun() {}

    public boolean isMaybeScanning(int keyCode, KeyEvent event) {
        log.info("isMaybeScanning--");

        log.info("event.getFlags:" + event.getFlags());
        if (event.getFlags() != 0x8 && event.getFlags() != 0x6) {
            return false;
        }
        if (currentTime == 0) {
            if (stringBuilder.length() > 0) {
                stringBuilder = stringBuilder.delete(0, stringBuilder.length());
            }
            currentTime = System.currentTimeMillis();
        } else {
            if ((System.currentTimeMillis() - currentTime) > maxKeysInterval) {
                if (stringBuilder.length() > 0) {
                    stringBuilder = stringBuilder.delete(0,
                            stringBuilder.length());
                }
            }
            currentTime = System.currentTimeMillis();
        }
        // Shift
        if (keyCode == KeyEvent.KEYCODE_SHIFT_RIGHT || keyCode == KeyEvent.KEYCODE_SHIFT_LEFT) {
            if (event.getAction() == KeyEvent.ACTION_DOWN) {
                //按着shift鍵,表示大寫
                isKeySHIFT = true;
            } else {
                //松開shift鍵,表示小寫
                isKeySHIFT = false;
            }
        }
        // Enter
        if (keyCode == KeyEvent.KEYCODE_ENTER) {
            isKeySHIFT = false;
            currentTime = 0;
            if (callBack != null) {
                log.info("stringBuilder:" + stringBuilder);
                callBack.onScanFinish(stringBuilder.toString());
            }
            return true;
        }
        if (keyCode >= KeyEvent.KEYCODE_0 && keyCode <= KeyEvent.KEYCODE_9) {
            // 數字鍵(鍵盤上方橫條數字,需要考慮Shift)
            handleTopNumKeys(keyCode);

        } else if (keyCode >= 29 && keyCode <= 54) {
            // 字母鍵(需要考慮Shift)ww
            checkShift((char) (keyCode + 68), (char) (keyCode + 36));
        } else if (keyCode >= 144 && keyCode <= 158) {
            // 數字鍵盤區
            handleNumPadKeys(keyCode);
            log.info("數字:" + stringBuilder);
        } else {
            // 鍵盤主鍵區其他雙字符鍵位
            switch (keyCode) {
                case KeyEvent.KEYCODE_GRAVE: {
                    checkShift(ASCII.CHAR_SIGN_BACKTICK, ASCII.CHAR_SIGN_TILDE);
                    break;
                }
                case KeyEvent.KEYCODE_MINUS: {
                    checkShift(ASCII.CHAR_SIGN_MINUS, ASCII.CHAR_SIGN_UNDERSCORE);
                    break;
                }
                case KeyEvent.KEYCODE_EQUALS: {
                    checkShift(ASCII.CHAR_SIGN_EQUALS, ASCII.CHAR_SIGN_PLUS);
                    break;
                }

                case KeyEvent.KEYCODE_LEFT_BRACKET: {
                    checkShift(ASCII.CHAR_SIGN_BRACKET_LEFT,
                            ASCII.CHAR_SIGN_BRACE_LEFT);
                    break;
                }
                case KeyEvent.KEYCODE_RIGHT_BRACKET: {
                    checkShift(ASCII.CHAR_SIGN_BRACKET_RIGHT,
                            ASCII.CHAR_SIGN_BRACE_RIGHT);
                    break;
                }
                case KeyEvent.KEYCODE_BACKSLASH: {
                    checkShift(ASCII.CHAR_SIGN_BACKSLASH, ASCII.CHAR_SIGN_BAR);
                    break;
                }
                case KeyEvent.KEYCODE_SEMICOLON: {
                    checkShift(ASCII.CHAR_SIGN_SEMICOLON, ASCII.CHAR_SIGN_COLON);
                    break;
                }
                case KeyEvent.KEYCODE_APOSTROPHE: {
                    checkShift(ASCII.CHAR_SIGN_QUOTE, ASCII.CHAR_SIGN_DOUBLE_QUOTE);
                    break;
                }
                case KeyEvent.KEYCODE_COMMA: {
                    checkShift(ASCII.CHAR_SIGN_COMMA, ASCII.CHAR_SIGN_LESS);
                    break;
                }
                case KeyEvent.KEYCODE_PERIOD: {
                    checkShift(ASCII.CHAR_SIGN_PERIOD, ASCII.CHAR_SIGN_GREATER);
                    break;
                }
                case KeyEvent.KEYCODE_SLASH: {
                    checkShift(ASCII.CHAR_SIGN_SLASH, ASCII.CHAR_SIGN_QUESTION);
                    break;
                }
                // 其他單字符鍵位
                case KeyEvent.KEYCODE_SPACE: {
                    stringBuilder.append(ASCII.CHAR_SIGN_SPACE);
                    log.info("Other StringBuilder:" + stringBuilder);
                    break;
                }
                default: {
                    return false;
                }
            }
            return true;
        }

        return true;

    }

    /**
     * 判斷是否同時按下Shift鍵
     *
     * @param ascallNoShift
     * @param ascallOnShift
     */
    private void checkShift(char ascallNoShift, char ascallOnShift) {
        if (isKeySHIFT) {
            stringBuilder.append(ascallOnShift);
            isKeySHIFT = false;
        } else {
            stringBuilder.append(ascallNoShift);
        }
    }

    /**
     * 數字鍵盤區按鍵
     *
     * @param keyCode
     */
    public void handleNumPadKeys(int keyCode) {
        if (keyCode <= 153) {
            stringBuilder.append((char) (keyCode - 96));
        } else if (keyCode == KeyEvent.KEYCODE_NUMPAD_DIVIDE) {
            stringBuilder.append(ASCII.CHAR_SIGN_SLASH);
        } else if (keyCode == KeyEvent.KEYCODE_NUMPAD_MULTIPLY) {
            stringBuilder.append(ASCII.CHAR_SIGN_STAR);
        } else if (keyCode == KeyEvent.KEYCODE_NUMPAD_SUBTRACT) {
            stringBuilder.append(ASCII.CHAR_SIGN_MINUS);
        } else if (keyCode == KeyEvent.KEYCODE_NUMPAD_ADD) {
            stringBuilder.append(ASCII.CHAR_SIGN_PLUS);
        } else if (keyCode == KeyEvent.KEYCODE_NUMPAD_DOT) {
            stringBuilder.append(ASCII.CHAR_SIGN_PERIOD);
        }
    }

    /**
     * 鍵盤上方數字鍵
     *
     * @param keyCode
     */
    private void handleTopNumKeys(int keyCode) {
        if (keyCode < 7 || keyCode > 16) {
            return;
        }
        switch (keyCode) {
            case KeyEvent.KEYCODE_0:
                checkShift(ASCII.CHAR_NUM_0, ASCII.CHAR_SIGN_PAREN_RIGHT);
                break;
            case KeyEvent.KEYCODE_1:
                checkShift(ASCII.CHAR_NUM_1, ASCII.CHAR_SIGN_EXCLAM);
                break;
            case KeyEvent.KEYCODE_2:
                checkShift(ASCII.CHAR_NUM_2, ASCII.CHAR_SIGN_AT);
                break;
            case KeyEvent.KEYCODE_3:
                checkShift(ASCII.CHAR_NUM_3, ASCII.CHAR_SIGN_HASH);
                break;
            case KeyEvent.KEYCODE_4:
                checkShift(ASCII.CHAR_NUM_4, ASCII.CHAR_SIGN_DOLLAR);
                break;
            case KeyEvent.KEYCODE_5:
                checkShift(ASCII.CHAR_NUM_5, ASCII.CHAR_SIGN_PERCENT);
                break;
            case KeyEvent.KEYCODE_6:
                checkShift(ASCII.CHAR_NUM_6, ASCII.CHAR_SIGN_CARET);
                break;
            case KeyEvent.KEYCODE_7:
                checkShift(ASCII.CHAR_NUM_7, ASCII.CHAR_SIGN_AMPERSAND);
                break;
            case KeyEvent.KEYCODE_8:
                checkShift(ASCII.CHAR_NUM_8, ASCII.CHAR_SIGN_STAR);
                break;
            case KeyEvent.KEYCODE_9:
                checkShift(ASCII.CHAR_NUM_9, ASCII.CHAR_SIGN_PAREN_LEFT);
                break;
            default:
                break;
        }
    }

    public interface ScanGunCallBack {
        public void onScanFinish(String data);
    }
}

3、在Fragment中使用ScanGun類。

ScanGun類定義了一個內部類接口,data就是掃描完成后的內容:

public interface ScanGunCallBack {
    public void onScanFinish(String data);
}

掃碼完成后,調用該接口的onScanFinish方法:

// Enter
if (keyCode == KeyEvent.KEYCODE_ENTER) {
    isKeySHIFT = false;
    currentTime = 0;
    if (callBack != null) {
        log.info("stringBuilder:" + stringBuilder);
        callBack.onScanFinish(stringBuilder.toString());
    }
    return true;
}

所以在Fragment獲取掃描結果,需要創建Scan的實例,並且實現這個onScanFinish方法:

/* 初始化掃碼槍 */
private void initScanGun() {
    // 設置key事件最大間隔,默認20ms,部分低端掃碼槍效率低
    ScanGun.setMaxKeysInterval(50);
    scanGun = new ScanGun(new ScanGun.ScanGunCallBack() {
        @RequiresApi(api = Build.VERSION_CODES.JELLY_BEAN_MR1)
        @Override
        public void onScanFinish(String scanResult) {
            if (payment.getVisibility() != View.GONE) { // 支付頁面沒關閉
                loadingDailog = createWaitingUI(loadingDailog, LOADING_MSG_Paying);
                // 判斷優惠券是否可用
                if (!validateCouponCodeAvailable()) {
                    return;
                }
                if (choosePaymentType.getCheckedRadioButtonId() == wechatPay.getId()) {
				……

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM