method called after release() exception unable to resume with android camera

后端 未结 9 601
無奈伤痛
無奈伤痛 2020-11-29 00:14

While developing a camera app I\'ve encountered an exception that only happened when I switch to other app (onPause() for my app).

01-15 17:22:1         


        
相关标签:
9条回答
  • 2020-11-29 00:38

    To Resume correctly, you need to do this:

    @Override
    public void onResume() {
        super.onResume();  
    
        // Get the Camera instance as the activity achieves full user focus
        if (mCamera == null) {
            initializeCamera(); // Local method to handle camera initialization
        }
    }
    
    
    
    protected void initializeCamera(){
        // Get an instance of Camera Object
        mCamera = getCameraInstance();
    
       // create a basic camera preview class that can be included in a View layout.
        mPreview=new CameraPreview(this,mCamera);
    
        //add your preview class to the FrameLayout element.
        preview.addView(mPreview);
    
       //Trigger capturing an image by calling the Camera.takePicture() method.
        captureButton.setOnClickListener(
                new View.OnClickListener() {
                    @Override
                    public void onClick(View v) {
                        // get an image from the camera
                        mCamera.takePicture(null, null, mPicture);
                    }
                }
            );
    }
    

    And also just to remind that in oncreate() do nothing except defining FrameLayout preview and Button captureButton.

    0 讨论(0)
  • 2020-11-29 00:42

    I've got the same problem. mCamera.setPreviewCallback(null); didn't help. In my activity I've added this to releaseCamera:

    mPreview.getHolder().removeCallback(mPreview);
    

    and it works now.

    0 讨论(0)
  • 2020-11-29 00:48
    @Override public void surfaceDestroyed(SurfaceHolder surfaceHolder) {
    
        this.getHolder().removeCallback(this);
        mCamera.stopPreview();
        mCamera.release();
        mCamera = null;
      Log.e("surfaceDestroyed", "surfaceDestroyed");
    
    }
    

    And re initialize the camera in on Resume function.

    0 讨论(0)
  • 2020-11-29 00:48

    I have put

    mPreview.getHolder().removeCallback(mPreview);  
    

    between.

    mCamera.setPreviewCallback(null);
    

    and

    mCamera.release();
    

    and it worked for me.

     @Override
                protected void onPause() {
                    super.onPause();
    
                    this.saveTextEdits();
                    try {
                        mCamera.stopPreview();
                        mCamera.setPreviewCallback(null);
                        **mPreview.getHolder().removeCallback(mPreview);**
                        mCamera.release();
                        mCamera = null;
                    }catch (Exception e){
    
                    }
                }
    
    0 讨论(0)
  • 2020-11-29 00:52

    @ookami.kb solution worked for me too, as well as @srunni commented.

    public void onPause() {
        super.onPause();
    
        if (mCamera != null) {
            mCamera.setPreviewCallback(null);
            mPreview.getHolder().removeCallback(mPreview);
            mCamera.release();
        }
    }
    

    I removed onDestroy method too.

    0 讨论(0)
  • 2020-11-29 00:55

    Adding to okambi's answer.

    This is the function messing everything up when you resume:

     public void surfaceCreated(SurfaceHolder holder) {
            // The Surface has been created, now tell the camera where to draw the preview.
            try {
                mCamera.setPreviewDisplay(holder);
                mCamera.startPreview();
            } catch (IOException e) {
                Log.d(TAG, "Error setting camera preview: " + e.getMessage());
            }
        }
    

    The try{} is not catching the exception being thrown. Namely that mCamera doesn't exist, and then when it tries to call setPreviewDisplay(holder), there is a crash.

    So by removing the callback, this surfaceCreated doesn't get called and avoids the crash.

    This is VERY POORLY DOCUMENTED by Google.

    0 讨论(0)
提交回复
热议问题