Android Zxing的简单使用

最近因为需求,用到了扫码,所以也就自己记录下,该文并没有太多详细的分析,只有自己使用的过程,并且只涉及android的扫二维码以及条形码,并没有多余的功能。(Zxing 代码具体什么版本忘记了,小伙伴可以自行替换)。

先来看下目录的结构
这里写图片描述

代码主要就是2部分,一部分是Zxing的代码,另一部分是2个Activity,其中ScanActivity就是调用了Zxing的扫码页面,ScanCodeActivity就是显示返回的扫码结果页。

然后看下对应的页面效果:

ScanCodeActivity:

这里写图片描述

ScanActivity:

这里写图片描述

这里写图片描述

具体代码实现:

public final class ScanActivity extends Activity implements ScanListener, View.OnClickListener {
    static final String TAG = ScanActivity.class.getSimpleName();
    private static final int RQ_CARAME = 102;
    private static final int SCAN_REQUEST = 7;
    SurfaceView scanPreview = null;
    private boolean isSuccess = false;
    private String scanResult;
    View scanContainer;
    View scanCropView;
    ImageView scanLine;
    ScanManager scanManager;
    TextView iv_light;
    TextView qrcode_g_gallery;
    TextView qrcode_ic_back;
    Button rescan ;
    ImageView scan_image;
    ImageView authorize_return;
    TextView title;
    TextView scan_hint;
    TextView tv_scan_result;
    final int PHOTOREQUESTCODE = 1111;
    private int scanMode;//扫描模型(条形,二维码,全部)




    @Override
    public void onCreate(Bundle icicle) {
        super.onCreate(icicle);
        Window window = getWindow();
        window.addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
        setContentView(R.layout.activity_scan);
        scanMode=getIntent().getIntExtra(Constant.REQUEST_SCAN_MODE,Constant.REQUEST_SCAN_MODE_ALL_MODE);
        initView();
    }

    void initView() {
        rescan = (Button)findViewById(R.id.service_register_rescan);
        scan_image = (ImageView)findViewById(R.id.scan_image);
        authorize_return = (ImageView)findViewById(R.id.authorize_return);
        title = (TextView) findViewById(R.id.common_title_TV_center);
        scan_hint = (TextView) findViewById(R.id.scan_hint);
        tv_scan_result = (TextView) findViewById(R.id.tv_scan_result);

        scanPreview = (SurfaceView) findViewById(R.id.capture_preview);
        scanContainer = findViewById(R.id.capture_container);
        scanCropView = findViewById(R.id.capture_crop_view);
        scanLine = (ImageView) findViewById(R.id.capture_scan_line);
        qrcode_g_gallery = (TextView) findViewById(R.id.qrcode_g_gallery);
        qrcode_g_gallery.setOnClickListener(this);
        qrcode_ic_back = (TextView) findViewById(R.id.qrcode_ic_back);
        qrcode_ic_back.setOnClickListener(this);
        iv_light = (TextView) findViewById(R.id.iv_light);
        iv_light.setOnClickListener(this);
        switch (scanMode){
            case DecodeThread.BARCODE_MODE://0X100
                title.setText(R.string.scan_barcode_title);
                scan_hint.setText(R.string.scan_barcode_hint);
                break;
            case DecodeThread.QRCODE_MODE://0X200
                title.setText(R.string.scan_qrcode_title);
                scan_hint.setText(R.string.scan_qrcode_hint);
                break;
            case DecodeThread.ALL_MODE://0X300
                title.setText(R.string.scan_allcode_title);
                scan_hint.setText(R.string.scan_allcode_hint);
                break;
        }
        rescan.setOnClickListener(this);
        authorize_return.setOnClickListener(this);

        scanManager = new ScanManager(this, scanPreview, scanContainer, scanCropView, scanLine, scanMode,this);


    }

    @Override
    public void onResume() {
        super.onResume();
        Log.e("scanManager","scanManager init 4");
        if(scanManager != null){
            scanManager.onResume();
        }
        rescan.setVisibility(View.INVISIBLE);
        scan_image.setVisibility(View.GONE);
    }

    @Override
    public void onPause() {
        super.onPause();
        if(scanManager != null){
            scanManager.onPause();
        }
    }
    /**
     *
     */
    public void scanResult(Result rawResult, Bundle bundle) {
        //扫描成功后,扫描器不会再连续扫描,如需连续扫描,调用reScan()方法。
        //scanManager.reScan();
//      Toast.makeText(that, "result="+rawResult.getText(), Toast.LENGTH_LONG).show();

        if (!scanManager.isScanning()) { //如果当前不是在扫描状态
            //设置再次扫描按钮出现
            rescan.setVisibility(View.VISIBLE);
            scan_image.setVisibility(View.VISIBLE);
            Bitmap barcode = null;
            byte[] compressedBitmap = bundle.getByteArray(DecodeThread.BARCODE_BITMAP);
            if (compressedBitmap != null) {
                barcode = BitmapFactory.decodeByteArray(compressedBitmap, 0, compressedBitmap.length, null);
                barcode = barcode.copy(Bitmap.Config.ARGB_8888, true);
            }
            scan_image.setImageBitmap(barcode);
        }
        rescan.setVisibility(View.VISIBLE);
        scan_image.setVisibility(View.VISIBLE);
        tv_scan_result.setVisibility(View.VISIBLE);
        scanResult = rawResult.getText().toString();
        Drawable drawable= getResources().getDrawable(R.mipmap.scan_success);
        qrcode_ic_back.setBackground(drawable);
        isSuccess = true;
        tv_scan_result.setText("结果:"+rawResult.getText());
    }

    void startScan() {
        if (rescan.getVisibility() == View.VISIBLE) {
            rescan.setVisibility(View.INVISIBLE);
            scan_image.setVisibility(View.GONE);
            Drawable drawable= getResources().getDrawable(R.mipmap.scan2code_icon_back_nor);
            qrcode_ic_back.setBackground(drawable);
            isSuccess = false;
            scanManager.reScan();

        }
    }

    @Override
    public void scanError(Exception e) {
        Toast.makeText(this, e.getMessage(), Toast.LENGTH_LONG).show();
        //相机扫描出错时
        if(e.getMessage()!=null&&e.getMessage().startsWith("相机")){
            scanPreview.setVisibility(View.INVISIBLE);
        }
    }

    public void showPictures(int requestCode) {
        Intent intent = new Intent(Intent.ACTION_PICK);
        intent.setType("image/*");
        startActivityForResult(intent, requestCode);
    }

    @Override
    public void onActivityResult(int requestCode, int resultCode, Intent data) {
        super.onActivityResult(requestCode, resultCode, data);
        String photo_path;
        if (resultCode == RESULT_OK) {
            switch (requestCode) {
                case PHOTOREQUESTCODE:
                    String[] proj = {MediaStore.Images.Media.DATA};
                    Cursor cursor = this.getContentResolver().query(data.getData(), proj, null, null, null);
                    if (cursor.moveToFirst()) {
                        int colum_index = cursor.getColumnIndexOrThrow(MediaStore.Images.Media.DATA);
                        photo_path = cursor.getString(colum_index);
                        if (photo_path == null) {
                            photo_path = Utils.getPath(getApplicationContext(), data.getData());
                        }
                        scanManager.scanningImage(photo_path);
                    }
            }
        }
    }

    @Override
    public void onClick(View v) {
        switch (v.getId()) {
            case R.id.qrcode_g_gallery:
                showPictures(PHOTOREQUESTCODE);
                break;
            case R.id.iv_light:
                scanManager.switchLight();
                break;
            case R.id.qrcode_ic_back:
                if(isSuccess){
                    Intent intent = new Intent(ScanActivity.this, ScanCodeActivity.class);//这种方法今天才学的,记下!方便这样写,坑爹的有些教程,这块没有给Inent绑定
                    intent.putExtra("scanResult",scanResult);
                    setResult(Activity.RESULT_OK, intent);
                    finish();
                }else{
                    finish();
                }

                break;
            case R.id.service_register_rescan://再次开启扫描
                startScan();
                break;
            case R.id.authorize_return:
                finish();
                break;
            default:
                break;
        }
    }

}
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
                android:id="@+id/capture_container"
                android:layout_width="match_parent"
                android:layout_height="match_parent"
                android:background="@android:color/white" >
    <SurfaceView
        android:id="@+id/capture_preview"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        />
    <!-- 扫描框上面的布局 -->
    <RelativeLayout
        android:id="@+id/top_mask"
        android:layout_width="match_parent"
        android:layout_height="150dp"
        android:layout_alignParentTop="true"
        android:background="@color/scan_bg">
        <RelativeLayout
            android:id="@+id/title_bar"
            android:layout_width="fill_parent"
            android:layout_height="45dip"
            android:background="@android:color/white" >

            <ImageView
                android:id="@+id/authorize_return"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_alignParentLeft="true"
                android:layout_centerVertical="true"
                android:background="@null"
                android:paddingLeft="12dp"
                android:paddingRight="20dp"
                android:src="@mipmap/ic_my_returns_arrow"
                />
            <TextView
                android:id="@+id/common_title_TV_center"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_centerHorizontal="true"
                android:layout_centerVertical="true"
                android:ellipsize="middle"
                android:singleLine="true"
                android:text="二维码扫描"
                android:textSize="18sp" />
        </RelativeLayout>
        <TextView
            android:id="@+id/tv_scan_result"
            android:layout_marginTop="20dp"
            android:layout_below="@id/title_bar"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="哈哈"
            android:textSize="14sp"
            android:layout_centerInParent="true"
            android:textColor="@android:color/white"
            android:visibility="gone"
            />
    </RelativeLayout>
    <!-- 扫描框底部的布局 -->
    <RelativeLayout
        android:id="@+id/bottom_mask"
        android:layout_width="match_parent"
        android:layout_height="200dp"
        android:layout_alignParentBottom="true"
        android:background="@color/scan_bg"
        android:orientation="vertical"
        android:paddingBottom="16dp"
        >
        <TextView
            android:id="@+id/scan_hint"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_centerHorizontal="true"
            android:text="@string/scan_allcode_hint"
            android:textColor="#b4b4b4"
            android:textSize="14sp"
            android:paddingTop="20dp"
            android:paddingBottom="20dp"
            />

        <TextView
            android:id="@+id/iv_light"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_alignParentRight="true"
            android:layout_marginRight="30dp"
            android:layout_below="@id/scan_hint"
            android:background="@drawable/shouquan_qrcode_s_flashgun"
            android:clickable="true" />

        <TextView
            android:id="@+id/qrcode_ic_back"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_centerHorizontal="true"
            android:layout_below="@id/scan_hint"
            android:background="@mipmap/scan2code_icon_back_nor"
            android:clickable="true" />

        <TextView
            android:id="@+id/qrcode_g_gallery"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_alignParentLeft="true"
            android:layout_marginLeft="30dp"
            android:layout_below="@id/scan_hint"
            android:background="@drawable/shouquan_qrcode_g_gallery"
            android:clickable="true"

            android:textSize="20sp" />
        <Button
            android:id="@+id/service_register_rescan"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_gravity="center_horizontal"
            android:background="@drawable/rescan_shape_button"
            android:padding="10dp"
            android:text="再次扫描"
            android:textColor="@android:color/white"
            android:textSize="18sp"
            android:layout_centerHorizontal="true"
            android:layout_below="@id/qrcode_g_gallery"
            android:visibility="visible"
            android:layout_marginTop="20dp"

            />
    </RelativeLayout>
    <!-- 扫描框中间的布局 -->
    <RelativeLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_below="@id/top_mask"
        android:layout_above="@id/bottom_mask"
        >
        <ImageView
            android:id="@+id/left_mask"
            android:layout_width="34dp"
            android:layout_height="match_parent"
            android:layout_alignParentLeft="true"
            android:background="@color/scan_bg"
            android:contentDescription="@string/app_name" />
        <ImageView
            android:id="@+id/right_mask"
            android:layout_width="34dp"
            android:layout_height="match_parent"
            android:layout_alignParentRight="true"
            android:background="@color/scan_bg" />
        <RelativeLayout
            android:id="@+id/capture_crop_view"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:layout_toLeftOf="@id/right_mask"
            android:layout_toRightOf="@id/left_mask"
            android:layout_centerHorizontal="true"
            android:background="@android:color/transparent" >
            <ImageView
                android:id="@+id/capture_scan_line"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:layout_alignParentTop="true"
                android:layout_margin="5dp"
                android:background="@mipmap/scanning_line" />
            <com.skt.scandemo.view.MyImageView
                android:id="@+id/scan_image"
                android:layout_width="match_parent"
                android:layout_height="match_parent"
                />
        </RelativeLayout>
    </RelativeLayout>

</RelativeLayout>

说明一下:

首先需要初始化扫码的管理类,扫码的操作都在这个管理类当中,当然其中的listener需要该类实现ScanListener。

/**
     * @param activity   扫描的activity
     * @param scanPreview  预览的SurfaceView
     * @param scanContainer  扫描的布局,全屏布局
     * @param scanCropView  扫描的矩形区域
     * @param scanLine  扫描线
     * @param scanMode  扫码模型
     * @param listener  扫码的监听   
     */
scanManager = new ScanManager(this, scanPreview, scanContainer, scanCropView, scanLine, scanMode,this);

然后ScanListerer中只有两个方法,一个成功,一个失败的回调

public interface ScanListener {
    /**
     * 返回扫描结果
     * @param rawResult  结果对象
     * @param bundle  存放了截图,或者是空的
     */
    public void scanResult(Result rawResult, Bundle bundle);
    /**
     * 扫描抛出的异常
     * @param e
     */
    public void scanError(Exception e);

}

成功后,执行scanResult方法,在该方法中,主要做的操作就是更新UI,解析数据,展示数据。

public void scanResult(Result rawResult, Bundle bundle) {
        //扫描成功后,扫描器不会再连续扫描,如需连续扫描,调用reScan()方法。
        //scanManager.reScan();
//      Toast.makeText(that, "result="+rawResult.getText(), Toast.LENGTH_LONG).show();

        if (!scanManager.isScanning()) { //如果当前不是在扫描状态
            //设置再次扫描按钮出现
            rescan.setVisibility(View.VISIBLE);
            scan_image.setVisibility(View.VISIBLE);
            Bitmap barcode = null;
            byte[] compressedBitmap = bundle.getByteArray(DecodeThread.BARCODE_BITMAP);
            if (compressedBitmap != null) {
                barcode = BitmapFactory.decodeByteArray(compressedBitmap, 0, compressedBitmap.length, null);
                barcode = barcode.copy(Bitmap.Config.ARGB_8888, true);
            }
            scan_image.setImageBitmap(barcode);
        }
        rescan.setVisibility(View.VISIBLE);
        scan_image.setVisibility(View.VISIBLE);
        tv_scan_result.setVisibility(View.VISIBLE);
        scanResult = rawResult.getText().toString();
        Drawable drawable= getResources().getDrawable(R.mipmap.scan_success);
        qrcode_ic_back.setBackground(drawable);
        isSuccess = true;
        tv_scan_result.setText("结果:"+rawResult.getText());
    }

ScanManager.java

public class ScanManager implements SurfaceHolder.Callback{
    boolean isHasSurface = false;
    CameraManager cameraManager;
    //用于拍摄扫描的handler
    CaptureActivityHandler handler;
    //用于照片扫描的handler,不可共用,图片扫描是不需要摄像机的
    PhotoScanHandler photoScanHandler;
    Rect mCropRect = null;
    InactivityTimer inactivityTimer;
    public BeepManager beepManager;
    SurfaceView scanPreview = null;
    View scanContainer;
    View scanCropView;
    ImageView scanLine;
    final String TAG= ScanManager.class.getSimpleName();
    Activity activity;
    ScanListener listener;
    boolean isOpenLight=false;

    private int scanMode;//扫描模型(条形,二维码,全部)
    /**
     * 用于启动照相机扫描二维码,在activity的onCreate里面构造出来
     * 在activity的生命周期中调用此类相对应的生命周期方法
     * @param activity   扫描的activity
     * @param scanPreview  预览的SurfaceView
     * @param scanContainer  扫描的布局,全屏布局
     * @param scanCropView  扫描的矩形区域
     * @param scanLine  扫描线
     * @param scanMode  扫码模型
     *  @param listener  扫码的监听
     * 
     */
    public ScanManager(Activity activity, SurfaceView scanPreview, View scanContainer,
                       View scanCropView, ImageView scanLine, int scanMode, ScanListener listener) {
        this.activity=activity;
        this.scanPreview=scanPreview;
        this.scanContainer=scanContainer;
        this.scanCropView=scanCropView;
        this.scanLine=scanLine;
        this.listener=listener;
        this.scanMode=scanMode;
        //启动动画
        TranslateAnimation animation = new TranslateAnimation(Animation.RELATIVE_TO_PARENT, 0.0f, Animation.RELATIVE_TO_PARENT, 0.0f, Animation.RELATIVE_TO_PARENT, 0.0f, Animation.RELATIVE_TO_PARENT,
                0.9f);
        animation.setDuration(4500);
        animation.setRepeatCount(-1);
        animation.setRepeatMode(Animation.RESTART);
        scanLine.startAnimation(animation);

    }
    /**
     * 用于图片扫描的构造函数
     * @param listener  结果的监听回调
     */
    public ScanManager(ScanListener listener){
        this.listener=listener;
    }

    public void onResume(){
        // CameraManager must be initialized here, not in onCreate(). This is
        // necessary because we don't
        // want to open the camera driver and measure the screen size if we're
        // going to show the help on
        // first launch. That led to bugs where the scanning rectangle was the
        // wrong size and partially
        // off screen.
        inactivityTimer = new InactivityTimer(activity);
        beepManager = new BeepManager(activity);
        cameraManager = new CameraManager(activity.getApplicationContext());

        handler = null;
        if (isHasSurface) {
            // The activity was paused but not stopped, so the surface still
            // exists. Therefore
            // surfaceCreated() won't be called, so init the camera here.
            initCamera(scanPreview.getHolder());
        } else {
            // Install the callback and wait for surfaceCreated() to init the
            // camera.
            scanPreview.getHolder().addCallback(this);
        }
        inactivityTimer.onResume();
    }
    public void onPause() {
        if (handler != null) {
            handler.quitSynchronously();
            handler = null;
        }
        inactivityTimer.onPause();
        beepManager.close();
        cameraManager.closeDriver();
        if (!isHasSurface) {
            scanPreview.getHolder().removeCallback(this);
        }
    }
    public void onDestroy() {
        inactivityTimer.shutdown();
    }


    @Override
    public void surfaceCreated(SurfaceHolder holder) {
        if (holder == null) {
            Log.e(TAG, "*** WARNING *** surfaceCreated() gave us a null surface!");
        }
        if (!isHasSurface) {
            isHasSurface = true;
            initCamera(holder);
        }
    }

    @Override
    public void surfaceChanged(SurfaceHolder holder, int format, int width,
                               int height) {
    }

    @Override
    public void surfaceDestroyed(SurfaceHolder holder) {
        isHasSurface = false;
    }
    void initCamera(SurfaceHolder surfaceHolder) {
        if (surfaceHolder == null) {
            throw new IllegalStateException("No SurfaceHolder provided");
        }
        if (cameraManager.isOpen()) {
            Log.w(TAG, "initCamera() while already open -- late SurfaceView callback?");
            return;
        }
        try {
            cameraManager.openDriver(surfaceHolder);
            // Creating the handler starts the preview, which can also throw a
            // RuntimeException.
            if (handler == null) {
                handler = new CaptureActivityHandler(this, cameraManager, scanMode);
                Log.e("hongliang1", "handler new成功!:"+handler);
            }

            initCrop();
        } catch (IOException ioe) {
            Log.e(TAG,"hongliang", ioe);
            //弹出提示,报错
            ioe.printStackTrace();
            listener.scanError(new Exception("相机打开出错,请检查是否被禁止了该权限!"));
        } catch (RuntimeException e) {
            Log.e(TAG, "hongliang", e);
            //弹出提示,报错
            e.printStackTrace();
            listener.scanError(new Exception("相机打开出错,请检查是否被禁止了该权限!"));
        }
    }
    /**
     * 开关闪关灯
     */
    public void switchLight(){
        if(isOpenLight){
            cameraManager.offLight();
        }else{
            cameraManager.openLight();
        }
        isOpenLight=!isOpenLight;
    }
    public Handler getHandler() {
        return handler;
    }

    public CameraManager getCameraManager() {
        return cameraManager;
    }
    public Rect getCropRect() {
        return mCropRect;
    }
    /**
     * 扫描成功的结果回调
     * @param rawResult
     * @param bundle
     */
    public void handleDecode(Result rawResult, Bundle bundle) {
        inactivityTimer.onActivity();
        //扫描成功播放声音滴一下,可根据需要自行确定什么时候播
        beepManager.playBeepSoundAndVibrate();
        bundle.putInt("width", mCropRect.width());
        bundle.putInt("height", mCropRect.height());
        bundle.putString("result", rawResult.getText());
        listener.scanResult(rawResult, bundle);
    }
    public void handleDecodeError(Exception e){
        listener.scanError(e);
    }
    /**
     * 初始化截取的矩形区域
     */
    void initCrop() {
        int cameraWidth = cameraManager.getCameraResolution().y;
        int cameraHeight = cameraManager.getCameraResolution().x;

        /** 获取布局中扫描框的位置信息 */
        int[] location = new int[2];
        scanCropView.getLocationInWindow(location);

        int cropLeft = location[0];
        int cropTop = location[1] - getStatusBarHeight();

        int cropWidth = scanCropView.getWidth();
        int cropHeight = scanCropView.getHeight();

        /** 获取布局容器的宽高 */
        int containerWidth = scanContainer.getWidth();
        int containerHeight = scanContainer.getHeight();

        /** 计算最终截取的矩形的左上角顶点x坐标 */
        int x = cropLeft * cameraWidth / containerWidth;
        /** 计算最终截取的矩形的左上角顶点y坐标 */
        int y = cropTop * cameraHeight / containerHeight;

        /** 计算最终截取的矩形的宽度 */
        int width = cropWidth * cameraWidth / containerWidth;
        /** 计算最终截取的矩形的高度 */
        int height = cropHeight * cameraHeight / containerHeight;

        /** 生成最终的截取的矩形 */
        mCropRect = new Rect(x, y, width + x, height + y);
    }
    int getStatusBarHeight() {
        try {
            Class<?> c = Class.forName("com.android.internal.R$dimen");
            Object obj = c.newInstance();
            Field field = c.getField("status_bar_height");
            int x = Integer.parseInt(field.get(obj).toString());
            return activity.getResources().getDimensionPixelSize(x);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return 0;
    }
    /**
     * 用于扫描本地图片二维码或者一维码
     * @param photo_path2 本地图片的所在位置
     * @return
     */
    public  void scanningImage(final String photo_path2) {
        if(TextUtils.isEmpty(photo_path2)){
            listener.scanError(new Exception("photo url is null!"));
        }
        photoScanHandler=new PhotoScanHandler(this);
        new Thread(new Runnable() {

            @Override
            public void run() {
                //获取初始化的设置器
                Map<DecodeHintType, Object> hints = DecodeThread.getHints();
                hints.put(DecodeHintType.CHARACTER_SET, "utf-8");

//              Hashtable<DecodeHintType, String> hints = new Hashtable<DecodeHintType, String>();

                Bitmap bitmap= BitmapUtil.decodeBitmapFromPath(photo_path2,600,600);
                RGBLuminanceSource source = new RGBLuminanceSource(bitmap);
                BinaryBitmap bitmap1 = new BinaryBitmap(new HybridBinarizer(source));
                QRCodeReader reader = new QRCodeReader();
                MultiFormatReader multiFormatReader=new MultiFormatReader();
                try {
                    Message msg= Message.obtain();
                    msg.what=PhotoScanHandler.PHOTODECODEOK;
                    msg.obj = multiFormatReader.decode(bitmap1, hints);
                    photoScanHandler.sendMessage(msg);
                } catch (Exception e) {
                    Message msg= Message.obtain();
                    msg.what=PhotoScanHandler.PHOTODECODEERROR;
                    msg.obj=new Exception("图片有误,或者图片模糊!");
                    photoScanHandler.sendMessage(msg);
                }
            }
        }).start();
    }
    /**
     * 扫描一次后,如需再次扫描,请调用这个方法
     */
    public void reScan(){
        if(handler!=null){
            handler.sendEmptyMessage(R.id.restart_preview);
        }
    }
    public boolean isScanning(){
        if(handler!=null){
            return handler.isScanning();
        }
        return false;
    }

}

代码挺详细的就不再细说了。

Demo地址:https://download.csdn.net/download/silence_sep/10567267

猜你喜欢

转载自blog.csdn.net/Silence_Sep/article/details/81233333