我在onPause()onResume()相机实时循环中遇到了一些麻烦: 相机预览,拍照完全没问题。除了一个例外:
我启动应用程序,单击主页按钮,切换回应用程序并再次拍摄。
结果:仍然执行了shuttercallback(参见代码),但jpeg回调不再存在了!然后我的星系S振动,屏幕保持黑色,因为在jpegCallback之后没有重新触发startPreview()。堆栈跟踪对我来说远非有用。 奇怪的是,这只发生在我的Galaxy S上,而不是在模拟器上。我真的不知道如何继续前进:/ 任何人都知道什么可能有用?
10-28 18:59:40.649: ERROR/SecCamera(4291): SetRotate(angle(0)) 10-28 18:59:40.649: ERROR/CameraHardwareSec(4291): ====setParameters processingmethod = (null) 10-28 18:59:40.649: ERROR/SecCamera(4291): setRecordingSize(width(800), height(480)) 10-28 18:59:40.673: ERROR/SecCamera(4291): SetRotate(angle(0)) 10-28 18:59:40.673: ERROR/CameraHardwareSec(4291): ====setParameters processingmethod = (null) 10-28 18:59:40.673: ERROR/SecCamera(4291): setRecordingSize(width(800), height(480)) 10-28 18:59:40.692: ERROR/SecCamera(4291): SetRotate(angle(0)) 10-28 18:59:40.692: ERROR/CameraHardwareSec(4291): ====setParameters processingmethod = (null) 10-28 18:59:40.692: ERROR/SecCamera(4291): setRecordingSize(width(800), height(480)) 10-28 18:59:40.712: ERROR/SecCamera(4291): SetRotate(angle(0)) 10-28 18:59:40.712: ERROR/CameraHardwareSec(4291): ====setParameters processingmethod = (null) 10-28 18:59:40.712: ERROR/SecCamera(4291): setRecordingSize(width(800), height(480)) 10-28 18:59:40.751: ERROR/CameraHardwareSec(4291): stopPreview() 10-28 18:59:40.751: ERROR/SecCamera(4291): cancelAutofocus() 10-28 18:59:40.751: ERROR/SecCamera(4291): cancelAutofocus() end, 0, 4 10-28 18:59:40.768: ERROR/SecCamera(4291): stopPreview() 10-28 18:59:40.768: ERROR/SecCamera(4291): fimc_v4l2_streamoff() 10-28 18:59:40.797: ERROR/CameraHardwareSec(4291): stopPreview() end 10-28 18:59:41.622: ERROR/SecCamera(4291): fimc_v4l2_streamoff() 10-28 18:59:46.536: ERROR/dalvikvm(2993): Failed to write stack traces to /data/anr/traces.txt (2775 of 2970): Unknown error: 0 10-28 18:59:46.540: ERROR/dalvikvm(2919): Failed to write stack traces to /data/anr/traces.txt (-1 of 3414): Math result not representable 10-28 18:59:46.610: ERROR/dalvikvm(3044): Failed to write stack traces to /data/anr/traces.txt (3354 of 7154): Math result not representable ...
这是我的(缩短的)代码:
public class CameraActivity extends Activity implements MenuViewCallback, CutoutPathManagerCallback { public static final String TAG = "CutoutCamera"; Preview preview; OverlayView overlay; static MenuView menuView; @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); // Hide the window title. requestWindowFeature(Window.FEATURE_NO_TITLE); getWindow().addFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN); ... preview = (Preview) this.findViewById(R.id.preview); ... } ... @Override protected void onResume() { super.onResume(); this.log("onResume()"); preview.openCamera(); } @Override protected void onPause() { super.onPause(); this.log("onPause()"); if (preview.camera != null) { preview.camera.release(); preview.camera = null; } } // Called when shutter is opened ShutterCallback shutterCallback = new ShutterCallback() { // public void onShutter() { Log.d(TAG, "onShutter'd"); } }; // Handles data for raw picture PictureCallback rawCallback = new PictureCallback() { // public void onPictureTaken(byte[] data, Camera camera) { Log.d(TAG, "onPictureTaken - raw"); } }; // Handles data for jpeg picture PictureCallback jpegCallback = new PictureCallback() { // public void onPictureTaken(byte[] data, Camera camera) { Log.d(TAG, "onPictureTaken - jpeg"); ... } }; @Override public void shootButtonClicked() { preview.camera.takePicture(shutterCallback, rawCallback, jpegCallback); } @Override public void focusButtonClicked() { preview.camera.autoFocus(new Camera.AutoFocusCallback() { public void onAutoFocus(boolean success, Camera camera) { } }); } }
/** * order of execution: * openCamera() * onMeasure() * onLayout() * onMeasure() * onLayout() * surfaceCreated() * surfaceChanged() * onMeasure() * onLayout() * onMeasure() * @author stephan * */ class Preview extends ViewGroup implements SurfaceHolder.Callback { // private static final String TAG = "Preview"; SurfaceHolder mHolder; // public Camera camera; // private List supportedPreviewSizes; private Size previewSize; SurfaceView mSurfaceView; CameraActivity cameraActivity; int l2 = 0, t2 = 0, r2 = 0, b2 = 0; int padding = 20; Size optimalPreviewSize, optimalPictureSize; // the size of this view. gets set in onMeasure() int fullWidth, fullHeight; public Preview(Context context) { super(context); init(context); } public Preview(Context context, AttributeSet attrs) { super(context, attrs); init(context); } public Preview(Context context, AttributeSet attrs, int defStyle) { super(context, attrs, defStyle); init(context); } private void init(Context context) { setKeepScreenOn(true); cameraActivity = (CameraActivity) context; mSurfaceView = new SurfaceView(context); addView(mSurfaceView); mHolder = mSurfaceView.getHolder(); // mHolder.addCallback(this); // mHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS); // } ... public void openCamera() { cameraActivity.log("openCamera()"); if (this.camera == null) { cameraActivity.log("Camera.open()"); this.camera = Camera.open(); //supportedPreviewSizes = camera.getParameters().getSupportedPreviewSizes(); requestLayout(); // -> onMeassure() -> onLayout() } } @Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { cameraActivity.log("onMeasure()"); // We purposely disregard child measurements because act as a // wrapper to a SurfaceView that centers the camera preview instead // of stretching it. fullWidth = resolveSize(getSuggestedMinimumWidth(), widthMeasureSpec); fullHeight = resolveSize(getSuggestedMinimumHeight(), heightMeasureSpec); setMeasuredDimension(fullWidth, fullHeight); if(this.camera != null){ cameraActivity.log("fullSize:"+fullWidth+"x"+fullHeight); this.setCameraPreviewSize(); this.setCameraPictureSize(); } } private void calcScaledPreviewSize(){ ... } ... private void setCameraPreviewSize() { Camera.Parameters parameters = camera.getParameters(); if(parameters.getPreviewSize() != this.getOptimalPreviewSize()){ parameters.setPreviewSize(this.getOptimalPreviewSize().width, this.getOptimalPreviewSize().height); this.camera.setParameters(parameters); } } private void setCameraPictureSize() { Camera.Parameters parameters = this.camera.getParameters(); if(parameters.getPictureSize() != this.getOptimalCameraPictureSize()){ parameters.setPictureSize(getOptimalCameraPictureSize().width, getOptimalCameraPictureSize().height); this.camera.setParameters(parameters); } } @Override protected void onLayout(boolean changed, int l, int t, int r, int b) { cameraActivity.log("onLayout()"); if (changed && getChildCount() > 0 && this.camera != null) { final View child = getChildAt(0); cameraActivity.log("r:"+this.getPreviewRight()+" l:"+this.getPreviewLeft()+" b:"+this.getPreviewBottom()+" t:"+this.getPreviewTop()); child.layout(this.getPreviewLeft(), this.getPreviewTop(), this.getPreviewRight(), this.getPreviewBottom()); cameraActivity.initOverlay(this.getPreviewLeft(),this.getPreviewTop(),this.getPreviewRight(),this.getPreviewBottom()); } } private Size getOptimalPreviewSize() { if(optimalPreviewSize == null){ //calculate optimal preview size } return optimalPreviewSize; } private Size getOptimalCameraPictureSize() { if(optimalPictureSize == null){ //calculate optimal image size } return optimalPictureSize; } // Called once the holder is ready public void surfaceCreated(SurfaceHolder holder) { // // The Surface has been created, acquire the camera and tell it where // to draw. cameraActivity.log("surfaceCreated()"); try { if (this.camera != null) { this.camera.setPreviewDisplay(holder); } } catch (IOException exception) { Log.e(TAG, "IOException caused by setPreviewDisplay()", exception); } } public void surfaceChanged(SurfaceHolder holder, int format, int w, int h) { cameraActivity.log("surfaceChanged()"); if (camera != null) { Camera.Parameters parameters = camera.getParameters(); parameters.setPreviewSize(getOptimalPreviewSize().width, getOptimalPreviewSize().height); requestLayout(); camera.setParameters(parameters); camera.startPreview(); } } public void surfaceDestroyed(SurfaceHolder holder) { // cameraActivity.log("surfaceDestroyed()"); if(this.camera != null){ camera.stopPreview(); } } public void releaseCamera(){ cameraActivity.log("releaseCamera()"); if (camera != null) { camera.stopPreview(); camera.setPreviewCallback(null); camera.release(); camera = null; } } }
答案 0 :(得分:6)
这是我100%修复它的方法,最后(在我尝试过的每台设备上工作,包括Galaxy S):
我在onResume上销毁了camere预览对象并重新实例化(如启动时)。更多细节在这里:
答案 1 :(得分:4)
达到这个帖子有点晚了,但我遇到了类似的问题。首先,如果你使用客户ROM,它可能是相机驱动程序的问题(我的一个X8 runniing 4.0.4)。如果您按电源按钮将手机置于待机模式并在短时间内将其带回(有或没有主屏幕锁定),也会出现此问题。尝试和错误后,我发现在关闭之前关闭相机后短暂延迟.onPause是最好的。我的代码如下。
@Override
public void onPause() {
// Log.d(TAG,"ccp_onPause");
closeCamera();
try {
Thread.sleep(500);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
super.onPause();
}
和closeCamera();
public void closeCamera() {
if (mCamera != null) {
mCamera.stopPreview();
mCamera.setPreviewCallback(null);
mCamera.lock();
mCamera.release();
mCamera=null;
requestLayout();
}
}
答案 2 :(得分:2)
我猜你要做的就是在预览中创建一个用于重置相机的setter方法(预览中的本地相机对象在onPause()之后变为无效,因为相机已经发布,但预览的其余部分是仍然保持)。