Android 扫码枪 读取(外接键盘读取)

1、概述

android 设备外接一个 标准扫码枪,要把扫码枪扫到的内容取出来。界面上放一个EditTextView 直接就把内容显示到EditTextView中了。 然而有些界面上并不能摆EditTextView 。针对没有EditTextView的界面展开下文。扫码枪和外接键盘原理是一样的,类比,也特意拿了个外接键盘一起调研了。

2、扫码枪-输入设备

项目中使用的是标准的扫码枪(实验的是新大陆的NLS-FR40),标准的意思就是它都不给开发文档。查了下说是走的标准“输入事件”,和外接键盘是一样的。既然是输入事件,就掐Activity 的 dispatchKeyEvent 方法了。

    public boolean dispatchKeyEvent(KeyEvent event) {

扫码枪在识别到扫的码后,会多一个KEYCODE_ENTER,和KEYCODE_DPAD_DOWN 事件,查阅的资料里都有说到KEYCODE_ENTER,没提到KEYCODE_DPAD_DOWN,也不知道其它扫码枪会不会生成这个事件

3、实验结果

在Activity 的dispatchKeyEvent 方法中把 KeyEvent log 打印了下:(只打出action=ACTION_UP 躺起的log,按下action=ACTION_DOWN 是结队的 忽略)

  • 3.1、android 设备软键盘的log
    在这里插入图片描述

  • 3.2、外接扫码枪的log (新大陆的NLS-FR40)
    在这里插入图片描述

  • 3.2、外接键盘的log (普通的键盘)
    在这里插入图片描述
    这里附一句,若小键盘的num按钮锁住,metaState= meta_num_lock_on

对比结论小结:

  1. 标准外接扫描枪和标准外接键盘是类似的输入设备
  2. 自带软件盘的输入事件里,deviceId,source,scanCode,flag 和外接的设备不同
  3. 扫码枪和外接键盘的 deviceId,source 不同

4、查看KeyEvent源码进行比较

简单的查看下keyEvent 的源码,可以明显的看到,设备的虚拟软键盘是把deiveId=KeyCharacterMap.VIRTUAL_KEYBOARD (-1),写死了,所以取该字段的不同来区分是软键盘还是 外接键盘。 目前不打算区分扫描枪和外接键盘。

     * Create a new key event.
     *
     * @param downTime The time (in {@link android.os.SystemClock#uptimeMillis})
     * at which this key code originally went down.
     * @param eventTime The time (in {@link android.os.SystemClock#uptimeMillis})
     * at which this event happened.
     * @param action Action code: either {@link #ACTION_DOWN},
     * {@link #ACTION_UP}, or {@link #ACTION_MULTIPLE}.
     * @param code The key code.
     * @param repeat A repeat count for down events (> 0 if this is after the
     * initial down) or event count for multiple events.
     */
    public KeyEvent(long downTime, long eventTime, int action,
                    int code, int repeat) {
        mDownTime = downTime;
        mEventTime = eventTime;
        mAction = action;
        mKeyCode = code;
        mRepeatCount = repeat;
        mDeviceId = KeyCharacterMap.VIRTUAL_KEYBOARD;
    }

    

    /**
     * Create a new key event.
     *
     * @param downTime The time (in {@link android.os.SystemClock#uptimeMillis})
     * at which this key code originally went down.
     * @param eventTime The time (in {@link android.os.SystemClock#uptimeMillis})
     * at which this event happened.
     * @param action Action code: either {@link #ACTION_DOWN},
     * {@link #ACTION_UP}, or {@link #ACTION_MULTIPLE}.
     * @param code The key code.
     * @param repeat A repeat count for down events (> 0 if this is after the
     * initial down) or event count for multiple events.
     * @param metaState Flags indicating which meta keys are currently pressed.
     * @param deviceId The device ID that generated the key event.
     * @param scancode Raw device scan code of the event.
     */
    public KeyEvent(long downTime, long eventTime, int action,
                    int code, int repeat, int metaState,
                    int deviceId, int scancode) {
        mDownTime = downTime;
        mEventTime = eventTime;
        mAction = action;
        mKeyCode = code;
        mRepeatCount = repeat;
        mMetaState = metaState;
        mDeviceId = deviceId;
        mScanCode = scancode;
    }

5、拦截策略

需要一点android “事件传递” 的基础知识,面试必备知识。以前也记录过:Android 事件传递与焦点处理(tv)
在Activity 中事件传递,特别是按键的拦截其实很方便,重写dispatchKeyEvent 方法就可以了。重写的思路也很简单:判断是不是扫描枪用deviceId == -1 来判断。
伪代码

   public boolean dispatchKeyEvent(KeyEvent event) {
        Log.d(TAG, "event= " + event);

        if (如果是扫描枪的事件) {
         //直接消费掉,不继续向下传,editTextView也不自动填充了,KEYCODE_ENTER 事件也不影响 其它控件了,比如button 的点击事件
            return true;
        }

        return super.dispatchKeyEvent(event);
    }

实际使用中,往往没有这么暴力,比如要对是否完全拦截进行控制,单独封装管理工具类,这些属于封装技巧了,在章末有简单封装

     * 处理输入事件
     *
     * @param event
     * @return true 表示消费掉,拦截不在传递, false 不管
     */
    public boolean dispatchKeyEvent(KeyEvent event) {

        /**
         * 系统的软键盘  按下去是 -1, 不管,不拦截
         */
        if (event.getDeviceId() == -1) {
            return false;
        }

        //按下弹起,识别到弹起的话算一次 有效输入
        //只要是 扫码枪的事件  都要把他消费掉 不然会被editText 显示出来
        if (event.getAction() == KeyEvent.ACTION_UP) {

            //只要数字,一维码里面没有 字母
            int code = event.getKeyCode();
            if (code >= KeyEvent.KEYCODE_0 && code <= KeyEvent.KEYCODE_9) {

                codeStr += (code - KeyEvent.KEYCODE_0);
            }

            //识别到结束,当下使用的设备是  是还会有个KEYCODE_DPAD_DOWN 事件,不知道其它设备有没有  先忽略
            if (code == KeyEvent.KEYCODE_ENTER) {

                if (listener != null) {
                    listener.onResult(codeStr);
                    codeStr = "";
                }
            }

        }
        //都是扫码枪来的事件,选择消费掉

        return isInterrupt;
    }

6、其它处理

项目需要外接扫码枪,扫码枪有几种模式:

  1. 短按触发扫码,松开停止
  2. 短按触发,连续扫码
  3. 感应触发,超时停止 (项目中会用这种方式)

描述这个的原因是,会涉及不相关界面的误操作,比如在x界面,我们去扫码了。如果不处理会导致KEYCODE_ENTER 会响应该界面中的某个按钮点击事件,造成干扰。so 我们需要在这个项目的基类BaseActivity 中对扫码枪的输入事件进行处理。目前我打算使用的处理策略是,BaseActivity 完全拦截扫码枪事件,需要使用到的界面自行打开。这边的处理算封装上的处理就不熬述了,具体见demo代码

7、付例与参考

注:

AccessibilityService 的方式,需要手动在:设置->无障碍->服务,中开启,需要人力培训交互不够友好放弃了

参考:

[1]、https://stackoverflow.com/questions/11349542/handle-barcode-scanner-value-via-android-device
[2]、https://blog.csdn.net/csdnno/article/details/79639426

工程demo

代码:https://github.com/lckj686/BarcodeScannerGunMaster

### 回答1: LabVIEW是一种强大的图形化编程工具,它可以与各种硬件设备和仪器进行集成。要使用LabVIEW读取扫码的二维码,可以按照以下步骤进行操作: 1. 安装VISA驱动程序:扫码通常通过串口与计算机连接,需要在计算机上安装适当的驱动程序。可以从生产商的官方网站上下载并安装VISA(Virtual Instrument Software Architecture)驱动程序。 2. 连接扫码:将扫码插入计算机上的串口(或通过USB转串口适配器连接),确保连接正常。 3. 打开LabVIEW:打开LabVIEW,创建一个新的VI(Virtual Instrument)。 4. 创建串口读取节点:在Block Diagram中,搜索“VISA”并选择“VISA Resource Name”函数。将其拖动到Block Diagram上。 5. 配置串口:右键单击“VISA Resource Name”节点,选择“Create Constant”。在弹出的对话框中,选择与扫码连接的串口。 6. 设置读取参数:使用“VISA Configure Serial Port”节点来设置串口的波特率、数据位、停止位和校验位等参数。通过右键单击节点并选择“Create Constant”来设置需要的参数。 7. 读取二维码数据:使用“VISA Read”节点来读取扫码接收到的数据。将其连接到“VISA Configure Serial Port”节点的输出。 8. 显示结果:使用适当的控件(如String、Indicator等)来显示读取到的二维码数据。 9. 运行VI:点击LabVIEW界面上的运行按钮,即可开始读取扫码的二维码。如果一切设置正确,LabVIEW会从扫码接收到数据并显示。 需要注意的是,具体使用LabVIEW读取扫码的二维码可能会因扫码型号、串口设置等因素而有所不同。因此,在操作过程中,根据具体的设备和需求进行调整和优化。 ### 回答2: 在labview中使用扫码读取二维码需要按照以下步骤进行操作: 1. 连接扫码:首先确保扫码已经正确连接到电脑。可以通过USB接口或者其他接口将扫码连接到电脑。 2. 安装必要的驱动程序:在使用扫码之前,需要确保已经安装了扫码的驱动程序。如果没有自动安装,可以从官方网站上下载并进行手动安装。 3. 打开LabView:启动LabView软件。 4. 创建新的VI文件:在LabView中创建一个新的VI文件。 5. 添加控件:在新的VI文件中,从"Controls"面板中添加一个按钮和一个文本框控件。 6. 控件连线:将扫码的输出端口连接到文本框控件的输入端口。 7. 编写代码:在按钮的点击事件中,添加代码来执行读取二维码的操作。可以使用LabView内置的VI函数来实现。 8. 运行程序:运行程序,点击按钮,扫描二维码。 9. 获取二维码数据:扫描二维码后,数据将会显示在文本框控件中。 10. 处理二维码数据:根据需要,可以对获取到的二维码数据进行进一步的处理,例如解码、解析等操作。 总结起来,在LabView中使用扫码读取二维码的关键步骤是连接扫码、安装驱动程序、创建VI文件、添加控件、编写代码、运行程序、获取和处理二维码数据。通过以上步骤,可以实现在LabView中使用扫码读取二维码的功能。 ### 回答3: LabVIEW是一种基于图形化编程环境的开发工具,常用于科学研究和工程应用。要使用扫码读取二维码,可以参考以下步骤: 1. 连接扫码:将扫码通过USB接口或其他适配器连接到计算机。 2. 安装扫码驱动程序:根据扫码型号,从官方网站或光盘上下载和安装相应的驱动程序。确保驱动程序与LabVIEW兼容。 3. 打开LabVIEW:启动LabVIEW开发环境。 4. 创建新的VI:在LabVIEW开发环境中,创建一个新的VI(Virtual Instrument)。 5. 添加输入控制:在VI中,选择"输入控制"栏目,并从控件面板中拖拽一个文本框或字符串输入框到前面板上。 6. 配置输入对象:选择文本框或字符串输入框,在属性面板上将其命名为"二维码扫描结果"或类似的名称。 7. 添加扫码读取功能:在LabVIEW编辑器中,选择"函数"栏目,并搜索或浏览相关的扫码API函数。 8. 将函数拖拽到编辑器中:在函数库中找到适合的函数,例如"读取二维码"或"扫描"函数,并将其拖拽到编辑器图表中。 9. 连接输入和输出:将扫码输入连接到前面板上的文本框或字符串输入框,并将输出连接到后面的数据处理模块。 10. 配置参数:根据扫码的要求,设置相应的参数,如扫描速度、解码格式等。 11. 运行VI:保存并运行VI,然后尝试使用扫码扫描二维码。扫描结果将自动显示在前面板上的文本框或字符串输入框中。 12. 数据处理:可以通过其他LabVIEW功能模块对扫描结果进行处理、解码或记录。 13. 调试和优化:如果存在问题或需要优化,可以使用调试工具和技术进行诊断和修正。 总的来说,通过以上步骤,您就可以在LabVIEW中使用扫码读取二维码。请注意,具体的实现可能会因扫码型号、LabVIEW版本等因素而有所差异,请根据实际情况进行调整和优化。
评论 18
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值