我正在为我的应用编写自定义相机。使用后置或前置摄像头打开活动时,它工作正常。但我真的很难在活动中切换相机。
当我点按切换相机按钮时,预览冻结,没有任何反应。我已经尝试了与相机和预览相关的其他问题中提出的答案和提示,但没有任何效果。
这是我的活动:
public class CameraActivity extends Activity implements SurfaceHolder.Callback {
//================================================================================
// Properties
//================================================================================
// Tag
private final String TAG = "CameraActivity";
// Camera and CameraPreview objects
private Camera mCamera;
// SurfaceHolder object
private SurfaceHolder mSurfaceHolder;
// private CameraPreview mPreview;
// ImageButtons
private ImageButton captureButton;
private ImageButton camSwitchButton;
// Picture previewLayout
FrameLayout previewLayout;
SurfaceView preview;
// Current camera is facing FRONT or BACK
private int currentCameraId = Camera.CameraInfo.CAMERA_FACING_FRONT;
// Picture taking callback
private Camera.PictureCallback mPictureCallback;
//================================================================================
// Methods
//================================================================================
@Override
public void onCreate(final Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// Activity with no notification bar
requestWindowFeature(Window.FEATURE_NO_TITLE);
// Set content view
setContentView(R.layout.activity_camera);
// Initialize activity and previews
InitActivity();
InitPreview();
// Set onClicks
}
/**
* Initialize activity views
*/
private void InitActivity() {
// Create an instance of Camera
mCamera = GetCameraInstance(currentCameraId);
// Set the SurfaceView
preview = (SurfaceView) findViewById(R.id.camera_preview);
mSurfaceHolder = preview.getHolder();
mSurfaceHolder.addCallback(this);
}
/**
* Initialize the camera preview
*/
private void InitPreview() {
if (mCamera != null) {
try {
mCamera.setPreviewDisplay(mSurfaceHolder);
} catch (IOException e) {
// log
}
mCamera.startPreview();
}
}
@Override
protected void onPause() {
super.onPause();
if (mCamera != null) {
mCamera.stopPreview();
mCamera.release(); // release the camera for other applications
// mCamera = null;
}
}
@Override
protected void onResume() {
super.onResume();
if (mCamera == null) {
InitActivity();
InitPreview();
}
}
/**
* Get camera instance
* @return Camera instance (null if doesn't exist)
*/
private Camera GetCameraInstance(int camid) {
Camera c = null;
try {
c = Camera.open(camid); // attempt to get a Camera instance
Camera.Parameters campar = c.getParameters();
// Set auto-focus
if (getPackageManager().hasSystemFeature("android.hardware.camera.autofocus")) {
campar.setFocusMode(Camera.Parameters.FOCUS_MODE_CONTINUOUS_PICTURE);
}
c.setParameters(campar);
}
catch (Exception e){
// log
}
return c; // returns null if camera is unavailable
}
/**
* Switch the camera from front to back and vica verca
*/
private void SwitchCamera() {
if (mCamera != null) {
mCamera.stopPreview();
mCamera.release();
// mCamera = null;
}
//swap the id of the camera to be used
if (currentCameraId == Camera.CameraInfo.CAMERA_FACING_BACK) {
currentCameraId = Camera.CameraInfo.CAMERA_FACING_FRONT;
}
else currentCameraId = Camera.CameraInfo.CAMERA_FACING_FRONT;
// Remove the view and re-add it
ViewGroup rootView = (ViewGroup) preview.getParent();
rootView.removeView(previewLayout);
mCamera = GetCameraInstance(currentCameraId);
InitActivity();
}
@Override
public void surfaceCreated(SurfaceHolder surfaceHolder) {
Logger.Log(TAG, "SurfaceCreated");
InitPreview();
}
@Override
public void surfaceChanged(SurfaceHolder surfaceHolder, int format, int width, int height) {
// Return if no surface found
if (mSurfaceHolder.getSurface() == null) {
return;
}
// Start preview with new settings
Camera.Parameters params = mCamera.getParameters();
boolean isPortrait = IsPortrait();
// Configure the parameters (so the image is showing correctly)
ConfigureCameraParameters(params, isPortrait);
// Start preview
InitPreview();
}
@Override
public void surfaceDestroyed(SurfaceHolder surfaceHolder) {
if (mCamera != null) {
mCamera.stopPreview();
mCamera.release();
mCamera = null;
}
}
/**
* Configure the camer parameters
* @param cameraParams Camera parameters
* @param isPortrait Is the camera in portrait mode?
*/
protected void ConfigureCameraParameters(Camera.Parameters cameraParams, boolean isPortrait) {
int angle;
Display display = getWindowManager().getDefaultDisplay();
// Correct the orientation
switch (display.getRotation()) {
case Surface.ROTATION_0: // This is display orientation
angle = 90; // This is camera orientation
break;
case Surface.ROTATION_90:
angle = 0;
break;
case Surface.ROTATION_180:
angle = 270;
break;
case Surface.ROTATION_270:
angle = 180;
break;
default:
angle = 90;
break;
}
mCamera.setDisplayOrientation(angle);
mCamera.setParameters(cameraParams);
}
/**
* Check whether the camera is in portrait mode
* @return True|False
*/
private boolean IsPortrait() {
return (getResources().getConfiguration().orientation
== Configuration.ORIENTATION_PORTRAIT);
}
}
清单中的权限:
<uses-permission android:name="android.permission.CAMERA" />
<uses-feature android:name="android.hardware.camera" />
<uses-feature android:name="android.hardware.camera.autofocus" />
如果有人可以提供帮助,我真的很感激。
答案 0 :(得分:1)
你非常接近,每次切换相机时都不需要破坏表面视图,只需要破坏相机会话,然后确保将相机连接回Surfaceview以便显示。我在Razr Max上面向后面的逻辑时遇到了一些问题所以我只是将其切换为1和0。
private void SwitchCamera() {
if (mCamera != null) {
mCamera.stopPreview();
mCamera.release();
mCamera = null;
}
//swap the id of the camera to be used
if (currentCameraId == Camera.CameraInfo.CAMERA_FACING_FRONT) {
currentCameraId = 0;
} else {
currentCameraId = 1;
}
mCamera = GetCameraInstance(currentCameraId);
InitPreview();
}