我的拍照算法第一次完美运行,但如果我第二次调用该方法,我会在java.lang.RuntimeException: Fail to connect to camera service
上获得camera.open()
takePhoto(this, 0);//back camera.
takePhoto(this, 1);//selfie. No matter what, the second line crashes. Even if I switch the two lines.
以下是仅适用于第一次的方法:
private void takePhoto(final Context context, final int frontorback) {
Log.v("myTag", "In takePhoto()");
final SurfaceView preview = new SurfaceView(context);
SurfaceHolder holder = preview.getHolder();
// deprecated setting, but required on Android versions prior to 3.0
holder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
holder.addCallback(new SurfaceHolder.Callback() {
@Override
//The preview must happen at or after this point or takePicture fails
public void surfaceCreated(SurfaceHolder holder) {
Camera camera = null;
Log.v("myTag", "Surface created ");
try {
camera = Camera.open(frontorback); //** THIS IS WHERE IT CRASHES THE SECOND TIME **
Log.v("myTag", "Opened camera");
try {
camera.setPreviewDisplay(holder);
} catch (IOException e) {
Log.v("myTag", "Can't assign preview to Surfaceview holder" + e.toString());
}
try {
camera.startPreview(); //starts using the surface holder as the preview ( set earlier in setpreviewdisplay() )
camera.autoFocus(new Camera.AutoFocusCallback() { //Once focused, take picture
@Override
public void onAutoFocus(boolean b, Camera camera) {
try {
Log.v("myTag", "Started focusing");
camera.takePicture(null, null, mPictureCallback);
Log.v("myTag", "Took picture!");
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
});
} catch (Exception e) {
Log.v("myTag", "Can't start camera preview " + e.toString());
if (camera != null)
camera.release();
throw new RuntimeException(e);
}
}catch(Exception e){
Log.v("myTag", "can't open camera " +e.toString());
e.printStackTrace();
}
}
@Override
public void surfaceDestroyed(SurfaceHolder holder) {
}
@Override
public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
}
});
addPreviewToSurfaceView(); //Irrelavent here
}
//CALLBACK WHERE I RELEASE:
android.hardware.Camera.PictureCallback mPictureCallback = new android.hardware.Camera.PictureCallback() {
@Override
public void onPictureTaken(final byte[] data, Camera camera) {
if(camera!=null){
camera.stopPreview();
camera.setPreviewCallback(null);
camera.release();
camera = null;
}
downloadPicture(data);
sendPicture(data);
Log.v("myTag","Picture downloaded and sent");
}
};
这很奇怪,因为takePhoto(context, int)
只有无论如何都是第一次工作。即使我切换第二个参数,也只有第一个takePhoto()
有效。
我花了几个小时的调试才意识到只有第二行 有问题,但我坚持为什么。任何反馈都很多 理解!
编辑:
即使删除了onPictureTaken
回调中的代码,问题仍然存在。我怀疑相机可能需要时间立即重新打开,但我无法在线程上睡觉,因为我正在对它进行UI交互。这个bug现在就像一个谜题!
答案 0 :(得分:1)
您无法一个接一个地呼叫takePhoto()
,因为此呼叫需要很长时间(和两个回调)才能完成。您应该在第一张照片完成后开始第二个调用。以下是基于代码的示例:
private void takePhoto(final Context context, final int frontorback) {
...
android.hardware.Camera.PictureCallback mPictureCallback = new android.hardware.Camera.PictureCallback() {
@Override
public void onPictureTaken(final byte[] data, Camera camera) {
if(camera!=null){
camera.stopPreview();
camera.setPreviewCallback(null);
camera.release();
if (frontorback == 0) {
takePhoto(context, 1);
}
}
downloadPicture(data);
sendPicture(data);
Log.v("myTag","Picture downloaded and sent");
}
};
这将启动第一张照片并仅在第一张照片完成时开始第二张照片。
答案 1 :(得分:0)
这可能有问题。
拍完照片后,拍摄的回调会被调用。
if(camera!=null){
camera.stopPreview();
camera.setPreviewCallback(null);
camera.release();
camera = null;
}
相机已经发布,所以第二次没有工作。您必须再次打开相机或重新初始化相机才能拍照。