【问题标题】:Camera freezes on phone sleep/wake相机在手机睡眠/唤醒时冻结
【发布时间】:2014-02-20 00:50:49
【问题描述】:

我正在构建一个自定义录像机,并注意到如果手机在相机活动运行时进入睡眠或锁定模式.. 唤醒时相机预览卡在静态静止图像上。如果我在活动之间来回走动,相机在返回时就可以了。这个错误显然只在手机进入睡眠状态并醒来时才会出现。

我的录像机活动

public class DRPVideoCaptureActivity extends Activity {

    private Camera myCamera;
    private DRPCameraSurfaceView myCameraSurfaceView;
    private MediaRecorder mediaRecorder;

    SurfaceHolder surfaceHolder;
    boolean recording = false;

    Globals g = new Globals();
    ImageButton btn_record;
    FrameLayout _videoView;

    ImageView btn_flashToggle;
    ImageView btn_cameraToggle;
    ImageView btn_close;

    public enum FlashState {
        off, on, auto
    }

    FlashState _flashState = FlashState.off;

    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.video_camera);

        _videoView = (FrameLayout) findViewById(R.id.video_frame);
        btn_record = (ImageButton) findViewById(R.id.btn_record);
        btn_flashToggle = (ImageView) findViewById(R.id.btn_flash_toggle);
        btn_cameraToggle = (ImageView) findViewById(R.id.btn_camera_toggle);
        btn_close = (ImageView) findViewById(R.id.btn_close);
        recording = false;


        // myButton = (Button)findViewById(R.id.mybutton);

    }

    @Override
    public void onResume() {
        super.onResume();
        // Get Camera for preview
        _videoView.setVisibility(View.INVISIBLE);
        myCamera = getCameraInstance();
        if (myCamera == null) {
            Toast.makeText(DRPVideoCaptureActivity.this, "Fail to get Camera",
                    Toast.LENGTH_LONG).show();
        }else{

            myCameraSurfaceView = new DRPCameraSurfaceView(this, myCamera);
            _videoView.addView(myCameraSurfaceView);
        }

        _videoView.setVisibility(View.VISIBLE);

    }

    Button.OnClickListener recordListener = new Button.OnClickListener() {

        @Override
        public void onClick(View arg0) {
            // TODO Auto-generated method stub
            if (recording) {
                // stop recording and release camera
                mediaRecorder.stop(); // stop the recording
                releaseMediaRecorder(); // release the MediaRecorder object

                // Exit after saved
                finish();
            } else {

                // Release Camera before MediaRecorder start
                releaseCamera();

                if (!prepareMediaRecorder()) {
                    Toast.makeText(DRPVideoCaptureActivity.this,
                            "Fail in prepareMediaRecorder()!\n - Ended -",
                            Toast.LENGTH_LONG).show();
                    finish();
                }

                mediaRecorder.start();
                recording = true;
                // myButton.setText("STOP");
            }
        }
    };

    private Camera getCameraInstance() {
        // TODO Auto-generated method stub
        Camera c = null;
        try {

            c = Camera.open(); // attempt to get a Camera instance
            c.setDisplayOrientation(90);
        } catch (Exception e) {
            Log.v("cam","EXCEPTION: "+e);// Camera is not available (in use or does not exist)
        }
        return c; // returns null if camera is unavailable
    }

    private boolean prepareMediaRecorder() {
        myCamera = getCameraInstance();
        mediaRecorder = new MediaRecorder();

        myCamera.unlock();
        mediaRecorder.setCamera(myCamera);

        mediaRecorder.setAudioSource(MediaRecorder.AudioSource.CAMCORDER);
        mediaRecorder.setVideoSource(MediaRecorder.VideoSource.CAMERA);

        mediaRecorder.setProfile(CamcorderProfile
                .get(CamcorderProfile.QUALITY_HIGH));

        mediaRecorder.setOutputFile(g.kExtStorageDirectory + g.kVideoDirectory
                + "myvideo.mp4");
        mediaRecorder.setMaxDuration(60000); // Set max duration 60 sec.
        mediaRecorder.setMaxFileSize(5000000); // Set max file size 5M

        mediaRecorder.setPreviewDisplay(myCameraSurfaceView.getHolder()
                .getSurface());

        try {
            mediaRecorder.prepare();
        } catch (IllegalStateException e) {
            releaseMediaRecorder();
            return false;
        } catch (IOException e) {
            releaseMediaRecorder();
            return false;
        }
        return true;

    }

    @Override
    protected void onPause() {
        super.onPause();
        releaseMediaRecorder(); // if you are using MediaRecorder, release it
                                // first
        releaseCamera(); // release the camera immediately on pause event

    }

    private void releaseMediaRecorder() {
        if (mediaRecorder != null) {
            mediaRecorder.reset(); // clear recorder configuration
            mediaRecorder.release(); // release the recorder object
            mediaRecorder = null;
            myCamera.lock(); // lock camera for later use
        }
    }

    private void releaseCamera() {
        if (myCamera != null) {
            myCamera.stopPreview();

            myCamera.release(); // release the camera for other applications
            myCamera = null;
        }
    }

}

我的相机表面视图

public class DRPCameraSurfaceView extends SurfaceView implements SurfaceHolder.Callback{

    private SurfaceHolder mHolder;
    private Camera mCamera;

    public DRPCameraSurfaceView(Context context, Camera camera) {
        super(context);
        mCamera = camera;

        // Install a SurfaceHolder.Callback so we get notified when the
        // underlying surface is created and destroyed.
        mHolder = getHolder();
        mHolder.addCallback(this);
        // deprecated setting, but required on Android versions prior to 3.0
        mHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
    }

    @Override
    public void surfaceChanged(SurfaceHolder holder, int format, int weight,
            int height) {
        // If your preview can change or rotate, take care of those events here.
        // Make sure to stop the preview before resizing or reformatting it.

        if (mHolder.getSurface() == null){
          // preview surface does not exist
          return;
        }

        // stop preview before making changes
        try {
            mCamera.stopPreview();
        } catch (Exception e){
          // ignore: tried to stop a non-existent preview
        }

        // make any resize, rotate or reformatting changes here

        // start preview with new settings
        try {
            mCamera.setPreviewDisplay(mHolder);
            mCamera.startPreview();

        } catch (Exception e){
        }
    }

    @Override
    public void surfaceCreated(SurfaceHolder holder) {

        // The Surface has been created, now tell the camera where to draw the preview.
        try {
            mCamera.setPreviewDisplay(holder);
            mCamera.startPreview();
        } catch (IOException e) {
        }
    }

    @Override
    public void surfaceDestroyed(SurfaceHolder holder) {
        this.getHolder().removeCallback(this);
        //mCamera.stopPreview();
       // mCamera.release();
       // mCamera = null;
        Log.v("surfaceDestroyed", "surfaceDestroyed");


    }
}

【问题讨论】:

    标签: android android-camera


    【解决方案1】:

    您正在尝试构建能够从后台录制的应用程序 为此,您必须借助 android 中的服务 还有一个想法是,如果您的相机当前在您的应用程序的后台运行,而另一个应用程序在尝试访问相机时却被您的应用程序占用,那么它会导致该应用程序崩溃,请注意

    请参考此链接以获取后台视频记录:Link 1

    【讨论】:

    • 它没有崩溃.. 相机预览只是静止
    • 我只是给你建议,如果你不从你的应用程序中释放相机,那么其他想要使用相机的应用程序将会崩溃..只是为了你的知识朋友..
    • 对于您的解决方案,您应该在服务中附加视频录制代码,以便它在后台运行。有关 android 服务的更多信息,请在此处找到。 developer.android.com/reference/android/app/Service.html
    猜你喜欢
    • 2014-05-27
    • 1970-01-01
    • 2013-04-22
    • 1970-01-01
    • 2021-02-22
    • 2022-11-13
    • 2012-10-08
    • 2023-03-30
    • 2011-02-10
    相关资源
    最近更新 更多