我是Android开发的菜鸟,我正在尝试制作一个自定义相机,拍摄照片并录制视频。我已经能够成功捕获图像但是当我尝试将相机切换到媒体记录器时,我得到一个NullPointerException,它说" java.lang.RuntimeException:无法连接到相机服务 &#34 ;.在我尝试切换到媒体之前,我释放了相机并且我在清单中拥有正确的权限,因此我无法弄清楚它崩溃的原因。非常感谢任何帮助。
我的代码:
//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
}
答案 0 :(得分:1)
您是否尝试从onDestroy方法的表面视图中释放相机?
答案 1 :(得分:1)
我可能是一个&#34; bit&#34;我迟到但我一直在努力解决类似的问题。当我尝试从MediaRecorder
切换回照片模式时,我实际上遇到了同样的崩溃。我刚刚玩过相机方法stopPreview()
,release()
和lock()\unlock()
,有人说它有助于将相机/录像机实例设置为空位,但我不知道为什么或如果它无论如何 - 相机生命周期并不是一个简单的过程,特别是如果你想同时用于视频和照片 - 确保你有这些方法应该在哪里。