ZBarScanner抛出c​​amera.release()被调用后正在使用相机

时间:2017-03-03 07:59:46

标签: android android-camera qr-code zbar

我正在尝试使用ZBar Scanner创建条形码扫描程序,但在开发过程中我遇到了错误camera is being used after camera.release() was called

错误转到课程camera.setOneShotPreviewCallback(this);

中的这一行ZBarScannerView.java

我已尝试过在stackoverflow上提出的所有类似问题,但仍然是错误。

请建议我如何解决这个问题。

这是我的代码:

ZBarScannerView.java

public class ZBarScannerView extends BarcodeScannerView {
    private static final String TAG = "ZBarScannerView";
    private ImageScanner mScanner;
    private List<BarcodeFormat> mFormats;
    private ZBarScannerView.ResultHandler mResultHandler;

    private boolean switcher = true;

    public ZBarScannerView(Context context) {
        super(context);
        this.setupScanner();
    }

    public ZBarScannerView(Context context, AttributeSet attributeSet) {
        super(context, attributeSet);
        this.setupScanner();
    }

    public void setFormats(List<BarcodeFormat> formats) {
        this.mFormats = formats;
        this.setupScanner();
    }

    public void setResultHandler(ZBarScannerView.ResultHandler resultHandler) {
        this.mResultHandler = resultHandler;
    }

    public Collection<BarcodeFormat> getFormats() {
        return this.mFormats == null ? BarcodeFormat.ALL_FORMATS : this.mFormats;
    }

    public void setupScanner() {
        this.mScanner = new ImageScanner();
        this.mScanner.setConfig(0, 256, 3);
        this.mScanner.setConfig(0, 257, 3);
        this.mScanner.setConfig(0, 0, 0);
        Iterator i$ = this.getFormats().iterator();

        while (i$.hasNext()) {
            BarcodeFormat format = (BarcodeFormat) i$.next();
            this.mScanner.setConfig(format.getId(), 0, 1);
        }

    }

    public void onPreviewFrame(byte[] data, Camera camera) {
        Camera.Parameters parameters = camera.getParameters();
        Camera.Size size = parameters.getPreviewSize();
        int width = size.width;
        int height = size.height;

        switcher = !switcher;


        if(DisplayUtils.getScreenOrientation(getContext()) == Configuration.ORIENTATION_PORTRAIT) {
            byte[] rotatedData = new byte[data.length];
            for (int y = 0; y < height; y++) {
                for (int x = 0; x < width; x++)
                    rotatedData[x * height + height - y - 1] = data[x + y * width];
            }
            int tmp = width;
            width = height;
            height = tmp;
            data = rotatedData;
        }

        Image barcode = new Image(width, height, "Y800");

        if (switcher) {
            int[] pixels = applyGrayScale(data,width,height);
            Bitmap bm = Bitmap.createBitmap(pixels,width,height, Bitmap.Config.ARGB_8888);
            bm = MyUtils.createInvertedBitmap(bm, width, height);

            pixels = new int[width*height];
            bm.getPixels(pixels, 0, bm.getWidth(), 0, 0, bm.getWidth(), bm.getHeight());

            encodeYUV420SP(data, pixels, bm.getWidth(), bm.getHeight());
        }


        barcode.setData(data);

        int result = mScanner.scanImage(barcode);

        if (result != 0) {
            stopCamera();
            if(mResultHandler != null) {
                SymbolSet syms = mScanner.getResults();
                final Result rawResult = new Result();
                for (Symbol sym : syms) {
                    String symData = sym.getData();
                    if (!TextUtils.isEmpty(symData)) {
                        rawResult.setContents(symData);
                        rawResult.setBarcodeFormat(BarcodeFormat.getFormatById(sym.getType()));
                        break;
                    }
                }

                Handler var17 = new Handler(Looper.getMainLooper());
                var17.post(new Runnable() {
                    public void run() {
                        ZBarScannerView.ResultHandler tmpResultHandler = ZBarScannerView.this.mResultHandler;
                        ZBarScannerView.this.mResultHandler = null;
                        ZBarScannerView.this.stopCameraPreview();
                        if (tmpResultHandler != null) {
                            tmpResultHandler.handleResult(rawResult);
                        }

                    }
                });
            }
        } else {
            camera.setOneShotPreviewCallback(this); //this always give me error camera is being used after camera.release() was called
        }
    }


    void encodeYUV420SP(byte[] yuv420sp, int[] argb, int width, int height) {
        final int frameSize = width * height;

        int yIndex = 0;
        int uvIndex = frameSize;

        int a, R, G, B, Y, U, V;
        int index = 0;
        for (int j = 0; j < height; j++) {
            for (int i = 0; i < width; i++) {

                a = (argb[index] & 0xff000000) >> 24; // a is not used obviously
                R = (argb[index] & 0xff0000) >> 16;
                G = (argb[index] & 0xff00) >> 8;
                B = (argb[index] & 0xff) >> 0;

                // well known RGB to YUV algorithm
                Y = ((66 * R + 129 * G + 25 * B + 128) >> 8) + 16;
                U = ((-38 * R - 74 * G + 112 * B + 128) >> 8) + 128;
                V = ((112 * R - 94 * G - 18 * B + 128) >> 8) + 128;

                // NV21 has a plane of Y and interleaved planes of VU each sampled by a factor of 2
                //    meaning for every 4 Y pixels there are 1 V and 1 U.  Note the sampling is every other
                //    pixel AND every other scanline.
                yuv420sp[yIndex++] = (byte) ((Y < 0) ? 0 : ((Y > 255) ? 255 : Y));
                if (j % 2 == 0 && index % 2 == 0) {
                    yuv420sp[uvIndex++] = (byte) ((V < 0) ? 0 : ((V > 255) ? 255 : V));
                    yuv420sp[uvIndex++] = (byte) ((U < 0) ? 0 : ((U > 255) ? 255 : U));
                }

                index++;
            }
        }
    }

    public void resumeCameraPreview(ZBarScannerView.ResultHandler resultHandler) {
        this.mResultHandler = resultHandler;
        super.resumeCameraPreview();
    }

    static {
        System.loadLibrary("iconv");
    }

    public interface ResultHandler {
        void handleResult(Result var1);
    }


}

MainActivity.java

public class MainActivity extends ActivityMyApps implements ZBarScannerView.ResultHandler, OnClickListener, OnPermissionCallback {

    protected void onCreate(Bundle savedInstanceState) {
    }

    @Override
    protected void initView() {
        super.initView();

        mScannerView = new ZBarScannerView(this);
        setupFormats();
        cameraFrame.addView(mScannerView);

    }


    @Override
    public void onSaveInstanceState(Bundle outState) {
        super.onSaveInstanceState(outState);
        outState.putBoolean(FLASH_STATE, mFlash);
        outState.putBoolean(AUTO_FOCUS_STATE, mAutoFocus);
        outState.putIntegerArrayList(SELECTED_FORMATS, mSelectedIndices);
        outState.putInt(CAMERA_ID, mCameraId);
    }


    @Override
    protected void onResume() {
        super.onResume();
        cameraView.handleMessage(new Message());
        Toast.makeText(this, "OnResume", Toast.LENGTH_SHORT).show();

    }

    public void stopCamera() {
        mScannerView.stopCamera();
    }

    @Override
    protected void onPause() {
        super.onPause();
        stopCamera();
//        closeMessageDialog();
//        closeFormatsDialog();
        Toast.makeText(this, "OnPause", Toast.LENGTH_SHORT).show();
    }

    @Override
    protected void menuOpen() {
        super.menuOpen();
        stopCamera();
        cameraResume();
    }

    @Override
    protected void onDestroy() {
        mScannerView.stopCamera();
        super.onDestroy();
        Toast.makeText(this, "OnDestroy", Toast.LENGTH_SHORT).show();
    }

    @Override
    protected void menuClosed() {
        super.menuClosed();
        if (isCameraActive()) {
            cameraResume();
        } else {
            isCameraActive = false;
        }
    }
}

我将不胜感激任何建议。谢谢

0 个答案:

没有答案