如何在完成后重新打开活动并在其中再次启动相机预览

Posted

技术标签:

【中文标题】如何在完成后重新打开活动并在其中再次启动相机预览【英文标题】:How to re open an activity after finishing it and also start the Camera Preview again in it 【发布时间】:2016-08-15 15:15:25 【问题描述】:

在名为 CameraActivity 的相机应用的 Launcher 活动中,我重写了 onPause() 方法,如下所示,

@Override
protected void onPause() 
    super.onPause();
    mCamera.release();
    finish();

这样,每当通过按主页按钮或返回按钮退出应用程序时,相机就会被释放并且活动完成以让其他相机应用程序访问相机。但现在我创建了另一个名为CameraSettings 的活动。并使用Intent 打开它。问题是当我想回到CameraActivity 时,应用程序会关闭并返回主屏幕,因为我在onPause() 中使用了finish() 方法。即使我不使用finish() 方法,我仍然会收到错误,因为相机已经释放。

我想要的是,当我在CameraActivity 中时,如果我按下返回/主页,那么相机将被释放,如果我进入CameraSettings 活动,在对相机进行更改后我想返回CameraActivity 将重新打开相机以使用。我尝试覆盖onResume() 方法并再次启动相机预览,但它给出了错误。下面是onResume()的方法,

@Override
protected void onResume() 
    super.onResume();
    mCamera.startPreview();

这是我第一次启动相机预览的onCreate() 方法,

@Override
protected void onCreate(Bundle savedInstanceState) 
    super.onCreate(savedInstanceState);
    setContentView(R.layout.layout_test);
    getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,
            WindowManager.LayoutParams.FLAG_FULLSCREEN);

    //ShutterSound
    final Camera.ShutterCallback shutter = new Camera.ShutterCallback() 
        @Override
        public void onShutter() 

        
    ;

    //Settings listener
    settings = (ImageView) findViewById(R.id.settings);
    settings.setOnClickListener(new View.OnClickListener() 
        @Override
        public void onClick(View v) 
            Intent openSettings = new Intent(getApplicationContext(),CameraSettings.class);
            startActivity(openSettings);
        
    );



    //Capture button listener
    captureButton = (Button) findViewById(R.id.captureButton);
    captureButton.setOnClickListener(
            new View.OnClickListener() 
                @Override
                public void onClick(View v) 
                    captureButton.setEnabled(false);
                    // get an image from the camera
                    mCamera.takePicture(shutter, null, mPicture);
                
            
    );

    //Switch the cameras
    switchCamera = (ImageView) findViewById(R.id.switchCamera);
    switchCamera.setOnClickListener(new View.OnClickListener() 

        @Override
        public void onClick(View v) 
            checkFrontCameraInUse = !checkFrontCameraInUse;
            switchCamera.setEnabled(false);
            switchCamera();
        
    );

    /*
    * Below code is
    * needed to start the camera first time
    * */

    // Create an instance of Camera
    mCamera = CameraInstance.getCameraInstance(0);
    // Create our Preview view and set it as the content of our activity.
    mPreview = new CameraPreview(this, mCamera, 0);
    preview = (LinearLayout) findViewById(R.id.camera_preview);

    assert preview != null;
    preview.addView(mPreview);

这是错误信息,

    FATAL EXCEPTION: main
    Process: com.prohelika.testcamera, PID: 28304
    java.lang.RuntimeException: Camera is being used after Camera.release() was called
    at android.hardware.Camera.setPreviewSurface(Native Method)
    at android.hardware.Camera.setPreviewDisplay(Camera.java:801)
    at com.prohelika.testcamera.CameraPreview.surfaceCreated(CameraPreview.java:36)
    at android.view.SurfaceView.updateWindow(SurfaceView.java:675)
    at android.view.SurfaceView.onWindowVisibilityChanged(SurfaceView.java:273)
    at android.view.View.dispatchWindowVisibilityChanged(View.java:8998)
    at android.view.ViewGroup.dispatchWindowVisibilityChanged(ViewGroup.java:1190)
    at android.view.ViewGroup.dispatchWindowVisibilityChanged(ViewGroup.java:1190)
    at android.view.ViewGroup.dispatchWindowVisibilityChanged(ViewGroup.java:1190)
    at android.view.ViewGroup.dispatchWindowVisibilityChanged(ViewGroup.java:1190)
    at android.view.ViewGroup.dispatchWindowVisibilityChanged(ViewGroup.java:1190)
    at android.view.ViewGroup.dispatchWindowVisibilityChanged(ViewGroup.java:1190)
    at android.view.ViewRootImpl.performTraversals(ViewRootImpl.java:1575)
    at android.view.ViewRootImpl.doTraversal(ViewRootImpl.java:1296)
    at android.view.ViewRootImpl$TraversalRunnable.run(ViewRootImpl.java:6602)
    at android.view.Choreographer$CallbackRecord.run(Choreographer.java:800)
    at android.view.Choreographer.doCallbacks(Choreographer.java:603)
    at android.view.Choreographer.doFrame(Choreographer.java:572)
    at android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:786)
    at android.os.Handler.handleCallback(Handler.java:815)
    at android.os.Handler.dispatchMessage(Handler.java:104)
    at android.os.Looper.loop(Looper.java:194)
    at android.app.ActivityThread.main(ActivityThread.java:5717)
    at java.lang.reflect.Method.invoke(Native Method)
    at java.lang.reflect.Method.invoke(Method.java:372)
    at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:959)
    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:754)

如果我的解释不好,请原谅我。

【问题讨论】:

您需要添加更多详细信息,例如您尝试了什么、遇到了什么错误、您从哪里开始预览相机。 你用过startActivityForResult(yourSettingsIntent)吗?如果没有,请查看docs。 @Anders 我在第一次使用预览的地方添加了 onCreate() 方法 @Amy 不,我没有,但它不会触发 onPause() 方法吗? 嗯,你说得对,我的错^^' 【参考方案1】:

由于您已经释放了相机资源,因此在您的 onResume() 方法中调用 startPreview() 方法时出现错误。

释放后将camera 设置为null。 并从相机预览中删除previewCallback

    @Override
    protected void onPause() 
        super.onPause();
        mCamera.setPreviewCallback(null);
        mPreview.getHolder().removeCallback(mPreview);
        mCamera.release();
        mCamera = nulll
        finish();
    

尝试检查相机是否为null 并在onResume() 方法中重新初始化您的camera 实例:

@Override
protected void onResume() 
    super.onResume();
    if (mCamera == null) 
        mCamera = getCameraInstance();
    
    mCamera.startPreview();

P.S.如果出现null,您可能需要重新初始化预览。

希望这会有所帮助!

【讨论】:

它仍然给出同样的错误:(我应该添加我得到的错误消息吗? 我已经添加了,请查看 立即查看答案 @FarhanFarooqui 你检查过更新的答案了吗? 对不起,我出去吃午饭了。我现在已经检查过了,它没有报错但也没有开始预览

以上是关于如何在完成后重新打开活动并在其中再次启动相机预览的主要内容,如果未能解决你的问题,请参考以下文章

活动生命周期。当应用程序已经打开(折叠)正在关闭并在图标单击时重新启动?

从纵向活动中以横向打开相机时上下文为空

为啥我的相机在另一个活动开始后停止预览?

屏幕关闭时Android相机不会拍照

我想在相同的Activity中停止后重启相机源

在颤振中重新启动(再次关闭和打开)后对话框状态不会改变