我有一些麻烦的的onPause()onResume()摄像机的现场循环: 相机采用preVIEW和拍照工作完全正常。有一个例外:
我启动应用程序,单击主页按钮,切换到该应用程序并拍摄。
结果:仍执行shuttercallback(见code),而JPEG回调不下去了!然后我的GALAXY S振动,屏幕一直是黑色的,因为启动preVIEW()不重新触发jpegCallback后。堆栈跟踪是远远有用的我。 奇怪的是,这只是发生在我的Galaxy S,而不是在模拟器上。我真的不知道如何继续前进:/ 任何人有一个想法,这可能是有用的?
10-28 18:59:40.649:ERROR / SecCamera(4291):SetRotate(角(0)) 10-28 18:59:40.649:ERROR / CameraHardwareSec(4291):==== setParameters processingmethod =(空) 10-28 18:59:40.649:ERROR / SecCamera(4291):setRecordingSize(宽度(800),高度(480)) 10-28 18:59:40.673:ERROR / SecCamera(4291):SetRotate(角(0)) 10-28 18:59:40.673:ERROR / CameraHardwareSec(4291):==== setParameters processingmethod =(空) 10-28 18:59:40.673:ERROR / SecCamera(4291):setRecordingSize(宽度(800),高度(480)) 10-28 18:59:40.692:ERROR / SecCamera(4291):SetRotate(角(0)) 10-28 18:59:40.692:ERROR / CameraHardwareSec(4291):==== setParameters processingmethod =(空) 10-28 18:59:40.692:ERROR / SecCamera(4291):setRecordingSize(宽度(800),高度(480)) 10-28 18:59:40.712:ERROR / SecCamera(4291):SetRotate(角(0)) 10-28 18:59:40.712:ERROR / CameraHardwareSec(4291):==== setParameters processingmethod =(空) 10-28 18:59:40.712:ERROR / SecCamera(4291):setRecordingSize(宽度(800),高度(480)) 10-28 18:59:40.751:ERROR / CameraHardwareSec(4291):停止preVIEW() 10-28 18:59:40.751:ERROR / SecCamera(4291):cancelAutofocus() 10-28 18:59:40.751:ERROR / SecCamera(4291):cancelAutofocus()结束,0,4 10-28 18:59:40.768:ERROR / SecCamera(4291):停止preVIEW() 10-28 18:59:40.768:ERROR / SecCamera(4291):fimc_v4l2_streamoff() 10-28 18:59:40.797:ERROR / CameraHardwareSec(4291):停止preVIEW()结束 10-28 18:59:41.622:ERROR / SecCamera(4291):fimc_v4l2_streamoff() 10-28 18:59:46.536:ERROR / dalvikvm(2993):无法写入堆栈跟踪到/data/anr/traces.txt(2775 2970):未知错误:0 10-28 18:59:46.540:ERROR / dalvikvm(2919):无法写入堆栈跟踪到/data/anr/traces.txt(-1 3414):数学成绩不重presentable 10-28 18:59:46.610:ERROR / dalvikvm(3044):无法写入堆栈跟踪到/data/anr/traces.txt(3354 7154的):数学成绩不重presentable ...
下面是我的(缩短)code:
公共类CameraActivity扩展活动实现MenuViewCallback,CutoutPathManagerCallback { 公共静态最终字符串变量=CutoutCamera; preVIEW preVIEW; OverlayView叠加; 静态MenuView menuView; @覆盖 公共无效的onCreate(包savedInstanceState){ super.onCreate(savedInstanceState); //隐藏窗口标题。 requestWindowFeature(Window.FEATURE_NO_TITLE); 。getWindow()addFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN); ... preVIEW =(preVIEW)this.findViewById(R.id. preVIEW); ... } ... @覆盖 保护无效onResume(){ super.onResume(); this.log(onResume()); preview.openCamera(); } @覆盖 保护无效的onPause(){ super.onPause(); this.log(的onPause()); 如果(preview.camera!= NULL){ preview.camera.release(); preview.camera = NULL; } } //当快门打开时调用 ShutterCallback shutterCallback =新ShutterCallback(){// 公共无效onShutter(){ Log.d(TAG,onShutter'd); } }; //处理对原始图像数据 PictureCallback rawCallback =新PictureCallback(){// 公共无效onPictureTaken(byte []的数据,摄像头摄像头){ Log.d(TAG,onPictureTaken - 生); } }; //处理数据的JPEG图片 PictureCallback jpegCallback =新PictureCallback(){// 公共无效onPictureTaken(byte []的数据,摄像头摄像头){ Log.d(TAG,onPictureTaken - JPEG); ... } }; @覆盖 公共无效shootButtonClicked(){ preview.camera.takePicture(shutterCallback,rawCallback,jpegCallback); } @覆盖 公共无效focusButtonClicked(){ preview.camera.autoFocus(新Camera.AutoFocusCallback(){ 公共无效onAutoFocus(布尔成功,相机摄像头){ } }); } }
/ ** *执行顺序: * 开放式摄像头() * onMeasure() * onLayout() * onMeasure() * onLayout() * surfaceCreated() * surfaceChanged() * onMeasure() * onLayout() * onMeasure() * @author斯蒂芬 * * / 类preVIEW延伸的ViewGroup实现SurfaceHolder.Callback {// 私有静态最后字符串变量=preVIEW; SurfaceHolder mHolder; // 公共摄像头摄像头; // 私人列表支持previewSizes; 私人大小previewSize; SurfaceView mSurfaceView; CameraActivity cameraActivity; INT 12 = 0,T2 = 0,R2 = 0,B2 = 0; INT填充= 20; 尺寸优化previewSize,optimalPictureSize; //该视图的大小。获取onMeasure设置() INT全角,fullHeight; 公共preVIEW(上下文的背景下){ 超(上下文); 的init(上下文); } 公共preVIEW(上下文的背景下,ATTRS的AttributeSet){ 超(背景下,ATTRS); 的init(上下文); } 公共preVIEW(上下文的背景下,ATTRS的AttributeSet,诠释defStyle){ 超(背景下,ATTRS,defStyle); 的init(上下文); } 私人无效的init(上下文的背景下){ setKeepScreenOn(真正的); cameraActivity =(CameraActivity)范围内; mSurfaceView =新SurfaceView(上下文); addView(mSurfaceView); mHolder = mSurfaceView.getHolder(); // mHolder.addCallback(本); // mHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS); // } ... 公共无效openCamera(){ cameraActivity.log(openCamera()); 如果(this.camera == NULL){ cameraActivity.log(Camera.open()); this.camera = Camera.open(); //支持previewSizes = camera.getParameters()getSupported previewSizes()。 requestLayout(); // - > onMeassure() - > onLayout() } } @覆盖 保护无效onMeasure(INT widthMeasureSpec,诠释heightMeasureSpec){ cameraActivity.log(onMeasure()); //我们故意忽略孩子的测量,因为充当 //包装一个SurfaceView该中心相机preVIEW代替 拉伸吧//。 全角= resolveSize(getSuggestedMinimumWidth(),widthMeasureSpec); fullHeight = resolveSize(getSuggestedMinimumHeight(),heightMeasureSpec); setMeasuredDimension(全角,fullHeight); 如果(this.camera!= NULL){ cameraActivity.log(原图:+ +全角的x+ fullHeight); this.setCamera previewSize(); this.setCameraPictureSize(); } } 私人无效calcScaled previewSize(){ ... } ... 私人无效setCamera previewSize(){ Camera.Parameters参数= camera.getParameters(); 如果(parameters.get previewSize()!= this.getOptimal previewSize()){ parameters.set previewSize(this.getOptimal previewSize()宽,this.getOptimal previewSize()的高度。); this.camera.setParameters(参数); } } 私人无效setCameraPictureSize(){ Camera.Parameters参数= this.camera.getParameters(); 如果(parameters.getPictureSize()!= this.getOptimalCameraPictureSize()){ parameters.setPictureSize(getOptimalCameraPictureSize()宽度,getOptimalCameraPictureSize()的高度。); this.camera.setParameters(参数); } } @覆盖 保护无效onLayout(布尔改变,诠释L,INT T,INT R,int b)在{ cameraActivity.log(onLayout()); 如果(改变&& getChildCount()> 0 && this.camera!= NULL){ 最后查看孩子= getChildAt(0); cameraActivity.log(R+ this.get previewRight()+L+ this.get previewLeft()+B:+ this.get previewBottom()+ T:+ this.get previewTop()); child.layout(this.get previewLeft(),this.get previewTop(),this.get previewRight(),this.get previewBottom()); cameraActivity.initOverlay(this.get$p$pviewLeft(),this.get$p$pviewTop(),this.get$p$pviewRight(),this.get$p$pviewBottom()); } } 私人大小getOptimal previewSize(){ 如果(最佳previewSize == NULL){ //计算出最佳的preVIEW大小 } 返回最佳的previewSize; } 私人尺寸getOptimalCameraPictureSize(){ 如果(optimalPictureSize == NULL){ //计算出最佳的图像大小 } 返回optimalPictureSize; } //调用一次支架已准备就绪 公共无效surfaceCreated(SurfaceHolder持有者){// //表面经创建,获取摄像机,并告诉它在哪里 //绘制。 cameraActivity.log(surfaceCreated()); 尝试 { 如果(this.camera!= NULL){ this.camera.set previewDisplay(保持器); } }赶上(IOException异常除外){ Log.e(TAG,IOException异常造成集previewDisplay(),除外); } } 公共无效surfaceChanged(SurfaceHolder持有人,INT格式,INT W,INT高){ cameraActivity.log(surfaceChanged()); 如果(相机!= NULL){ Camera.Parameters参数= camera.getParameters(); parameters.set previewSize(getOptimal previewSize()宽,getOptimal previewSize()的高度。); requestLayout(); camera.setParameters(参数); camera.start preVIEW(); } } 公共无效surfaceDestroyed(SurfaceHolder持有者){// cameraActivity.log(surfaceDestroyed()); 如果(this.camera!= NULL){ camera.stop preVIEW(); } } 公共无效releaseCamera(){ cameraActivity.log(releaseCamera()); 如果(相机!= NULL){ camera.stop preVIEW(); camera.set previewCallback(空); camera.release(); 摄像头= NULL; } } }
解决方案
这是我如何固定它100%,最后(工作在每个设备上我试了一下,包括银河S):
我破坏了房间preVIEW对象onResume和重新实例一起(如在启动时)。更多细节在这里:
android:我没有得到任何堆栈跟踪,电话刚挂
I have some troubles with the onPause() onResume() camera live cycle: Camera with preview, and taking photos works totally fine. With one exceptions:
I start the app, click the home button, switch back to the app and take another shot.
Result: shuttercallback is still executed (see code), but jpeg callback isn't anymore! Then my galaxy S vibrates, and the screen stays black, since startPreview() is not re-triggered after jpegCallback. The stack trace is far from usefull for me. Strange thing is that this only happens on my Galaxy S, not on the emulator. I have really no clue how to move on :/ Anyone has an idea what could be usefull?
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 ...
Here is my (shortened) code:
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; } } }
解决方案
This is how I fixed it 100%, finally (working on every device I tried it on, including Galaxy S):
I destroyed the camere preview object onResume and reinstantiated all together (like on startup). More details here:
android: I get no stacktrace, phone just hangs
相关推荐
最新文章