对ZXing进行封装,整合成一个调用简单的Scanner接口

来源:互联网 发布:ug四轴联动编程实例 编辑:程序博客网 时间:2024/06/16 08:58

        最近有用到扫描二维码和条形码的需求,看到当前主要有两个比较有名的开源库ZBar和ZXing,怀着对Google的仰慕之心,并且凭着对二维码扫码的优势,最终决定使用ZXing来进行开发。

        网上已有很多大神对ZXing的使用进行了详解,但是并没有独立成一个模块。本文的思路是将ZXing再次封装,整合成一个调用简单的Scanner,仅仅对外暴露出几个回调的接口,使其作为一个独立的插件来使用,对项目的耦合性尽可能的低。

        至于具体实现,本人由于水平有限,思前想后,最终采用广播来实现(如有大神有更好的实现方式,欢迎指教)。核心思想是用一个Scanner类来进行对扫码Activity的管理,包括该Activity的启动、扫码结果的处理、扫码错误以及用户取消事件的处理和最终Activity的关闭等。

        Scanner类中的处理

        1. Scanner 打开时的处理:启动扫码的Activity,注册广播,该广播接收器中实现了对ScannerListener的监听回调

    public void open(){        Intent intent = new Intent(context, MipcaActivityCapture.class);        intent.putExtra(TIMEOUT, mTimeout);        context.startActivity(intent);        registerMyBroadcastReceiver();    }    private void registerMyBroadcastReceiver(){        if(!isBroadcastRegistered) {            isBroadcastRegistered = !isBroadcastRegistered;            IntentFilter intentFilter = new IntentFilter();            intentFilter.addAction(QRCodeScanner.SCAN_INTENT_ACTION);            context.registerReceiver(receiver, intentFilter);        }    }    private BroadcastReceiver receiver = new BroadcastReceiver() {        @Override        public void onReceive(Context context, Intent intent) {            if (intent.getAction().endsWith(SCAN_INTENT_ACTION)) {                int flag = intent.getIntExtra("FLAGS", ERROR_FLAG);                switch ( flag ){                    case SUCCESS_FLAG:                        qrCodeStr = intent.getStringExtra("QR_CODE_STR");                        if(listener != null) {                            listener.onReadSuccess(qrCodeStr);                        }                        break;                    case CANCEL_FLAG:                        if(listener != null){                            listener.onCancel();                        }                        break;                    case ERROR_FLAG:                    default:                        if(listener != null){                            listener.onReadError();                        }                        break;                }            }        }    };
        2. Scanner开始扫码时的处理:实现监听器接口

    public void start(ScannerListener listener){        this.listener = listener;    }    public interface ScannerListener{        void onReadSuccess(String result);        void onReadError();        void onCancel();    }
        3. Scanner关闭时的处理:取消广播的注册,并向扫码Actiivty发送关闭自身的广播(该Scanner的设计思想是只能通过此种方式关闭扫码Activity,禁止其他方式来关闭)

    public void close(){        unRegisterMyBroadcastReceiver();        Intent intent = new Intent(MipcaActivityCapture.CLOSE_SCANNER_INTENT_ACTION);        context.sendBroadcast(intent);    }    private void unRegisterMyBroadcastReceiver(){        if(isBroadcastRegistered) {            isBroadcastRegistered = !isBroadcastRegistered;            context.unregisterReceiver(receiver);        }    }

        扫码Activity中的处理

        1. 在该Activity 的onCreate方法中注册自己的销毁广播

    private void registerDestroyActivityReceiver(){        IntentFilter intentFilter = new IntentFilter();        intentFilter.addAction(CLOSE_SCANNER_INTENT_ACTION);        registerReceiver(mDestroyActivityReceiver, intentFilter);    }    private BroadcastReceiver mDestroyActivityReceiver = new BroadcastReceiver() {        @Override        public void onReceive(Context context, Intent intent) {           if(intent.getAction().equals(CLOSE_SCANNER_INTENT_ACTION)){                finish();            }        }    };

        2.在扫码结果处理的代码中根据扫码结果发送扫码成功或失败的广播

    /**     * 处理扫描结果     * @param result     * @param barcode     */    public void handleDecode(Result result, Bitmap barcode) {        inactivityTimer.onActivity();        playBeepSoundAndVibrate();        String resultString = result.getText();        if(TextUtils.isEmpty(resultString)){            Toast.makeText(MipcaActivityCapture.this, "Scan failed!", Toast.LENGTH_SHORT).show();            sendScanErrorBroadcast();        }else{            sendSuccessBroadcast(resultString);        }    }    private void sendSuccessBroadcast(String qrcodeStr){        Intent intent = new Intent(QRCodeScanner.SCAN_INTENT_ACTION);        intent.putExtra("FLAGS", QRCodeScanner.SUCCESS_FLAG);        intent.putExtra("QR_CODE_STR", qrcodeStr);        sendBroadcast(intent);    }    public void sendScanErrorBroadcast(){        Intent intent = new Intent(QRCodeScanner.SCAN_INTENT_ACTION);        intent.putExtra("FLAGS", QRCodeScanner.ERROR_FLAG);        sendBroadcast(intent);    }
        3.在用户点击“返回”按钮或“返回”键时发送“用户取消操作事件”的广播

    private void sendCancelBroadcast(){        Intent intent = new Intent(QRCodeScanner.SCAN_INTENT_ACTION);        intent.putExtra("FLAGS", QRCodeScanner.CANCEL_FLAG);        sendBroadcast(intent);    }
        4.在扫码Activity的onDestroy()方法中取消销毁广播的注册

    @Override    protected void onDestroy() {        inactivityTimer.shutdown();        super.onDestroy();        unregisterReceiver(mDestroyActivityReceiver);    }
        至此,Scanner的封装已经完成,让我们来体会一下该Scanner使用时的简洁和优雅吧

    private void startScanner(){        final QRCodeScanner qrCodeScanner = new QRCodeScanner(this);        qrCodeScanner.open();        qrCodeScanner.start(new QRCodeScanner.ScannerListener() {            @Override            public void onReadSuccess(String result) {                qrCodeScanner.close();                tvQRCode.setText(result);                Log.i("Tag", "read success...");            }            @Override            public void onReadError() {                qrCodeScanner.close();                Log.i("Tag", "read error or time out...");            }            @Override            public void onCancel() {                qrCodeScanner.close();                Log.i("Tag", "user canceled...");            }        });    }
        源码下载地址:对ZXing封装的Scanner源码


阅读全文
0 0
原创粉丝点击