Android 实现USB扫码数据抓取(三个参考方法)

日期:2019-07-29 分类:微信刷脸开发SDK资料 下载:1816 浏览:13588

点击下载

更多附件:
点击下载 点击下载

Android使用AccessibilityService实现USB扫码枪数据抓取

 

android单屏机,通过扫码枪扫描二维码的场景非常多,扫码枪的种类也有蓝牙、USB、串口等等

目前USB的扫码枪主流的就是以下两种

1USB HID-KBW:扫码器会将扫描出来的内容转化为键盘事件,就是AndroidKeyEvent里面对应的常量(KeyEvent.KEYCODE_*)

2USB 虚拟串口:可使用android-serialport-api 连接到UsbDevice进行通信,读取数据。(设备要支持串口)

支持 Android 热插拔USB扫描枪会在有EditText时,扫描枪扫描内容自动输入到编辑框了,但是有很多输入法兼容的问题,比如搜狗输入法识别到HID设备时会隐藏无法弹出,如果输入法切换成中文时会输入中文等等。

通过串口的方式直接获取原始数据,不再跟输入法产生冲突,可惜设备是USB HID的,通过大量的尝试(包括USB虚拟串口)都不支持(对串口不了解的同学可以先看看这篇文章上半年最好的Android串口开发入门指南 - 简书 

扫码枪是基于键盘输入的,尝试从获取焦点的Activity中的dispatchKeyEvent(KeyEvent event)进行拦截,可惜只能解决掉中文的问题,事件还是先走到输入法才能回到Activity。于是强大的AccessibilityService就上场了,使用AccessibilityService可以优先获取到键盘事件。

使用强大的AccessibilityServiceGoogle为了让Android系统更实用,为用户提供了无障碍辅助服务),但需要到系统设置->无障碍->服务 开启当前服务。对AccessibilityService不了解的同学看看http://www.jianshu.com/p/4cd8c109cdfb

废话不多说看实现步骤

1、先创建扫码Service直接继承AccessibilityServiceOK

public class ScanService extends AccessibilityService {

    private static OnKeyEvent onKeyEvent;

    @Override

    public int onStartCommand(Intent intent, int flags, int startId) {

        return START_STICKY;

    }

 

    @Override

    public void onAccessibilityEvent(AccessibilityEvent event) {

    }

 

    @Override

    public void onInterrupt() {

    }

 

    @Override

    protected boolean onKeyEvent(KeyEvent event) {

        if(onKeyEvent!=null){

          //这里通过回调的方式将事件传出去统一处理

          //返回true事件就会拦截不会继续传递

           return onKeyEvent.onKeyEvent(event);

        }

        return super.onKeyEvent(event);

    }

    /**

     * 设置监听

     * @param onKeyEvent

     */

    public static void setOnKeyEvent(OnKeyEvent onKeyEvent){

        ScanService.onKeyEvent=onKeyEvent;

    }

    public interface OnKeyEvent{

        boolean onKeyEvent(KeyEvent event);

    }

}

2、创建好自己的ScanService后需要在manifest中进行注册

 <service

            android:name="包名.service.ScanService"

            android:enabled="true"

            android:exported="true"

            android:permission="android.permission.BIND_ACCESSIBILITY_SERVICE">

            <intent-filter>

                <action android:name="android.accessibilityservice.AccessibilityService"/>

            </intent-filter>

            <meta-data

                android:name="android.accessibilityservice"

                android:resource="@xml/accessibility"

                />

</service>

创建android:resource需要用到的xml ,在res下新建xml文件夹,新建accessibility.xml

<?xml version="1.0" encoding="utf-8"?>

<accessibility-service xmlns:android="http://schemas.android.com/apk/res/android"

    android:accessibilityEventTypes="typeAllMask"

    android:accessibilityFeedbackType="feedbackGeneric"

    android:accessibilityFlags="flagRequestFilterKeyEvents"

    android:canRetrieveWindowContent="true"

    android:notificationTimeout="100"

    android:canRequestFilterKeyEvents="true"

    android:description="@string/accessibility_description"

    android:packageNames="包名" />

android:description指定一个String作为描述文案

<string name="accessibility_description">这里是描述辅助功能的文案</string>

到此为止AccessibilityService就配置好了,你的应用就会出现在系统设置->辅助功能列表里,只需要手动在设置中打开辅助功能,扫码枪的键盘事件就会触发ScanServiceonKeyEvent

接下来是对事件的处理
1
、过滤非扫码枪的设备

  /**

     * 检测输入设备是否是扫码器

     *

     * @param context

     * @return 是的话返回true,否则返回false

     */

    public boolean isInputFromScanner(Context context, KeyEvent event) {

        if (event.getDevice() == null) {

            return false;

        }

//        event.getDevice().getControllerNumber();

        if (event.getKeyCode() == KeyEvent.KEYCODE_BACK || event.getKeyCode() == KeyEvent.KEYCODE_VOLUME_DOWN || event.getKeyCode() == KeyEvent.KEYCODE_VOLUME_UP) {

            //实体按键,若按键为返回、音量加减、返回false

            return false;

        }

        if (event.getDevice().getSources() == (InputDevice.SOURCE_KEYBOARD | InputDevice.SOURCE_DPAD | InputDevice.SOURCE_CLASS_BUTTON)) {

            //虚拟按键返回false

            return false;

        }

        Configuration cfg = context.getResources().getConfiguration();

        return cfg.keyboard != Configuration.KEYBOARD_UNDEFINED;

    }

2、处理事件

Runnable mScanningFishedRunnable = new Runnable() {

            @Override

            public void run() {

                String code = mStringBufferResult.toString();

                //做相应处理....

                mStringBufferResult.setLength(0);

            }

        };

/**

     * 扫码枪事件解析

     *

     * @param event

     */

    public void analysisKeyEvent(KeyEvent event) {

 

        int keyCode = event.getKeyCode();

 


上一篇:对接收银机双工线 开发SDK

下一篇:安卓app实现laucher(启动器功能)功能

0755 - 8336 8811
13632541019 18025353128