android - 如何在同一个 Activity 中使用 Camera 和 MediaRecorder?

标签 android nullpointerexception camera surfaceview mediarecorder

我是 Android 开发新手,我正在尝试制作一个可以拍照和录制视频的自定义相机。我已经能够成功捕获图像,但是当我尝试将相机切换到媒体记录器时,我收到一个 NullPointerException,上面写着“java.lang.RuntimeException:无法连接到相机服务” “。在我尝试切换到媒体之前,我释放了相机,并且我的 list 中拥有正确的权限,因此我无法弄清楚它崩溃的原因。非常感谢任何帮助。

我的代码:

//Starting Camera
@Override
public void onResume(){
    super.onResume();
    if(is_photo_mode){ //8/4/2014
        setSurface();
    }
}

private void setSurface() {
    SurfaceView previewSurfaceView = (SurfaceView)findViewById(R.id.preview_surface);
    previewSurfaceView.getHolder().addCallback(shCallback);
}

private SurfaceHolder.Callback shCallback = new SurfaceHolder.Callback() {

    @Override
    public void surfaceDestroyed(SurfaceHolder holder) {
        Log.i(LOG_TAG, "surfaceDestroyed callback");
        if (camera != null) {
            camera.stopPreview();
            camera.release();
        }
        camera = null;
    }

    @Override
    public void surfaceCreated(SurfaceHolder holder) {
        Log.i(LOG_TAG, "surfaceCreated callback"); 
        startCamera(1-cameraId);            
    }

    @Override
    public void surfaceChanged(SurfaceHolder holder, int format, int width,
            int height) {
        Log.i(LOG_TAG, "surfaceChanged callback " + width + "x" + height);
        if(is_photo_mode){   //8/4/2014
            restartPreview();
        }
    }
  };

  protected void startCamera(final int id) {

    releaseCamera();

    new AsyncTask<Integer, Void, Camera>() {

        @Override
        protected Camera doInBackground(Integer... ids) {
            return openCamera(ids[0]);
        }

        @Override
        protected void onPostExecute(Camera c) {
            if(is_photo_mode){
                startPreview(id, c);
            }else{
                prepareMediaRecorder();
            }
        }

    }.execute(id);
}

private static Camera openCamera(int id) {
    Log.d(LOG_TAG, "opening camera " + id);
    Camera camera = null;
    try {
        camera = Camera.open(id);
        Log.d(LOG_TAG, "opened camera " + id);
    } catch (Exception e) {
        e.printStackTrace();
        camera.release();
        camera = null;
    }
    return camera;
}

private void startPreview(int id, Camera c) {
    if (c != null) {
        try {
            SurfaceView previewSurfaceView = (SurfaceView)findViewById(R.id.preview_surface);
            SurfaceHolder holder = previewSurfaceView.getHolder();
            c.setPreviewDisplay(holder);
            camera = c; 
            cameraId = id;
            restartPreview();
        } catch (IOException e) {
            e.printStackTrace();
            c.release();
        }
    }
}


private void restartPreview() {
    if (camera == null) {
        return;
    }
    int degrees = 0;
    switch (getWindowManager().getDefaultDisplay().getRotation()) {
    case Surface.ROTATION_0: 
        degrees = 0;
        break;
    case Surface.ROTATION_90: 
        degrees = 90;
        break;
    case Surface.ROTATION_180:
        degrees = 180;
        break;
    case Surface.ROTATION_270:
        degrees = 270;
        break;
    }
    Camera.CameraInfo ci = new Camera.CameraInfo();
    Camera.getCameraInfo(cameraId, ci);
    if (ci.facing == Camera.CameraInfo.CAMERA_FACING_FRONT) {
        degrees += ci.orientation;
        degrees %= 360;
        degrees = 360 - degrees;
        front_facing_camera = true;

    }else {
        degrees = 360 - degrees;
        degrees += ci.orientation;
        front_facing_camera = false;

    }
    camera.setDisplayOrientation(degrees%360);
    camera.startPreview();

    Camera.Parameters params = camera.getParameters();
    if(params.isZoomSupported()){
        Log.e("ZOOM", "Enabled");
    }else{
        Log.e("ZOOM", "Disabled");
        zoom_in.setVisibility(View.GONE);
        zoom_out.setVisibility(View.GONE);
    }

}

//SWITCHING FROM CAMERA TO VIDEO
else if (v.getId() == R.id.mode_button) {
        if(is_photo_mode){
            is_photo_mode = false;
            mode_select.setText("VID");
            Log.e("MODE", "video");
        }else{
            is_photo_mode = true;
            mode_select.setText("CAM");
            Log.e("MODE", "photo");
        }
        switchMode();
    }

 public void switchMode() {
    startCamera( cameraId);
}

private boolean prepareMediaRecorder(){
    camera = getCameraInstance();

     Parameters parameters = camera.getParameters(); //<--NullPointerException here
     //parameters.setFlashMode(getFlashModeSetting());
     camera.setParameters(parameters);

     mediaRecorder = new MediaRecorder();

     camera.unlock();
     mediaRecorder.setCamera(camera);

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

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

     mediaRecorder.setOutputFile("/sdcard/myvideo.mp4");
     mediaRecorder.setMaxDuration(20000); // Set max duration 60 sec.
     mediaRecorder.setMaxFileSize(5000000); // Set max file size 5M

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

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

 }

private Camera getCameraInstance(){
      // TODO Auto-generated method stub
           Camera c = null;
           try {
               c = Camera.open(); // attempt to get a Camera instance <--This fails
           }
           catch (Exception e){
               // Camera is not available (in use or does not exist)
               e.printStackTrace();
               Log.e("CAMERA FAIL", e.toString()); //<-- java.lang.RuntimeException: Fail to connect to camera service

           }
           return c; // returns null if camera is unavailable
     }

最佳答案

您是否尝试过在 onDestroy 方法中从表面 View 释放相机?

关于android - 如何在同一个 Activity 中使用 Camera 和 MediaRecorder?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25122917/

相关文章:

android - phonegap 中格式错误的 config.xml 错误

java - 安卓相机,焦点 slider

Android:以编程方式启用/禁用应用程序小部件

java - 如何在 firestore 中点击 URL 时在 firebase 存储上上传 2 张图像

android - requestLocationUpdate() 抛出的 IllegalArgumentException

Android异常: java. io.IOException:打开失败:EACCES(权限被拒绝)

ios - 类型 'CMSampleBuffer' 的值没有成员 'imageBuffer'

java - android Intent 给出空指针异常

java - 遇到java.lang.NullPointerException

java - getExternalFilesDir(null) 抛出 NullPointerException