睡眠后相机冻结

时间:2014-07-25 15:02:45

标签: android android-camera

从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)上进行测试

2 个答案:

答案 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;
    }
}