dlazaro66 / QRCodeReaderView

Modification of ZXING Barcode Scanner project for easy Android QR-Code detection and AR purposes
1.9k stars 491 forks source link

'Fail to connect to camera service' when camera class initialize #129

Closed zodani closed 7 years ago

zodani commented 7 years ago

Hello, I faced RuntimeException . when i'm using like below.

qrdeCoderView = new QRCodeReaderView(this);

Fatal Exception: java.lang.RuntimeException: Fail to connect to camera service at android.hardware.Camera.(Camera.java:519) at android.hardware.Camera.open(Camera.java:364) at com.google.zxing.client.android.camera.open.OpenCameraInterface.open(OpenCameraInterface.java:76) at com.google.zxing.client.android.camera.CameraManager.openDriver(CameraManager.java:104) at com.dlazaro66.qrcodereaderview.QRCodeReaderView.surfaceCreated(QRCodeReaderView.java:213) at android.view.SurfaceView.updateWindow(SurfaceView.java:656) at android.view.SurfaceView$3.onPreDraw(SurfaceView.java:172) at android.view.ViewTreeObserver.dispatchOnPreDraw(ViewTreeObserver.java:1013) at android.view.ViewRootImpl.performTraversals(ViewRootImpl.java:2542) at android.view.ViewRootImpl.doTraversal(ViewRootImpl.java:1537) at android.view.ViewRootImpl$TraversalRunnable.run(ViewRootImpl.java:7183) at android.view.Choreographer$CallbackRecord.run(Choreographer.java:959) at android.view.Choreographer.doCallbacks(Choreographer.java:734) at android.view.Choreographer.doFrame(Choreographer.java:670) at android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:945) at android.os.Handler.handleCallback(Handler.java:751) at android.os.Handler.dispatchMessage(Handler.java:95) at android.os.Looper.loop(Looper.java:154) at android.app.ActivityThread.main(ActivityThread.java:6776) at java.lang.reflect.Method.invoke(Method.java) at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1496) at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1386)

I figure out mCameraManager.openDriver in QRCodeReaderView.surfaceCreated can throw RuntimeException. there are only catch the IOException without RuntimeException. so, need to add catch Exception or IOException.

catch (Exception e) {
       Log.w(TAG, "Can not openDriver: " + e.getMessage());
       mCameraManager.closeDriver();    
}

or

catch (RuntimeException e) {
       Log.w(TAG, "Can not openDriver: " + e.getMessage());
       mCameraManager.closeDriver();    
}
darylsze commented 7 years ago

may i know if author is going to fix this?

gpt3ch commented 7 years ago

getting same error someone please help

Vla2yslav commented 7 years ago

For fix this error use this code: if (ContextCompat.checkSelfPermission(getApplicationContext(), android.Manifest.permission.CAMERA) != PackageManager.PERMISSION_GRANTED) { ActivityCompat.requestPermissions(this, new String[]{android.Manifest.permission.CAMERA}, 50); }

darylsze commented 7 years ago

Thanks for your code. Its accurate to fix the problem. Some users disabled camera service permission on Android 6.0+ devices while my app do not support runtime permission, so the qrcodeview throw error out.

saeedmozaffari commented 7 years ago

i have same error,


Fatal Exception: java.lang.RuntimeException
Fail to connect to camera service
--
  | android.hardware.Camera.native_setup (Camera.java)
  | android.hardware.Camera. (Camera.java)
  | android.hardware.Camera.open (Camera.java:356)
  | com.google.zxing.client.android.camera.open.OpenCameraInterface.open (OpenCameraInterface.java:76)
  | com.google.zxing.client.android.camera.CameraManager.openDriver (CameraManager.java:104)
  | **com.dlazaro66.qrcodereaderview.QRCodeReaderView.surfaceCreated (QRCodeReaderView.java:213)**
  | android.view.SurfaceView.updateWindow (SurfaceView.java:600)
  | android.view.SurfaceView.access$000 (SurfaceView.java:94)
  | android.view.SurfaceView$3.onPreDraw (SurfaceView.java:183)
  | android.view.ViewTreeObserver.dispatchOnPreDraw (ViewTreeObserver.java:895)
  | android.view.ViewRootImpl.performTraversals (ViewRootImpl.java:2193)
  | android.view.ViewRootImpl.doTraversal (ViewRootImpl.java:1251)
  | android.view.ViewRootImpl$TraversalRunnable.run (ViewRootImpl.java:6557)
  | android.view.Choreographer$CallbackRecord.run (Choreographer.java:813)
  | android.view.Choreographer.doCallbacks (Choreographer.java:613)
  | android.view.Choreographer.doFrame (Choreographer.java:583)
  | android.view.Choreographer$FrameDisplayEventReceiver.run (Choreographer.java:799)
  | android.os.Handler.handleCallback (Handler.java:733)
  | android.os.Handler.dispatchMessage (Handler.java:95)
  | android.os.Looper.loop (Looper.java:146)
  | android.app.ActivityThread.main (ActivityThread.java:5653)
  | java.lang.reflect.Method.invokeNative (Method.java)
  | java.lang.reflect.Method.invoke (Method.java:515)
  | com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run (ZygoteInit.java:1291)
  | com.android.internal.os.ZygoteInit.main (ZygoteInit.java:1107)
  | dalvik.system.NativeStart.main (NativeStart.java)

also i checked camera permission.

This error has not happened to me, but my app users got this error. fabric info --> devices samsung -> 28% Xiaomi -> 24% HUAWEI -> 15% Sony -> 9% Other…

fabric info --> android versions version 4 -> 34% version 5 -> 30% version 7 -> 24% version 6 -> 12%

Piashsarker commented 7 years ago

Avoid using Utils.log(" ") ; It's because of permission issue , If you are using below XML in your main_layout.xml file than replace it with below instruction .

Add A FrameLayout instead of direct QRCodeReaderView .

  <FrameLayout
                    android:id="@+id/qr_reader_view_frame"
                    android:layout_width="match_parent"
                    android:layout_height="250dp">
</FrameLayout>

In a Extra XML file add below code suppose qr_reader_view.xml =>

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <com.dlazaro66.qrcodereaderview.QRCodeReaderView
        android:id="@+id/qr_reader_view"
        android:layout_width="match_parent"
        android:layout_height="match_parent" />

</LinearLayout>

Now Check for the permission in your activity or fragment , I did it in fragment so => below code will work in fragment but the logic are same. in onCreateView() add below permission check :

    if (ActivityCompat.checkSelfPermission(getContext(), Manifest.permission.CAMERA) == PackageManager.PERMISSION_GRANTED) {
                initQRCodeReaderView();
                Utils.log("Camera Permission Granted . ");

            } else {
                requestCameraPermission();
                Utils.log(" Requesting Camera Permission ");

            }
  private void requestCameraPermission() {

        if (ActivityCompat.shouldShowRequestPermissionRationale(getActivity(), Manifest.permission.CAMERA)) {
            Snackbar.make(getActivity().findViewById(android.R.id.content), "Camera access is required for QR code scanner.",
                    Snackbar.LENGTH_INDEFINITE).setAction("OK", new View.OnClickListener() {
                @Override public void onClick(View view) {
                    requestPermissions( new String[] {Manifest.permission.CAMERA}, MY_PERMISSION_REQUEST_CAMERA);
                }
            }).show();
        } else{
            Snackbar.make(getActivity().findViewById(android.R.id.content), "Requesting camera permission. Required for QR code scanner.",
                    Snackbar.LENGTH_SHORT).show();
            requestPermissions(new String[] {Manifest.permission.CAMERA}, MY_PERMISSION_REQUEST_CAMERA);
        }

    }

  @Override public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions,
                                                     @NonNull int[] grantResults) {
        if (requestCode != MY_PERMISSION_REQUEST_CAMERA) {
            return;
        }

        if (grantResults.length == 1 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
            Snackbar.make(getActivity().findViewById(android.R.id.content), "Camera permission was granted. Now you can scan QR code", Snackbar.LENGTH_SHORT).show();
            initQRCodeReaderView();
        } else {
            Snackbar.make(getActivity().findViewById(android.R.id.content), "Camera permission request was denied, Can't able to start QR scan", Snackbar.LENGTH_SHORT)
                    .show();
        }
    }

    public void initQRCodeReaderView(){

        Utils.log("Init QR Code Reader Running .");
        View qrView =getActivity().getLayoutInflater().inflate(R.layout.qr_reader_view,qrReaderViewFrame,true);
        qrCodeReaderView = qrView.findViewById(R.id.qr_reader_view);
        qrCodeReaderView.setOnQRCodeReadListener(QRScannerFragment.this);
        // Use this function to enable/disable decoding
        qrCodeReaderView.setQRDecodingEnabled(true);
        // Use this function to change the autofocus interval (default is 5 secs)
        qrCodeReaderView.setAutofocusInterval(2000L);

        // Use this function to enable/disable Torch
        qrCodeReaderView.setTorchEnabled(true);

        // Use this function to set front camera preview
        qrCodeReaderView.setFrontCamera();

        // Use this function to set back camera preview
        qrCodeReaderView.setBackCamera();
    }

Hope this will help , Thanks . And Thanks @dlazaro66 for the library man , Just change the view aspect when using custom height and weight in xml .

datnt1987 commented 7 years ago

I have issue "Fail to connect to camera service" with my fragment. So I've already request permission for camera but when I come to my fragment, this issue occur then show dialog permission allow confirmation. I put the request permission code in fragment onResume() function. Please help me.

my fragment xml file <?xml version="1.0" encoding="utf-8"?> <FrameLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent">

<com.dlazaro66.qrcodereaderview.QRCodeReaderView
  android:id="@+id/qrdecoderview"
  android:layout_width="match_parent"
  android:layout_height="match_parent"
  />

<TextView
    android:id="@+id/tvErrorMessage"
    style="@style/TextView.Title"
    android:layout_width="@dimen/rect_scan_size"
    android:layout_height="wrap_content"
    android:layout_gravity="center"
    android:layout_marginBottom="40dp"
    android:gravity="center"
    android:paddingLeft="8dp"
    android:paddingRight="8dp"
    android:singleLine="false"
    android:textColor="@color/white"/>

<TextView
    style="@style/TextView.Title"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_gravity="center"
    android:layout_marginTop="@dimen/margin_top_label_qr_code"
    android:text="@string/label_qr_to_pay"
    android:textColor="@color/white"/>

<TextView
    style="@style/TextView.Title"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_gravity="center"
    android:layout_marginTop="@dimen/margin_top_title_qr_code"
    android:text="@string/scan.qr.code"
    android:textColor="@color/white"
    android:textStyle="bold"/>

Piashsarker commented 7 years ago

@datnt1987 please check my answer , And remember that don't put

 <com.dlazaro66.qrcodereaderview.QRCodeReaderView
        android:id="@+id/qr_reader_view"
        android:layout_width="match_parent"
        android:layout_height="match_parent" />

above code in your fragment xml directly . Try to use it after getting the permission , Instead of this use a <FrameLayout/>and Inflate the view when get the permission . Hope to hear from you . If you face further problem copy and paste your fragment Java and XML code.

datnt1987 commented 7 years ago

Dear @Piashsarker , I did it follow your suggest. Thanks so much

Piashsarker commented 7 years ago

Welcome @datnt1987 , Happy Coding :) .

dlazaro66 commented 7 years ago

I'll close this issue as solved. You should have camera permissions before starting the camera (or putting it in a layout) Reopen if you have more issues. Thanks for the answers @Piashsarker

77rahulroy commented 6 years ago

Thanks Bro. You solved my problem. Thank you so much. @Vla2yslav