从onResume()
调用此方法 private void initCameraPreview() {
mCamera = getCameraInstance();
mSurfaceView = (SurfaceView) findViewById(R.id.camera_view);
mCameraPreview = new CameraPreview(this, mCamera, mSurfaceView.getHolder());
}
private Camera getCameraInstance() {
Camera c = null;
try {
c = Camera.open(); // attempt to get a Camera instance
} catch (Exception e) {
// Camera is not available (in use or does not exist)
e.printStackTrace();
}
return c; // returns null if camera is unavailable
}
这是我的onPause()
@Override
protected void onPause() {
isPicTaken = false;
mCameraPreview.surfaceDestroyed(null);
Log.d("MainCameraActivity", "OnPause()");
super.onPause();
}
这是CameraPreview
public class CameraPreview extends SurfaceView implements SurfaceHolder.Callback {
private static String TAG = "Camera Preview class";
private SurfaceHolder mHolder;
private Camera mCamera;
private static boolean previewIsRunning;
public Camera getmCamera() {
return mCamera;
}
public CameraPreview(Context context, Camera mCamera, SurfaceHolder holder) {
super(context);
mHolder = holder;
this.mCamera = mCamera;
if (mHolder != null) {
mHolder.setKeepScreenOn(true);
mHolder.setSizeFromLayout();
mHolder.addCallback(this);
}
}
@Override
public void surfaceCreated(SurfaceHolder holder) {
if (mCamera != null) {
Camera.Parameters params = mCamera.getParameters();
params.setFocusMode("continuous-picture");
params.setRotation(90);
mCamera.setParameters(params);
try {
mCamera.setPreviewDisplay(mHolder);
} catch (IOException e) {
e.printStackTrace();
}
mCamera.setDisplayOrientation(90);
mCamera.startPreview();
previewIsRunning = true;
}
}
@Override
public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
}
@Override
public void surfaceDestroyed(SurfaceHolder holder) {
if (mCamera != null) {
myStopPreview();
mCamera = null;
}
previewIsRunning = false;
}
public void myStartPreview() {
if (!previewIsRunning) {
try {
mCamera = Camera.open();
Camera.Parameters params = mCamera.getParameters();
params.setFocusMode("continuous-picture");
params.setRotation(90);
mCamera.setParameters(params);
mCamera.setPreviewDisplay(mHolder);
mCamera.setDisplayOrientation(90);
mCamera.startPreview();
previewIsRunning = true;
} catch (IOException ex) {
ex.printStackTrace();
}
}
}
public void myStopPreview() {
if (previewIsRunning) {
mHolder.removeCallback(this);
mCamera.setPreviewCallback(null);
mCamera.stopPreview();
mCamera.release();
previewIsRunning = false;
}
}
}
如果我去另一个活动,然后返回,最小化应用程序并再次打开它,此代码有效,但如果我让手机睡眠,然后醒来,预览中的图片冻结,并且在调用takePicture之后我得到了这个< / p>
07-25 18:00:00.970 11395-11395/com.woxapp.pricehelper.app E/AndroidRuntime﹕ FATAL EXCEPTION: main
java.lang.RuntimeException: takePicture failed
at android.hardware.Camera.native_takePicture(Native Method)
at android.hardware.Camera.takePicture(Camera.java:1100)
at android.hardware.Camera.takePicture(Camera.java:1045)
at com.woxapp.pricehelper.app.activities.MainCameraActivity.onTakePhotoButtonClicked(MainCameraActivity.java:683)
at com.woxapp.pricehelper.app.views.MainCameraView$11.onClick(MainCameraView.java:545)
at android.view.View.performClick(View.java:4240)
at android.view.View$PerformClick.run(View.java:17721)
at android.os.Handler.handleCallback(Handler.java:730)
at android.os.Handler.dispatchMessage(Handler.java:92)
at android.os.Looper.loop(Looper.java:137)
at android.app.ActivityThread.main(ActivityThread.java:5103)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:525)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:737)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:553)
at dalvik.system.NativeStart.main(Native Method)
我真的不知道它是如何可能的,以及如何解决这个问题,在Nexus 4(Android 4.3)上进行测试
答案 0 :(得分:1)
您的initCameraPreview()
假设您的应用必须获得mCamera
;可能在某个地方,例如onStop()
你也会释放相机(或系统为你处理)。但是当您将手机置于睡眠状态然后唤醒时,只会为当前活动调用onPause()
和onResume()
。
所以,你应该确保你已经没有尝试获取相机了。一种简单的方法是在致电mCamera = null;
后立即添加mCamera.close()
;如果你不这样做 - 将其添加到你的活动的onStop()
方法。
然后,在initCameraPreview()
中,您只需检查
if (mCamera == null) {
mCamera = getCameraInstance();
}
答案 1 :(得分:1)
因为mSurfaceView的oncreated和onchanged无法调用。 最简单的方法是在onpause和onresume中设置mSurfaceView不可见和可见。在您的活动或片段中,添加以下代码:
@Override
public void onResume() {
super.onResume();
mCamera = Camera.open(0);
mSurfaceView.setVisibility(View.VISIBLE);// this can fix the freeze.
}
@Override
public void onPause() {
super.onPause();
mSurfaceView.setVisibility(View.GONE);//this to fix freeze.
if (mCamera != null) {
mCamera.release();
mCamera = null;
}
}