安卓相机的onPause / onResume问题 [英] android: camera onPause/onResume issue

查看:1180
本文介绍了安卓相机的onPause / onResume问题的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一些麻烦的的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和重新实例一起(如在启动时)。更多细节在这里:

<一个href="http://stackoverflow.com/questions/8481402/android-i-get-no-stacktrace-phone-just-hangs">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

这篇关于安卓相机的onPause / onResume问题的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆