美文网首页APP & program
Android USB扫码器/门禁/外接键盘等区分识别

Android USB扫码器/门禁/外接键盘等区分识别

作者: 孟工 | 来源:发表于2022-10-25 10:03 被阅读0次

    简介:市面上很多外接USB录入设备为了节约成本,都是模拟Android键盘按下弹起,这样就不需要开发jar而且跨平台。


    先写个工具类 ,将每次模拟键盘内容拼接,因为我实际开发不会出现多设备同时工作,所以没有区分设备,如果有多设备同时录入,把StringBuilder换成Map<Integer,StringBuilder>就可以了,Key是录入设备的ProductId,也就是代码中 mListener.onScanValue(mResult.toString(), event.getDevice().getProductId()); 

    public class ScanKeyManager {

    private StringBuildermResult;

        public OnScanValueListenermListener;

        private boolean mCaps;

        public interface OnScanValueListener {

    void onScanValue(String value, int type);

        }

    public ScanKeyManager(OnScanValueListener listener) {

    this.mListener = listener;

            this.mResult =new StringBuilder();

        }

    /**

    * 扫码设备事件解析

    */

        public void analysisKeyEvent(KeyEvent event) {

    int keyCode = event.getKeyCode();

            checkLetterStatus(event);

            if (event.getAction() == KeyEvent.ACTION_DOWN) {

    char aChar = getInputCode(mCaps, event.getKeyCode());

                if (aChar !=0) {

    mResult.append(aChar);

                }

    //如果是回车,扫码/门禁/键盘认为录入结束

                if (keyCode == KeyEvent.KEYCODE_ENTER) {

    if (mListener !=null) {

    mListener.onScanValue(mResult.toString(), event.getDevice().getProductId());

                    }

    mResult.delete(0, mResult.length());

                }

    }

    }

    /**

    * 判断大小写

    */

        private void checkLetterStatus(KeyEvent event) {

    int keyCode = event.getKeyCode();

            if (keyCode == KeyEvent.KEYCODE_SHIFT_RIGHT || keyCode == KeyEvent.KEYCODE_SHIFT_LEFT) {

    mCaps = event.getAction() == KeyEvent.ACTION_DOWN;

            }

    }

    /**

    * 将keyCode转为char

    *

        * @param caps    是不是大写

        * @param keyCode 按键

        * @return 按键对应的char

    */

        private char getInputCode(boolean caps, int keyCode) {

    if (keyCode >= KeyEvent.KEYCODE_A && keyCode <= KeyEvent.KEYCODE_Z) {

    return (char) ((caps ?'A' :'a') + keyCode - KeyEvent.KEYCODE_A);

            }else {

    return keyValue(caps, keyCode);

            }

    }

    /**

    * 按键对应的char表

    */

        private char keyValue(boolean caps, int keyCode) {

    switch (keyCode) {

    case KeyEvent.KEYCODE_0:

    return caps ?')' :'0';

                case KeyEvent.KEYCODE_1:

    return caps ?'!' :'1';

                case KeyEvent.KEYCODE_2:

    return caps ?'@' :'2';

                case KeyEvent.KEYCODE_3:

    return caps ?'#' :'3';

                case KeyEvent.KEYCODE_4:

    return caps ?'$' :'4';

                case KeyEvent.KEYCODE_5:

    return caps ?'%' :'5';

                case KeyEvent.KEYCODE_6:

    return caps ?'^' :'6';

                case KeyEvent.KEYCODE_7:

    return caps ?'&' :'7';

                case KeyEvent.KEYCODE_8:

    return caps ?'*' :'8';

                case KeyEvent.KEYCODE_9:

    return caps ?'(' :'9';

                case KeyEvent.KEYCODE_NUMPAD_SUBTRACT:

    case KeyEvent.KEYCODE_MINUS:

    return '-';

                case KeyEvent.KEYCODE_EQUALS:

    return '=';

                case KeyEvent.KEYCODE_NUMPAD_ADD:

    return '+';

                case KeyEvent.KEYCODE_GRAVE:

    return caps ?'~' :'`';

                case KeyEvent.KEYCODE_BACKSLASH:

    return caps ?'|' :'\\';

                case KeyEvent.KEYCODE_LEFT_BRACKET:

    return caps ?'{' :'[';

                case KeyEvent.KEYCODE_RIGHT_BRACKET:

    return caps ?'}' :']';

                case KeyEvent.KEYCODE_SEMICOLON:

    return caps ?':' :';';

                case KeyEvent.KEYCODE_APOSTROPHE:

    return caps ?'"' :'\'';

                case KeyEvent.KEYCODE_COMMA:

    return caps ?'<' :',';

                case KeyEvent.KEYCODE_PERIOD:

    return caps ?'>' :'.';

                case KeyEvent.KEYCODE_SLASH:

    return caps ?'?' :'/';

                default:

    return 0;

            }

    }

    }


            先要找出所有USB设备的地址或ProductId,如果公司设备的ProductId固定那就没必要用地址判断,我们需求是设备不一定是同一家公司,ProductId也肯定不一样,所以只能动态配置每个设备的地址,最后通过配置的地址和USB遍历的地址拿出ProductId,最后跟录入设备对比就知道是哪台设备了。

            一开始不知道设备链接地址,就重写第三步,自己挨个试一遍,拿出ProductId再根据第一步ProductId对比拿出USB的 DeviceName也就是USB地址(设备固定就跳过这一步)。

    1.识别USB设备:根据配置的地址对比拿到ProductId(外接设备的产品ID)

    private int usbCardId, usbScanId;

    /**

    * 获取所有usb设备

    */

    private void getAllUsb() {

    Map usbDeviceMap = ((UsbManager) getSystemService(Context.USB_SERVICE)).getDeviceList();

        if (usbDeviceMap !=null && usbDeviceMap.size() >0) {

    for (UsbDevice u : usbDeviceMap.values()) {

    //门禁卡的usb地址

    if (u.getDeviceName().equals(BaseActivity.deviceConfig.getPathIdCar())) {

    usbCardId = u.getProductId();

                }else if (u.getDeviceName().equals(BaseActivity.deviceConfig.getPathScan())) {

    //扫码器的usb地址

    usbScanId = u.getProductId();

                }

    Log.i("asoduao",

                        "usbCardId" +usbCardId

                                +",usbScanId:" +usbScanId

                                +",usbCardPath:" + BaseActivity.deviceConfig.getPathIdCar()

    +",usbScanPath:" + BaseActivity.deviceConfig.getPathScan()

    +",Name:" + u.getDeviceName()

    +",ProductId:" + u.getProductId());

            }

    }

    }

    2.创建工具类:根据ProductId做对应的事情

    //拦截扫码器回调,获取扫码内容

    scanKeyManager =new ScanKeyManager((value, type) -> {

    if (type ==usbCardId) {

    //门禁结果

    getUser(value);

        }else if (type ==usbScanId) {

    //扫码器结果

    getScanResult(value);

        }else {

    if (userInfo ==null) {

    //其他操作

    }

    });

    3.重写:如果遇到安卓虚拟键盘录入数字无效,就将下边注释部分放开,经测试我这台设备自身虚拟键盘录入不会走dispatchKeyEvent这个方法,其它安卓系统可能会走而且ProductId是0或者-1。

    @SuppressLint("RestrictedApi")

    @Override

        public boolean dispatchKeyEvent(KeyEvent event) {

    InputDevice u = event.getDevice();

    Log.i("UsbDeviceTAG",

            "Name:" + u.getName()

    +",id:" + u.getId()

    +",ProductId:" + u.getProductId()

    +",Descriptor:" + u.getDescriptor()

    +",ControllerNumber:" + u.getControllerNumber()

    +",Sources:" + u.getSources()

    +",KeyboardType:" + u.getKeyboardType());

    if (event.getDeviceId() == -1)return super.dispatchKeyEvent(event);

            if (event.getKeyCode() != KeyEvent.KEYCODE_BACK) {

    scanKeyManager.analysisKeyEvent(event);

    //            return true;//虚拟键盘录入数字无效放开

            }

    //        return super.dispatchKeyEvent(event);//虚拟键盘录入数字无效放开

            return true;//虚拟键盘录入数字无效注释

        }

    相关文章

      网友评论

        本文标题:Android USB扫码器/门禁/外接键盘等区分识别

        本文链接:https://www.haomeiwen.com/subject/aurazrtx.html