Andoid扫码枪监听

Android中的扫码枪被当成外接键盘,没有操作扫码枪的SDK。
监听思路:
1.通过监听Activity的onKeyDown方法实现。
2.编写一个1px的EditText实现

方法1的缺陷:
如果中途切换页面进行了其他的EditText编辑,返回的时候会导致输入法冲突导致onKeyDown没有执行

IInputConnectionWrapper: sendKeyEvent os inactive InputConnection

方法2的缺陷:
会引发软键盘弹出来。但是这个问题可以解决。

方法2相关代码:

package com.ztsh.cashier.widget

import android.app.Activity
import android.content.Context
import android.content.ContextWrapper
import android.util.AttributeSet
import android.view.KeyEvent
import android.view.LayoutInflater
import android.view.View
import android.view.WindowManager
import android.widget.EditText
import android.widget.FrameLayout
import android.widget.TextView
import com.ztsh.cashier.R
import com.ztsh.cashier.util.getValue
import java.lang.Exception
import java.lang.reflect.Method

/**
 * @author Linxz
 * 创建日期:2022年12月27日 23:39
 * version:
 * 描述:
 */
class ScanGunView : FrameLayout{

    private lateinit var activity: Activity
    private lateinit var edtScanCheck : EditText
    var onScanGunInvoke: ((code: String) -> Unit)? = null

    constructor(context: Context) : super(context) {}
    constructor(context: Context, attrs: AttributeSet?) : super(context, attrs) {init()}
    constructor(context: Context, attrs: AttributeSet?, defStyleAttr: Int) : super(context, attrs, defStyleAttr)


    private fun init(){
       LayoutInflater.from(context).inflate(R.layout.view_scan_gun,this)
       edtScanCheck = findViewById(R.id.edtScanCheck)
       activity = getActivity(context)!!
       setActionListener(activity,edtScanCheck)
    }

    /**
     * 1.去除焦点防止软键盘弹出
     * 2.添加回车键监听
     * */
    private fun setActionListener(activity: Activity, etScanCodeInput: EditText) {
        activity.window.setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_HIDDEN)
        try {
            val cls = EditText::class.java
            val setShowSoftInputOnFocus: Method = cls.getMethod("setShowSoftInputOnFocus", Boolean::class.javaPrimitiveType)
            setShowSoftInputOnFocus.isAccessible = true
            setShowSoftInputOnFocus.invoke(etScanCodeInput, false)
        } catch (e: Exception) {
            e.printStackTrace()
        }
        etScanCodeInput.setOnEditorActionListener { v: TextView?, actionId: Int, event: KeyEvent? ->
            onScanGunInvoke?.invoke(edtScanCheck.getValue())
            etScanCodeInput.setText("")
            false
        }
    }

    /**
     * view可见时主动获取焦点
     * */
    override fun onWindowVisibilityChanged(visibility: Int) {
        super.onWindowVisibilityChanged(visibility)
        if (visibility == View.VISIBLE){
            edtScanCheck.requestFocus()
        }
    }

    private fun getActivity(context: Context?): Activity? {
        return if (context is Activity) {
            context
        } else if (context is ContextWrapper) {
            getActivity(context.baseContext)
        }else{
            return null
        }
    }
}

需要监听扫码枪的页面添加如下代码

        //布局
        <com.ztsh.cashier.widget.ScanGunView
            android:layout_width="1px"
            android:layout_height="1px"/>
       //对应Activity或Fragment
       private lateinit var scanGunView: ScanGunView
       ...
       scanGunView.onScanGunInvoke = {
            showToast(it)
        }     

方法1相关代码:

package com.ztsh.cashier.util;

/**
 * @author Linxz
 * 创建日期:2022年12月21日 22:41
 * version:
 * 描述:
 */
import android.os.Handler;
import android.text.TextUtils;
import android.view.KeyEvent;

import java.util.ArrayList;

public class ScannerGunManager {
    private ArrayList<Integer> scannedCodes = new ArrayList<>();

    private final static long MESSAGE_DELAY = 1000;
    private final Handler mHandler;

    private Runnable mScanningFinishRunnable = new Runnable() {
        @Override
        public void run() {
            handleKeyCodes();
        }
    };

    public interface OnScanListener {
        void onResult(String code);
    }

    private OnScanListener listener;

    private volatile static ScannerGunManager sInstance;

    private ScannerGunManager() {
        mHandler = new Handler();
    }

    public static ScannerGunManager getInstance() {
        if (sInstance == null) {
            synchronized (ScannerGunManager.class) {
                if (sInstance == null) {
                    sInstance = new ScannerGunManager();
                }
            }
        }

        return sInstance;
    }

    public String keyCodeToChar(int code, boolean isShift) {
        switch (code) {
            case KeyEvent.KEYCODE_SHIFT_LEFT:
            case KeyEvent.KEYCODE_SHIFT_RIGHT:
            case KeyEvent.KEYCODE_SPACE:
            case KeyEvent.KEYCODE_DPAD_DOWN:
            case KeyEvent.KEYCODE_DPAD_UP:
                return "";

            case KeyEvent.KEYCODE_0:
                return isShift ? ")" : "0";
            case KeyEvent.KEYCODE_1:
                return isShift ? "!" : "1";
            case KeyEvent.KEYCODE_2:
                return isShift ? "@" : "2";
            case KeyEvent.KEYCODE_3:
                return isShift ? "#" : "3";
            case KeyEvent.KEYCODE_4:
                return isShift ? "$" : "4";
            case KeyEvent.KEYCODE_5:
                return isShift ? "%" : "5";
            case KeyEvent.KEYCODE_6:
                return isShift ? "^" : "6";
            case KeyEvent.KEYCODE_7:
                return isShift ? "&" : "7";
            case KeyEvent.KEYCODE_8:
                return isShift ? "*" : "8";
            case KeyEvent.KEYCODE_9:
                return isShift ? "(" : "9";

            case KeyEvent.KEYCODE_A:
                return isShift ? "A" : "a";
            case KeyEvent.KEYCODE_B:
                return isShift ? "B" : "b";
            case KeyEvent.KEYCODE_C:
                return isShift ? "C" : "c";
            case KeyEvent.KEYCODE_D:
                return isShift ? "D" : "d";
            case KeyEvent.KEYCODE_E:
                return isShift ? "E" : "e";
            case KeyEvent.KEYCODE_F:
                return isShift ? "F" : "f";
            case KeyEvent.KEYCODE_G:
                return isShift ? "G" : "g";
            case KeyEvent.KEYCODE_H:
                return isShift ? "H" : "h";
            case KeyEvent.KEYCODE_I:
                return isShift ? "I" : "i";
            case KeyEvent.KEYCODE_J:
                return isShift ? "J" : "j";
            case KeyEvent.KEYCODE_K:
                return isShift ? "K" : "k";
            case KeyEvent.KEYCODE_L:
                return isShift ? "L" : "l";
            case KeyEvent.KEYCODE_M:
                return isShift ? "M" : "m";
            case KeyEvent.KEYCODE_N:
                return isShift ? "N" : "n";
            case KeyEvent.KEYCODE_O:
                return isShift ? "O" : "o";
            case KeyEvent.KEYCODE_P:
                return isShift ? "P" : "p";
            case KeyEvent.KEYCODE_Q:
                return isShift ? "Q" : "q";
            case KeyEvent.KEYCODE_R:
                return isShift ? "R" : "r";
            case KeyEvent.KEYCODE_S:
                return isShift ? "S" : "s";
            case KeyEvent.KEYCODE_T:
                return isShift ? "T" : "t";
            case KeyEvent.KEYCODE_U:
                return isShift ? "U" : "u";
            case KeyEvent.KEYCODE_V:
                return isShift ? "V" : "v";
            case KeyEvent.KEYCODE_W:
                return isShift ? "W" : "w";
            case KeyEvent.KEYCODE_X:
                return isShift ? "X" : "x";
            case KeyEvent.KEYCODE_Y:
                return isShift ? "Y" : "y";
            case KeyEvent.KEYCODE_Z:
                return isShift ? "Z" : "z";

            case KeyEvent.KEYCODE_COMMA:
                return isShift ? "<" : ",";
            case KeyEvent.KEYCODE_PERIOD:
                return isShift ? ">" : ".";
            case KeyEvent.KEYCODE_SLASH:
                return isShift ? "?" : "/";
            case KeyEvent.KEYCODE_BACKSLASH:
                return isShift ? "|" : "\\";
            case KeyEvent.KEYCODE_APOSTROPHE:
                return isShift ? "\"" : "'";
            case KeyEvent.KEYCODE_SEMICOLON:
                return isShift ? ":" : ";";
            case KeyEvent.KEYCODE_LEFT_BRACKET:
                return isShift ? "{" : "[";
            case KeyEvent.KEYCODE_RIGHT_BRACKET:
                return isShift ? "}" : "]";
            case KeyEvent.KEYCODE_GRAVE:
                return isShift ? "~" : "`";
            case KeyEvent.KEYCODE_EQUALS:
                return isShift ? "+" : "=";
            case KeyEvent.KEYCODE_MINUS:
                return isShift ? "_" : "-";
            case KeyEvent.KEYCODE_NUMPAD_SUBTRACT:
                return "-";
            case KeyEvent.KEYCODE_NUMPAD_DIVIDE:
                return "/";
            case KeyEvent.KEYCODE_NUMPAD_MULTIPLY:
                return "*";
            case KeyEvent.KEYCODE_NUMPAD_DOT:
                return ".";
            case KeyEvent.KEYCODE_NUMPAD_ADD:
                return "+";
            case KeyEvent.KEYCODE_NUMPAD_COMMA:
                return ",";
            case KeyEvent.KEYCODE_NUMPAD_EQUALS:
                return "=";
            case KeyEvent.KEYCODE_NUMPAD_LEFT_PAREN:
                return "(";
            case KeyEvent.KEYCODE_NUMPAD_RIGHT_PAREN:
                return ")";
            default:
                return "?";
        }
    }

    private void handleKeyCodes() {
        int count = scannedCodes.size();
        if (count <= 0) {
            return;
        }

        String result = "";

        boolean hasShift = false;
        for (int keyCode : scannedCodes) {
            result += keyCodeToChar(keyCode, hasShift);
            hasShift = (keyCode == KeyEvent.KEYCODE_SHIFT_LEFT);
        }

        if (!TextUtils.isEmpty(result) && listener != null) {
            listener.onResult(result);
        }

        scannedCodes.clear();
    }

    public boolean dispatchKeyEvent(int keyCode, KeyEvent event) {

        if (event.getDeviceId() == -1) {
            return false;
        }

        if (keyCode != KeyEvent.KEYCODE_ENTER) {
            scannedCodes.add(keyCode);

            mHandler.removeCallbacks(mScanningFinishRunnable);
            mHandler.postDelayed(mScanningFinishRunnable, MESSAGE_DELAY);
        } else {
            mHandler.removeCallbacks(mScanningFinishRunnable);

            handleKeyCodes();
        }

        return true;
    }

    public void setScanListener(OnScanListener listener) {
        this.listener = listener;
    }
}


  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值