0

My project uses CameraSource for detecting QR codes. The code of my CameraSource is based on the official one (slightly modified for adding some log and stuff like that). Actually the app is composed by 2 activites (I'm simplifying the behaviour):

  1. First activity (FORM PRODUCT IN) has some info text and a frame with camera preview. When a barcode is detected, it passes the code to the second activity
  2. Second activity (PRODUCT IN) is similiar to the first one but scan different barcodes (it must be a separate activity)

My CameraSource implementation is instantiated in the onCreate, and has its callback, in particular "surfaceCreated" and "surfaceDestroyed":

@Override
        public void surfaceDestroyed(SurfaceHolder holder) {
            Log.e(TAG, "CAMERA SURFACE DESTROYING VIEW");
            cameraSource.stop();
        }

@Override
        public void surfaceCreated(SurfaceHolder holder) {

            Log.e(TAG, "CAMERA SURFACE CREATED");

            try {
                cameraSource.start(cameraView.getHolder());
                //getCameraFocusInfo();
            } catch (IOException ie) {
                Log.e(TAG, ie.getMessage());
            }
        }

The problem is that on emulator the second activity crashes because it cannot open the camera. On real device I see slightly different log (but without crash).

Logs first activity (same for both):

E/FORM PRODUCT IN: On Create

E/FORM PRODUCT IN: On Resume

E/FORM PRODUCT IN: CAMERA SURFACE CREATED

E/FORM PRODUCT IN: CAMERA SURFACE CHANGED: width 768 height: 1134

Barcode is detected, then second log (on Genymotion) and app crash:

E/FORM PRODUCT IN: On Pause

E/PRODUCT IN: On Create

E/PRODUCT IN: On Resume

E/PRODUCT IN: CAMERA SURFACE CREATED

E/AndroidRuntime: FATAL EXCEPTION: main

             Process: it.example, PID: 15231

             java.lang.RuntimeException: Fail to connect to camera service

Second log on device (app doesn't crash but reports errors):

E/FORM PRODUCT IN: On Pause

E/PRODUCT IN: On Create

E/PRODUCT IN: On Resume

E/PRODUCT IN: CAMERA SURFACE CREATED

E/PRODUCT IN: CAMERA SURFACE CHANGED: width 720 height: 1232

E/Camera: Error 2

E/FORM PRODUCT IN: CAMERA SURFACE DESTROYING VIEW

E/OpenCameraSource: Failed to clear camera preview: java.io.IOException: setPreviewTexture failed

E/FORM PRODUCT IN: on Stop

Nevermind if app crashes on emulator, but the logs on device tell me there is a problem when I try to open a camera because it was not yet released.

The OnCreate and OnResume of second activity (and creation of the relative new camera surface view) are called before the onStop of the first one, and the surface detroying call (the responsable to release the camera) is called after the second activity is started.

Is there a proper way to handle correctly the use of camera on 2 separate activities?

Community
  • 1
  • 1
Scognito
  • 152
  • 1
  • 13

1 Answers1

0

Actually I solved finding the correct answer here to a similiar question. Explaining here for future reference.

To force the surfaceView (that contains the camera preview) to be destroyed, just change the visibility (View.GONE in my case).

Since the onPause of first activity is called always before the onCreate of the second one, the solution is to make the view invisible on onPause (thus calling the onSurfaceDestroyed which stops the camera) and then make it visible again on the onResume.

@Override
protected void onPause() {

    super.onPause();
    cameraView.setVisibility(View.GONE);
    Log.e(TAG, "On Pause");
}

@Override
protected void onResume() {

    super.onResume();
    cameraView.setVisibility(View.VISIBLE);
    Log.e(TAG, "On Resume");
}
Community
  • 1
  • 1
Scognito
  • 152
  • 1
  • 13