-1

我想知道是否有人可以帮助我,我是android新手,我正在尝试编写一个小应用程序,显示前置摄像头的摄像头预览,一切正常,但是当我关闭应用程序时手机冻结然后崩溃,我一直在寻找对此的答案,但似乎无法在任何地方找到答案,代码如下

import android.app.Activity;
import android.hardware.Camera;
import android.media.MediaPlayer;
import android.os.Bundle;
import android.os.CountDownTimer;
import android.util.Log;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
import android.view.View;
import android.widget.ImageView;
import android.widget.Toast;

public class PreviewDemo extends Activity {

  private SurfaceView preview=null;
  private SurfaceHolder previewHolder=null;
  private Camera camera=null;
  private boolean inPreview=false;
  private boolean cameraConfigured=false;   
  public ImageView imageview1;
  public MediaPlayer mp;
  public MediaPlayer mp2;
  public MyCountDownTimer counter = new MyCountDownTimer(6000,1000);
  public MyCountDownTimer2 counter2 = new MyCountDownTimer2(2000,1000);


  @Override
  public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.main);
    mp = MediaPlayer.create(PreviewDemo.this, R.raw.shatter);
    mp2 = MediaPlayer.create(PreviewDemo.this, R.raw.beep);
    preview=(SurfaceView)findViewById(R.id.preview);
    previewHolder=preview.getHolder();
    previewHolder.addCallback(surfaceCallback);
    previewHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
    imageview1 = (ImageView) this.findViewById(R.id.imageView1);
    counter2.start();

  }

  @Override
  public void onResume() {
    super.onResume();
    int cameraCount = 0;
    Camera.CameraInfo cameraInfo = new Camera.CameraInfo();
    cameraCount = Camera.getNumberOfCameras();
            for ( int camIdx = 0; camIdx < cameraCount; camIdx++ ) {
        Camera.getCameraInfo( camIdx, cameraInfo );
        if ( cameraInfo.facing == Camera.CameraInfo.CAMERA_FACING_FRONT  ) {
            try {
                camera = Camera.open( camIdx );
                camera.setDisplayOrientation(90);
            } catch (RuntimeException e) {
                ;
            }
        }
    startPreview();
  }
  }
  @Override
  public void onPause() {
    if (inPreview) {
      camera.stopPreview();
    }

    camera.release();
    camera=null;
    inPreview=false;

    super.onPause();
  }
  public void onFinish(){
  }

  private Camera.Size getBestPreviewSize(int width, int height,
                                         Camera.Parameters parameters) {
    Camera.Size result=null;

    for (Camera.Size size : parameters.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);
  }

  private void initPreview(int width, int height) {
    if (camera!=null && previewHolder.getSurface()!=null) {
      try {
        camera.setPreviewDisplay(previewHolder);
      }
      catch (Throwable t) {
        Log.e("PreviewDemo-surfaceCallback",
              "Exception in setPreviewDisplay()", t);
        Toast
          .makeText(PreviewDemo.this, t.getMessage(), Toast.LENGTH_LONG)
          .show();
      }

      if (!cameraConfigured) {
        Camera.Parameters parameters=camera.getParameters();
        Camera.Size size=getBestPreviewSize(width, height,
                                            parameters);

        if (size!=null) {
          parameters.setPreviewSize(size.width, size.height);
          camera.setParameters(parameters);
          cameraConfigured=true;
        }
      }
    }
  }

  private void startPreview() {
    if (cameraConfigured && camera!=null) {
      camera.startPreview();
      inPreview=true;
    }
  }

  SurfaceHolder.Callback surfaceCallback=new SurfaceHolder.Callback() {
    public void surfaceCreated(SurfaceHolder holder) {
      // no-op -- wait until surfaceChanged()
    }

    public void surfaceChanged(SurfaceHolder holder,
                               int format, int width,
                               int height) {
      initPreview(width, height);
      startPreview();
    }

    public void surfaceDestroyed(SurfaceHolder holder) {
        camera.stopPreview();
        camera.setPreviewCallback(null); 
        camera.release();
        camera = null;

    }
  };
  public class MyCountDownTimer extends CountDownTimer{


      public MyCountDownTimer(long millisInFuture, long countDownInterval) {
      super(6000, 1000);
      }

      @Override
      public void onFinish() {
          imageview1.setVisibility(View.VISIBLE); 
          mp.start();
      }

      public void onTick(long millisUntilFinished) {
          mp2.start();
        }

      }

  public class MyCountDownTimer2 extends CountDownTimer{


      public MyCountDownTimer2(long millisInFuture, long countDownInterval) {
      super(2000, 1000);
      }

      @Override
      public void onFinish() {
          counter.start();
      }

      public void onTick(long millisUntilFinished) {

        }

      }
}

提前干杯马克

4

1 回答 1

0

您需要检查是否camera有效,因为您camera = null在多个地方设置,例如onPause()SurfaceViewonSurfaceDestroyed()回调。您的onPause()方法应如下所示:

@Override
public void onPause() {
    if(camera != null) {
        if (inPreview) {
          camera.stopPreview();
        }

        camera.release();
        camera=null;
    }
    inPreview=false;

    super.onPause();
}

同样的逻辑也适用于onSurfaceDestroyed()closeCamera()此外,如果您将此逻辑移动到方法中并从有效位置调用此方法,您的代码可能更易于维护。

于 2012-11-16T17:47:25.653 回答