在Camera.release被称为android之后正在使用相机

时间:2016-07-02 12:04:21

标签: android

我知道有一些类似的主题与此相关,但我无法解决我的问题。无论如何,我正在尝试使用" flash"制作一些前置摄像头。在Camera.release时,我在整个活动中只调用surfaceDestroyed()一次。所以这是我的MainActivity:

@SuppressWarnings("deprecation")
public class MainActivity extends AppCompatActivity {
    private Camera mCamera = null;
    private CameraPreview mCameraView = null;
    private int cameraId = 0;

    private void addView() {
        if (!getPackageManager()
                .hasSystemFeature(PackageManager.FEATURE_CAMERA)) {
            Toast.makeText(this, "No camera on this device", Toast.LENGTH_LONG)
                    .show();
        } else {
            cameraId = findFrontFacingCamera();
            if (cameraId < 0) {
                Toast.makeText(this, "No front facing camera found.",
                        Toast.LENGTH_LONG).show();
            } else {
                try {
                    mCamera = Camera.open(cameraId);
                } catch (Exception e) {
                    Log.d("ERROR", "Failed to get camera: " + e.getMessage());
                }
            }
        }
        if (mCamera != null) {
            mCameraView = new CameraPreview(this, mCamera);//create a SurfaceView to show camera data
            FrameLayout camera_view = (FrameLayout) findViewById(R.id.camera_view);
            camera_view.addView(mCameraView);//add the SurfaceView to the layout
        }
    }

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        addView();
        ImageButton imgCapture = (ImageButton) findViewById(R.id.imgCapture);
        imgCapture.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                WindowManager.LayoutParams layout = getWindow().getAttributes();
                layout.screenBrightness = 1F;
                getWindow().setAttributes(layout);
                setContentView(R.layout.whitescreen);
                new CountDownTimer(3000, 1000) {
                    public void onTick(long millisUntilFinished) {
                    }
                    public void onFinish() {
                        if (CameraPreview.safeToTakePicture) {
                            CameraPreview.safeToTakePicture = false;
                            mCamera.takePicture(null, null,
                                    new PhotoHandler(getApplicationContext()));
                        }
                            setContentView(R.layout.activity_main);
                        addView();
                    }
                }.start();
            }
        });
    }

    private int findFrontFacingCamera() {
        int cameraId = -1;
        // Search for the front facing camera
        int numberOfCameras = Camera.getNumberOfCameras();
        for (int i = 0; i < numberOfCameras; i++) {
            Camera.CameraInfo info = new Camera.CameraInfo();
            Camera.getCameraInfo(i, info);
            if (info.facing == Camera.CameraInfo.CAMERA_FACING_FRONT) {
                Log.d("Camera", "Camera found");
                cameraId = i;
                break;
            }
        }
        return cameraId;
    }

}

按下拍摄按钮时,我将布局切换为空白布局(白色布局),等待3秒钟拍照,然后再次添加相机视图,这是我的CameraPreview类:

@SuppressWarnings("deprecation")
public class CameraPreview extends SurfaceView implements SurfaceHolder.Callback {
    private SurfaceHolder mHolder;
    private Camera mCamera;
    public static boolean safeToTakePicture = false;

    public CameraPreview(Context context, Camera camera) {
        super(context);
        mCamera = camera;
        mCamera.setDisplayOrientation(90);
        mHolder = getHolder();
        mHolder.addCallback(this);
        mHolder.setType(SurfaceHolder.SURFACE_TYPE_NORMAL);
    }

    @Override
    public void surfaceCreated(SurfaceHolder surfaceHolder) {
        try {
            mCamera.setPreviewDisplay(surfaceHolder);
            mCamera.startPreview();
        } catch (IOException e) {
            Log.d("ERROR", "Camera error on surfaceCreated " + e.getMessage());
        }
    }

    @Override
    public void surfaceChanged(SurfaceHolder surfaceHolder, int i, int i2, int i3) {
        if (mHolder.getSurface() == null)
            return;
        try {
            mCamera.stopPreview();
        } catch (Exception e) {
            Log.d("ERROR", "Trying the camera and it's not running");
        }
        try {
            mCamera.setPreviewDisplay(mHolder);
            mCamera.startPreview();
            safeToTakePicture = true;
        } catch (IOException e) {
            Log.d("ERROR", "Camera error on surfaceChanged " + e.getMessage());
        }

    }

    @Override
    public void surfaceDestroyed(SurfaceHolder surfaceHolder) {
        mCamera.stopPreview();
        mCamera.release();
    }
}

我多次收到错误Camera is being used after Camera.release was called,例如在拍照时:

07-02 14:49:35.561 19017-19017/davidandguy.com.selfielightcamera E/AndroidRuntime: FATAL EXCEPTION: main
                                                                                   Process: davidandguy.com.selfielightcamera, PID: 19017
                                                                                   java.lang.RuntimeException: Camera is being used after Camera.release() was called
                                                                                       at android.hardware.Camera.native_takePicture(Native Method)
                                                                                       at android.hardware.Camera.takePicture(Camera.java:1523)
                                                                                       at android.hardware.Camera.takePicture(Camera.java:1468)
                                                                                       at davidandguy.com.selfielightcamera.MainActivity$1$1.onFinish(MainActivity.java:65)
                                                                                       at android.os.CountDownTimer$1.handleMessage(CountDownTimer.java:127)
                                                                                       at android.os.Handler.dispatchMessage(Handler.java:102)
                                                                                       at android.os.Looper.loop(Looper.java:158)
                                                                                       at android.app.ActivityThread.main(ActivityThread.java:7224)
                                                                                       at java.lang.reflect.Method.invoke(Native Method)
                                                                                       at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1230)
                                                                                       at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1120)

或者甚至在调用onResume()时,例如,最小化活动然后再次运行。我知道我需要放置onPause()onResume(),但我不知道在哪里/如何实现它。谢谢

1 个答案:

答案 0 :(得分:0)

这真的是过期的,但是当我在一分钟前设法解决了我的类似问题时,我想我会为自己和其他任何可能拼命搜索Stack的人做出贡献。

我在这里看不到你的生命周期代码,但是对我有用的是,在我的情况下,surfaceDestroyed是空的

首先是cameraPreview

public void surfaceChanged(SurfaceHolder surfaceHolder, int format, int width, int height) {
try {
    this.mCamera.setPreviewDisplay(surfaceHolder);
    this.mCamera.startPreview();
} catch (Exception e) {
}
}


public void surfaceCreated(SurfaceHolder surfaceHolder) {
try {
    //TODO we need this here too because on SurfaceCreated we always need to open the camera, in case its released

    this.mCamera.setPreviewDisplay(surfaceHolder);
    this.mCamera.setDisplayOrientation(90);
    //this.mCamera.startPreview();
} catch (IOException e) {
}
}

接下来是CameraActivity

@Override
public void onResume() {
    super.onResume();
   try{
       mCamera = openFrontFacingCameraGingerbread();
      // Add to Framelayout
       this.mCameraPreview = new CameraPreview(this, this.mCamera);
        mImage.removeAllViews();
       this.mImage.addView(this.mCameraPreview);

   }catch (RuntimeException ex){

    }



}


@Override
public void onPause() {
    super.onPause();
    captureButton.setText("Begin Capture");
    if(CameraActivity.this.timer !=null) {
        CameraActivity.this.timer.cancel();
        CameraActivity.this.timer.purge();
        CameraActivity.this.timer = null;
    }
    if (mCamera != null) {
        mCamera.setPreviewCallback(null);
        mCameraPreview.getHolder().removeCallback(mCameraPreview);
        mCamera.release();
        mCamera = null;
    }


}


@Override
protected void onDestroy(){
    super.onDestroy();
    releaseCameraAndPreview();
}

private void releaseCameraAndPreview() {

    if (mCamera != null) {
        mCamera.stopPreview();
        mCamera.release();
        mCamera = null;
    }
    if(mCameraPreview != null){
        mCameraPreview.destroyDrawingCache();
        mCameraPreview.mCamera = null;
    }
}