New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

An error occurred while connecting to camera: 0 #193

Open
syedjamal opened this Issue Apr 20, 2016 · 5 comments

Comments

Projects
None yet
4 participants
@syedjamal

syedjamal commented Apr 20, 2016

In my application I am using Zxing bar code scanner. I have set my bar code scanner to scan in both modes(landscape and portrait). it is working fine. but sometimes when I rotate my phone continuously from portrait to landscape vice versa it is showing the empty white screen in bar code scanning screen. I have checked the Logcat, it is showing this message W/CameraBase: An error occurred while connecting to camera: 0

My scanner Activity

public class SimpleScanner extends BaseScannerActivity implements ZXingScannerView.ResultHandler {


    private ZXingScannerView mScannerView;

    String content;

    @Override
    public void onCreate(Bundle state) {
        super.onCreate(state);
        setContentView(R.layout.activity_simple_scanner);
        setupToolbar();
        flashImageView = (ImageView) findViewById(R.id.imageview_flash);

        ViewGroup contentFrame = (ViewGroup) findViewById(R.id.content_frame);
        mScannerView = new ZXingScannerView(this) {
            @Override
            protected IViewFinder createViewFinderView(Context context) {
                return new CustomViewFinderView(context);
            }
        };
        setupFormats();
        contentFrame.addView(mScannerView);       

    }

    @Override
    public void onResume() {
        super.onResume();
        mScannerView.setResultHandler(this);
        mScannerView.startCamera();
    }

    @Override
    public void onPause() {
        super.onPause();
        mScannerView.stopCamera();
    }

    @Override
    public void handleResult(Result rawResult) {

        if(!rawResult.getBarcodeFormat().toString().equalsIgnoreCase("CODE_128") && !rawResult.getBarcodeFormat().toString().equalsIgnoreCase("CODE_93")){
            Toast.makeText(this, "Incorrect Barcode Format", Toast.LENGTH_SHORT).show();

            Handler handler = new Handler();
            handler.postDelayed(new Runnable() {
                @Override
                public void run() {
                    mScannerView.resumeCameraPreview(SimpleScanner.this);
                }
            }, 2000);

            return;
        }

        content = rawResult.getText();   

        Intent intent=new Intent();
        intent.putExtra("scannedText",rawResult.getText());
        setResult(2,intent);
        finish();    


        // Note:
        // * Wait 2 seconds to resume the preview.
        // * On older devices continuously stopping and resuming camera preview can result in freezing the app.
        // * I don't know why this is the case but I don't have the time to figure out.
        Handler handler = new Handler();
        handler.postDelayed(new Runnable() {
            @Override
            public void run() {
                mScannerView.resumeCameraPreview(SimpleScanner.this);
            }
        }, 2000);
    }
    public void setupFormats() {
        List<BarcodeFormat> formats = new ArrayList<BarcodeFormat>();


        formats.add(ZXingScannerView.ALL_FORMATS.get(6));
        formats.add(ZXingScannerView.ALL_FORMATS.get(7));

        if(mScannerView != null) {
            mScannerView.setFormats(formats);
        }
    }

    private static class CustomViewFinderView extends ViewFinderView {
        public static final String TRADE_MARK_TEXT = "";
        public static final int TRADE_MARK_TEXT_SIZE_SP = 40;
        public final Paint PAINT = new Paint();

        public CustomViewFinderView(Context context) {
            super(context);
            init();
        }

        public CustomViewFinderView(Context context, AttributeSet attrs) {
            super(context, attrs);
            init();
        }

        private void init() {
            PAINT.setColor(Color.WHITE);
            PAINT.setAntiAlias(true);
            float textPixelSize = TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_SP,
                    TRADE_MARK_TEXT_SIZE_SP, getResources().getDisplayMetrics());
            PAINT.setTextSize(textPixelSize);
        }

        @Override
        public void onDraw(Canvas canvas) {
            super.onDraw(canvas);
            drawTradeMark(canvas);
        }

        private void drawTradeMark(Canvas canvas) {
            Rect framingRect = getFramingRect();
            float tradeMarkTop;
            float tradeMarkLeft;
            if (framingRect != null) {
                tradeMarkTop = framingRect.bottom + PAINT.getTextSize() + 10;
                tradeMarkLeft = framingRect.left;
            } else {
                tradeMarkTop = 10;
                tradeMarkLeft = canvas.getHeight() - PAINT.getTextSize() - 10;
            }
            canvas.drawText(TRADE_MARK_TEXT, tradeMarkLeft, tradeMarkTop, PAINT);
        }
    }

}
@Timmmm

This comment has been minimized.

Contributor

Timmmm commented Jun 24, 2016

I also get this on a Nexus 5 (Android 6.0), but not an Xperia Z3C (also Android 6.0). The only thing I've found is this StackOverflow question.

@Timmmm

This comment has been minimized.

Contributor

Timmmm commented Jun 24, 2016

I traced this problem to an EACCESS error in new Camera(0) which runs throw new RuntimeException("Fail to connect to camera service"); (that exception is ignored by this library).

Ah I just remembered that I haven't requested permission to access the camera! I think it worked on the Z3C because a previous version of my app did ask.

@Timmmm

This comment has been minimized.

Contributor

Timmmm commented Jun 24, 2016

Yep that was it. Try this code:

public class QRActivity extends Activity implements ZBarScannerView.ResultHandler
{
    private ZBarScannerView mScannerView;

    public static final int PERMISSION_REQUEST_CAMERA = 1;

    @SuppressLint("NewApi")
    @Override
    public void onCreate(Bundle savedInstanceState)
    {
        super.onCreate(savedInstanceState);

        mScannerView = new ZBarScannerView(this);    // Programmatically initialize the scanner view
        setContentView(mScannerView);                // Set the scanner view as the content view

        // Request permission. This does it asynchronously so we have to wait for onRequestPermissionResult before trying to open the camera.
        if (!haveCameraPermission())
            requestPermissions(new String[]{Manifest.permission.CAMERA}, PERMISSION_REQUEST_CAMERA);
    }

    private boolean haveCameraPermission()
    {
        if (Build.VERSION.SDK_INT < 23)
            return true;
        return checkSelfPermission(Manifest.permission.CAMERA) == PackageManager.PERMISSION_GRANTED;
    }

    @Override
    public void onRequestPermissionsResult(int requestCode, String permissions[], int[] grantResults)
    {
        // This is because the dialog was cancelled when we recreated the activity.
        if (permissions.length == 0 || grantResults.length == 0)
            return;

        switch (requestCode)
        {
            case PERMISSION_REQUEST_CAMERA:
            {
                if (grantResults[0] == PackageManager.PERMISSION_GRANTED)
                {
                    startCamera();
                }
                else
                {
                    finish();
                }
            }
            break;
        }
    }

    public void startCamera()
    {
        mScannerView.setResultHandler(this); // Register ourselves as a handler for scan results.
        mScannerView.startCamera();          // Start camera on resume
    }

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

    @Override
    public void onResume()
    {
        super.onResume();
        startCamera();
    }

    @Override
    public void onPause()
    {
        super.onPause();
        stopCamera();
    }

    @Override
    public void handleResult(Result rawResult)
    {
        // ...
    }
}

I can't promise it will work in all cases of Android's crazy mega-state machine but it works for rotation as far as I can tell.

@codepainters

This comment has been minimized.

codepainters commented Feb 10, 2017

I faced the very same problem with version 1.9. It seems to be a race condition between camera opening and closing.

I've added a bit of ad hoc logging, and it seems that sometimes after a rotation a call to CameraUtils .getCameraInstance() (from CameraHandlerThread) happens before a call to BarcodeScannerView.stopCamera() (which I call from main thread), and returns null (due to camera being busy).

Should this happen, it never releases the camera for some reason and keeps failing afterwards.

Shouldn't camera open/close be performed by the same thread (or at least synchronised)?

@chilat

This comment has been minimized.

chilat commented Jul 3, 2017

I had this similar problem and I could not access the camera using the default app. Solved it by restarting the phone.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment