我正在 Android 中实现自定义摄像头。所有事情都以正确的方式进行,但是当我更改设备的方向时,我的应用程序 Force 关闭并给出错误:
08-29 10:50:31.368: D/AndroidRuntime(2099): Shutting down VM
08-29 10:50:31.368: W/dalvikvm(2099): threadid=1: thread exiting with uncaught exception (group=0x40a13300)
08-29 10:50:31.607: E/AndroidRuntime(2099): FATAL EXCEPTION: main
08-29 10:50:31.607: E/AndroidRuntime(2099):
08-29 10:50:31.607: E/AndroidRuntime(2099): at com.example.customcamera.CameraPreview.surfaceCreated(CameraPreview.java:37)
08-29 10:50:31.607: E/AndroidRuntime(2099): at android.view.SurfaceView.updateWindow(SurfaceView.java:543)
08-29 10:50:31.607: E/AndroidRuntime(2099): at android.view.SurfaceView.access$000(SurfaceView.java:81)
08-29 10:50:31.607: E/AndroidRuntime(2099): at android.view.SurfaceView$3.onPreDraw(SurfaceView.java:169)
08-29 10:50:31.607: E/AndroidRuntime(2099): at android.view.ViewTreeObserver.dispatchOnPreDraw(ViewTreeObserver.java:671)
08-29 10:50:31.607: E/AndroidRuntime(2099): at android.view.ViewRootImpl.performTraversals(ViewRootImpl.java:1820)
08-29 10:50:31.607: E/AndroidRuntime(2099): at android.view.ViewRootImpl.doTraversal(ViewRootImpl.java:1000)
08-29 10:50:31.607: E/AndroidRuntime(2099): at android.view.ViewRootImpl$TraversalRunnable.run(ViewRootImpl.java:4214)
08-29 10:50:31.607: E/AndroidRuntime(2099): at android.view.Choreographer$CallbackRecord.run(Choreographer.java:725)
08-29 10:50:31.607: E/AndroidRuntime(2099): at android.view.Choreographer.doCallbacks(Choreographer.java:555)
我的 CameraPreview 代码是:-
/** A basic Camera preview class */
public class CameraPreview extends SurfaceView implements SurfaceHolder.Callback {
private SurfaceHolder mHolder;
private Camera mCamera;
private Size mPreviewSize;
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();
mHolder.addCallback(this);
// deprecated setting, but required on Android versions prior to 3.0
mHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
}
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.
}
public void surfaceChanged(SurfaceHolder holder, int format, int w, int h) {
Log.d("Function", "surfaceChanged iniciado");
if (mHolder.getSurface() == null){
// preview surface does not exist
return;
}
// stop preview before making changes
try {
if(mCamera!=null){
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
try {
if(mCamera!=null){
//mCamera.setDisplayOrientation(90);
DVCameraActivity a=new DVCameraActivity();
if(a.display.getRotation() == Surface.ROTATION_0)
{
mCamera.setDisplayOrientation(90);
}
if(a.display.getRotation() == Surface.ROTATION_90)
{
//parameters.setPreviewSize(width, height);
}
if(a.display.getRotation() == Surface.ROTATION_180)
{
// parameters.setPreviewSize(height, width);
}
if(a.display.getRotation() == Surface.ROTATION_270)
{
//parameters.setPreviewSize(width, height);
mCamera.setDisplayOrientation(180);
}
Camera.Parameters parameters = mCamera.getParameters();
Camera.Size size = getBestPreviewSize(w, h);
parameters.setPreviewSize(size.width, size.height);
mCamera.setParameters(parameters);
mCamera.startPreview();
}
} catch (Exception e){
// Log.d(TAG, "Error starting camera preview: " + e.getMessage());
}
}
private Camera.Size getBestPreviewSize(int width, int height)
{
Camera.Size result=null;
Camera.Parameters p = mCamera.getParameters();
for (Camera.Size size : p.getSupportedPreviewSizes()) {
if (size.width<=width && size.height<=height) {
if (result==null) {
result=size;
} else {
int resultArea=result.width*result.height;
int newArea=size.width*size.height;
if (newArea>resultArea) {
result=size;
}
}
}
}
return result;
}
public static void setCameraDisplayOrientation(Activity activity,
int cameraId, android.hardware.Camera camera) {
android.hardware.Camera.CameraInfo info = new android.hardware.Camera.CameraInfo();
android.hardware.Camera.getCameraInfo(cameraId, info);
int rotation = activity.getWindowManager().getDefaultDisplay().getRotation();
int degrees = 0;
switch (rotation) {
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;
}
int result;
if (info.facing == Camera.CameraInfo.CAMERA_FACING_FRONT) {
result = (info.orientation + degrees) % 360;
result = (360 - result) % 360; // compensate the mirror
} else { // back-facing
result = (info.orientation - degrees + 360) % 360;
}
camera.setDisplayOrientation(result);
}
}
我的主要活动是:-
public class DVCameraActivity extends Activity {
private Camera mCamera;
private CameraPreview mCameraPreview;
public static final int MEDIA_TYPE_IMAGE = 1;
Display display;
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_dvcamera);
display = getWindowManager().getDefaultDisplay();
mCamera = getCameraInstance();
mCameraPreview = new CameraPreview(this, mCamera);
FrameLayout preview = (FrameLayout) findViewById(R.id.camera_preview);
preview.addView(mCameraPreview);
//Adding listener
Button captureButton = (Button) findViewById(R.id.button_capture);
captureButton.setOnClickListener(
new View.OnClickListener() {
@Override
public void onClick(View v) {
mCamera.takePicture(null, null, mPicture);
}
});
}
/**
* Helper method to access the camera returns null if
* it cannot get the camera or does not exist
* @return
*/
private Camera getCameraInstance() {
Camera camera = null;
try {
camera = Camera.open();
} catch (Exception e) {
// cannot get camera or does not exist
}
return camera;
}
PictureCallback mPicture = new PictureCallback() {
@Override
public void onPictureTaken(byte[] data, Camera camera) {
File pictureFile = getOutputMediaFile(MEDIA_TYPE_IMAGE);
if (pictureFile == null){
return;
}
try {
FileOutputStream fos = new FileOutputStream(pictureFile);
fos.write(data);
fos.close();
} catch (FileNotFoundException e) {
} catch (IOException e) {
}
}
};
/** Create a File for saving the image */
private static File getOutputMediaFile(int type){
File mediaStorageDir = new File(Environment.getExternalStoragePublicDirectory(
Environment.DIRECTORY_PICTURES), "MyCameraApp");
if (! mediaStorageDir.exists()){
if (! mediaStorageDir.mkdirs()){
Log.d("MyCameraApp", "failed to create directory");
return null;
}
}
// Create a media file name
String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss").format(new Date());
File mediaFile;
mediaFile = new File(mediaStorageDir.getPath() + File.separator +
"IMG_"+ timeStamp + ".jpg");
return mediaFile;
}
}