Tôi gặp một số trục trặc với chu kỳ sống onPause() onResume(): Máy ảnh xem trước và chụp ảnh hoạt động hoàn toàn tốt. Với một ngoại lệ:android: camera onPause/onResume issue
Tôi khởi động ứng dụng, nhấp vào nút trang chủ, quay lại ứng dụng và chụp một lần nữa.
Kết quả: shuttercallback vẫn được thực hiện (xem mã), nhưng gọi lại jpeg không còn nữa! Sau đó, thiên hà S của tôi rung và màn hình vẫn đen, vì startPreview() không được kích hoạt lại sau jpegCallback. Theo dõi ngăn xếp là xa hữu ích cho tôi. Điều lạ lùng là điều này chỉ xảy ra trên Galaxy S của tôi chứ không phải trên trình giả lập. Tôi thực sự không có đầu mối làm thế nào để di chuyển trên:/ Bất cứ ai cũng có một ý tưởng những gì có thể hữu ích?
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 ...
Sau đây là tôi (rút ngắn) mã:
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; } } }
Tại sao thêm một sự chậm trễ trong onPause khắc phục sự cố này, tôi tự hỏi :) –