相机在手机睡眠/唤醒时冻结

时间:2014-02-19 16:37:02

标签: android android-camera

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

我的录像机活动

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");


    }
}

1 个答案:

答案 0 :(得分:0)

你正在尝试构建能够从后台录制的应用程序 为此你必须在android中获得服务的帮助 还有一个想想,如果你的相机当前在你的应用程序和其他应用程序的后台运行时试图访问相机,但它占用你的应用程序然后它会导致崩溃,你的建议的应用程序要小心

从背景中引用此链接获取视频记录:Link 1