使用Android Camera框架我发现了一个问题:如果我尝试使用以下代码从后向前切换相机
releaseMediaRecorder();
releaseCamera();
if(currentCameraId == Camera.CameraInfo.CAMERA_FACING_BACK){
currentCameraId = Camera.CameraInfo.CAMERA_FACING_FRONT;
}
else {
currentCameraId = Camera.CameraInfo.CAMERA_FACING_BACK;
}
mCamera = Camera.open(currentCameraId);
mCamera.setPreviewCallback(null);
try {
mCamera.setPreviewDisplay(mPreview.getHolder());
} catch (IOException e) {
e.printStackTrace();
}
mCamera.startPreview();
除预览尺寸外,一切正常。事实上,我已经在我的Preview类中实现了一个获得最佳预览大小的函数,但是在这段代码中没有调用,因为我应该像在onResume方法中那样得到一个新的Preview实例:
@Override
protected void onResume() {
super.onResume();
try {
mCamera = Camera.open(currentCameraId);
mCamera.setPreviewCallback(null);
mPreview = new CameraPreview(this, mCamera);
preview.addView(mPreview);
mCamera.startPreview();
} catch (Exception e) {
Log.d(TAG, "Error starting camera preview: " + e.getMessage());
}
}
如果我执行onResume方法,一切正常,但如果我在切换摄像头代码中复制mPreview = new CameraPreview(this, mCamera);
和preview.addView(mPreview);
,Log会告诉我“D / Camera:app传递NULL表面”。
为什么呢?
- 编辑 -
我在CameraPreview类中实现了SurfaceHolder.Callback
public class CameraPreview extends SurfaceView implements SurfaceHolder.Callback {
private SurfaceHolder mHolder;
private Camera mCamera;
private static final String TAG = CameraPreview.class.getName();
Camera.Parameters params;
private float mDist;
public CameraPreview(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();
// deprecated setting, but required on Android versions prior to 3.0
mHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
mHolder.addCallback(this);
}
public void surfaceChanged(SurfaceHolder holder, int format, int w, int h) {
// 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
}
// set preview size and make any resize, rotate or
// reformatting changes here
params = mCamera.getParameters();
params.setWhiteBalance(Camera.Parameters.WHITE_BALANCE_AUTO);
params.setExposureCompensation(0);
mCamera.setParameters(params);
// start preview with new settings
try {
mCamera.setPreviewDisplay(mHolder);
mCamera.startPreview();
} catch (Exception e){
Log.d(TAG, "Error starting camera preview: " + e.getMessage());
}
}
// When the surface is ready then we can build the camera and attach
// the camera preview output to the UI holder
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) {
Log.d(TAG, "Error setting camera preview: " + e.getMessage());
}
}
public void surfaceDestroyed(SurfaceHolder holder) {
// empty. Take care of releasing the Camera preview in your activity.
if (mCamera != null) {
this.getHolder().removeCallback(this);
mCamera.stopPreview();
mCamera.setPreviewCallback(null);
mCamera.release();
mCamera = null;
}
}
private Camera.Size getOptimalPreviewSize(List<Camera.Size> sizes, int w, int h) {
final double ASPECT_TOLERANCE = 0.1;
double targetRatio = (double) w / h;
if (sizes == null)
return null;
Camera.Size optimalSize = null;
double minDiff = Double.MAX_VALUE;
int targetHeight = h;
// Try to find an size match aspect ratio and size
for (Camera.Size size : sizes) {
double ratio = (double) size.width / size.height;
if (Math.abs(ratio - targetRatio) > ASPECT_TOLERANCE)
continue;
if (Math.abs(size.height - targetHeight) < minDiff) {
optimalSize = size;
minDiff = Math.abs(size.height - targetHeight);
}
}
// Cannot find the one match the aspect ratio, ignore the requirement
if (optimalSize == null) {
minDiff = Double.MAX_VALUE;
for (Camera.Size size : sizes) {
if (Math.abs(size.height - targetHeight) < minDiff) {
optimalSize = size;
minDiff = Math.abs(size.height - targetHeight);
}
}
}
return optimalSize;
}
答案 0 :(得分:0)
我添加了这行代码解决了这个问题
mPreview = new CameraPreview(context, mCamera);
preview.addView(mPreview);
之前
try {
mCamera.setPreviewDisplay(mPreview.getHolder());
} catch (IOException e) {
e.printStackTrace();
}
并将preview.removeView(mPreview);
添加到releaseCamera()方法