Android外接设备扫码枪或USB外接磁条卡刷卡器工具类

原来项目中使用的zxing的扫码进行扫码支付,由于硬件设备更换开始使用USB扫码枪,就百度然后自己结合网上的demo优化了一个工具类,该工具类主要实现的就是扫描二维码,条形码(由于扫码枪和磁条卡刷卡器都属于同一类事件所以该工具类同样适用于USB外接磁条卡刷卡器)(很早之前找的代码找不到原来demo的连接 了,不好意思)
下面是工具类的实现,采用单例模式


/**
 * Created by RJX
 * 2018/7/18.
 * 自定义扫码枪---密码键盘刷卡器工具类
 */

public class ScanGunHelper {
    private static volatile ScanGunHelper mInstance;
    private final static long MESSAGE_DELAY = 500;             //延迟500ms,判断扫码是否完成。
    private StringBuffer mStringBufferResult;                  //扫码内容
    private boolean mCaps;                                     //大小写区分
    private Handler mHandler;
    private Runnable mScanningFishedRunnable;
    private ScanGunHelper.OnScanSuccessListener mOnScanSuccessListener;

    private ScanGunHelper() {
        mStringBufferResult = new StringBuffer();
        mHandler = new Handler();
        mScanningFishedRunnable = new Runnable() {
            @Override
            public void run() {
                performScanSuccess();
            }
        };
    }

    public static ScanGunHelper getInstance() {
        if (null == mInstance) {
            synchronized (ScanGunHelper.class) {
                if (null == mInstance) {
                    mInstance = new ScanGunHelper();
                }
            }
        }
        return mInstance;
    }

    /**
     * 返回扫码成功后的结果
     */
    private void performScanSuccess() {
        try {
            String barcode = mStringBufferResult.toString();
            if (mOnScanSuccessListener != null && !TextUtils.isEmpty(barcode)) {
                mOnScanSuccessListener.onSuccess(barcode);
            }
            mStringBufferResult.setLength(0);
            if (mHandler != null) {
                mHandler.removeCallbacks(mScanningFishedRunnable);
            }
            mOnScanSuccessListener = null;
        } catch (Exception e) {
            e.printStackTrace();
        }
    }


    /**
     * 扫码枪事件解析
     */
    public void analysisKeyEvent(KeyEvent event, ScanGunHelper.OnScanSuccessListener listener) {
        if (!isScanGunEvent(event)) {
            return;
        }
        //Virtual是我所使用机器的内置软键盘的名字
        //在这判断是因为项目中避免和软键盘冲突(扫码枪和软键盘都属于按键事件)
        if (!event.getDevice().getName().equals("Virtual")) {
            int keyCode = event.getKeyCode();
            //字母大小写判断
            checkLetterStatus(event);
            if (event.getAction() == KeyEvent.ACTION_DOWN) {
                mOnScanSuccessListener = listener;
                char aChar = getInputCode(event);
                if (aChar != 0) {
                    mStringBufferResult.append(aChar);
                }
                if (keyCode == KeyEvent.KEYCODE_ENTER) {
                    mHandler.removeCallbacks(mScanningFishedRunnable);
                    mHandler.post(mScanningFishedRunnable);
                } else {
                    mHandler.removeCallbacks(mScanningFishedRunnable);
                    mHandler.postDelayed(mScanningFishedRunnable, MESSAGE_DELAY);
                }
            }
        }
    }

    //检查shift键
    private void checkLetterStatus(KeyEvent event) {
        int keyCode = event.getKeyCode();
        if (keyCode == KeyEvent.KEYCODE_SHIFT_RIGHT || keyCode == KeyEvent.KEYCODE_SHIFT_LEFT) {
            //按着shift键,表示大写
            //松开shift键,表示小写
            mCaps = event.getAction() == KeyEvent.ACTION_DOWN;
        }
    }

    //获取扫描内容
    private char getInputCode(KeyEvent event) {
        int keyCode = event.getKeyCode();
        char aChar;
        if (keyCode >= KeyEvent.KEYCODE_A && keyCode <= KeyEvent.KEYCODE_Z) {
            //字母
            aChar = (char) ((mCaps ? 'A' : 'a') + keyCode - KeyEvent.KEYCODE_A);
        } else if (keyCode >= KeyEvent.KEYCODE_0 && keyCode <= KeyEvent.KEYCODE_9) {
            //数字
            aChar = (char) ('0' + keyCode - KeyEvent.KEYCODE_0);
        } else {
            //其他符号
            switch (keyCode) {
                case KeyEvent.KEYCODE_PERIOD:
                    aChar = '.';
                    break;
                case KeyEvent.KEYCODE_MINUS:
                    aChar = mCaps ? '_' : '-';
                    break;
                case KeyEvent.KEYCODE_SLASH:
                    aChar = '/';
                    break;
                case KeyEvent.KEYCODE_BACKSLASH:
                    aChar = mCaps ? '|' : '\\';
                    break;
                default:
                    aChar = 0;
                    break;
            }
        }
        return aChar;
    }


    /**
     * 扫码成功回调接口
     */
    public interface OnScanSuccessListener {
        void onSuccess(String barcode);
    }

    /**
     * 输入设备是否存在
     */
    private boolean isInputDeviceExist(String deviceName) {
        int[] deviceIds = InputDevice.getDeviceIds();
        for (int id : deviceIds) {
            if (InputDevice.getDevice(id).getName().equals(deviceName)) {
                return true;
            }
        }
        return false;
    }


    /**
     * 是否为扫码枪事件(部分机型KeyEvent获取的名字错误)
     */
    private boolean isScanGunEvent(KeyEvent event) {
        return isInputDeviceExist(event.getDevice().getName());
    }
}

接下来就是在Activity中使用了

/**
 *
 * @author RJxiang
 * @date 2018/7/3
 */
public class GunClosingActivity extends BaseActivity implements
        ScanGunHelper.OnScanSuccessListener {
    //其实这类事件都是普通的按键事件通过dispatchKeyEvent就可以拦截
    //------------------------------获取磁条卡信息-------------------------------
    @Override
    public boolean dispatchKeyEvent(KeyEvent event) {
        if (!event.getDevice().getName().equals("Virtual")) {
        //activity实现了扫码成功的回调这里的this就是这个listener(不懂得就百度下吧)
        //采用单例模式调用
            ScanGunHelper.getInstance().analysisKeyEvent(event, this);
            return true;
        }
        return super.dispatchKeyEvent(event);
    }

    @Override
    public void onSuccess(String barcode) {
        if (barcode != null) {
            if (TextUtils.isEmpty(barcode)) {
                ToastUtils.showToast(this, "刷卡失败", Toast.LENGTH_LONG);
                return;
            }
            requestMemberInfo(barcode); //请求会员信息
        }
    }
}

如果不能满足您的需求您可以在这个的基础上进行修改,
由于在fragment中使用时候需要拦截dispatchKeyEvent事件但是fragment中没办法做到拦截此方法,所以可以在fragment所关联的activity中拦截dispatchKeyEvent事件,再传给fragment,这只是其中的一种方案,仅供参考。

评论 7
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值