Android上的相机预览

时间:2013-10-07 17:33:25

标签: android android-camera

我正在尝试在Android上制作相机应用程序,Log-cat中没有错误但是当我按下后退按钮时应用程序没有关闭;如果我想在停止后打开另一个应用程序相机;相机被锁定!!任何提示或想法? 提前谢谢。

    public class Capture extends Activity {
    private Camera mCamera;
    private ViewCamera mPreview;
    public static final int MEDIA_TYPE_IMAGE = 1;

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.camera);
        releaseCamera();
        // Create an instance of Camera
        mCamera = getCameraInstance();
        Log.d("EyeSeeJD", "getCameraInstance");

        // Create our Preview view and set it as the content of our activity.
        mPreview = new ViewCamera(this, mCamera);
        FrameLayout preview = (FrameLayout) findViewById(R.id.frame);
        Log.d("EyeSeeJD", "addview ");

        preview.addView(mPreview);
    }

    /** A safe way to get an instance of the Camera object. */
    public static Camera getCameraInstance() {
        Camera c = null;
        try {
            c = Camera.open(); // attempt to get a Camera instance
            // c.lock();
        } catch (Exception e) {
            // Camera is not available (in use or does not exist)
            Log.d("EyeSeeJD", "can't open camera ");

        }
        return c; // returns null if camera is unavailable
    }

    /** Create a File for saving an image or video */
    private static File getOutputMediaFile(int type) {
        // To be safe, you should check that the SDCard is mounted
        // using Environment.getExternalStorageState() before doing this.

        File mediaStorageDir = new File(
                Environment
                        .getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES),
                "MyCameraApp");
        // This location works best if you want the created images to be shared
        // between applications and persist after your app has been uninstalled.

        // Create the storage directory if it does not exist
        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;
        if (type == MEDIA_TYPE_IMAGE) {
            mediaFile = new File(mediaStorageDir.getPath() + File.separator
                    + "IMG_" + timeStamp + ".jpg");
        } else {
            return null;
        }

        return mediaFile;
    }

    private PictureCallback mPicture = new PictureCallback() {

        @Override
        public void onPictureTaken(byte[] data, Camera camera) {

            File pictureFile = getOutputMediaFile(MEDIA_TYPE_IMAGE);
            if (pictureFile == null) {
                Log.d("EyeSeeJD",
                        "Error creating media file, check storage permissions ");
                return;
            }

            try {

                FileOutputStream fos = new FileOutputStream(pictureFile);
                fos.write(data);
                fos.close();
            } catch (FileNotFoundException e) {
                Log.d("EyeSeeJD", "File not found: " + e.getMessage());
            } catch (IOException e) {
                Log.d("EyeSeeJD", "Error accessing file: " + e.getMessage());
            }
        }

    };

    @Override
    protected void onResume() {
        super.onResume();
        /*
         * if (mCamera == null) { releaseCamera(); // release the camera
         * immediately on pause event System.exit(0); }
         */
    }

    @Override
    protected void onPause() {
        super.onPause();
        releaseCamera(); // release the camera immediately on pause event
        // System.exit(0);
    }

    private void releaseCamera() {
        if (mCamera != null) {
            mCamera.stopPreview();
            mCamera.setPreviewCallback(null);
            mPreview.getHolder().removeCallback(mPreview);
            // mCamera.unlock();
            mCamera.release(); // release the camera for other applications
            mCamera = null;

        }
    }

    @Override
    public void onBackPressed() { // TODO Auto-generated methodstub
        super.onBackPressed();
        //mCamera.setPreviewCallback(null);
        //mPreview.getHolder().removeCallback(mPreview);
        mCamera.stopPreview();
        mCamera.release(); // release the camera for other applications
        mCamera = null;
        finish();
        System.exit(0);
    }

    @Override
    public boolean onTouchEvent(MotionEvent event) {
        // TODO Auto-generated method stub
        //mCamera.setPreviewCallback(null);
        mCamera.takePicture(null, null, mPicture);
        //mCamera.release();
    //  mCamera.startPreview();
        return super.onTouchEvent(event);
    }

    @Override
    protected void onDestroy() {
        // TODO Auto-generated method stub
        super.onDestroy();
        mCamera.stopPreview();
        mCamera.setPreviewCallback(null);
        mPreview.getHolder().removeCallback(mPreview);
        mCamera.release(); // release the camera for other applications
        mCamera = null;
        finish();
        System.exit(0);
    }

}

ViewCamera.java

public class ViewCamera extends SurfaceView implements SurfaceHolder.Callback {
private SurfaceHolder mHolder = null;
private Camera mCamera = null;

public ViewCamera(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);
    mHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);

}

@Override
public void surfaceCreated(SurfaceHolder holder) {
    // TODO Auto-generated method stub
    // 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("EyeSeeJD", "Error setting camera preview: " + e.getMessage());
    }
}

// check if device has camera
private boolean checkCameraHardware(Context context) {
    if (context.getPackageManager().hasSystemFeature(
            PackageManager.FEATURE_CAMERA)) {
        // this device has a camera
        Log.d("EyeSeeJd", "there is a camera ");

        return true;
    } else {
        // no camera on this device
        Log.d("EyeSeeJd", "there is no camera ");

        return false;
    }
}

@Override
public void surfaceChanged(SurfaceHolder holder, int format, int w, int h) {
    // TODO Auto-generated method stub
    // 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
    /*Camera.Parameters parameters = mCamera.getParameters();
    parameters.setPreviewSize(320, 480);
    mCamera.setParameters(parameters);*/
    // start preview with new settings
    try {

        mCamera.setPreviewDisplay(mHolder);
        mCamera.startPreview();
        // mCamera.unlock();
    } catch (Exception e) {
        Log.d("EyeSeeJd",
                "Error starting camera preview: " + e.getMessage());
    }
}

@Override
public void surfaceDestroyed(SurfaceHolder arg0) {
    // TODO Auto-generated method stub
    // empty. Take care of releasing the Camera preview in your activity.

    this.getHolder().removeCallback(this);
    mCamera.stopPreview();
    mCamera.release();
    mCamera = null;
}

}

2 个答案:

答案 0 :(得分:0)

如果不在调试器中关注代码,很难说出真正发生了什么,但有可能会多次调用Camera.release()。某处可能有NullPointerExeception阻止正常关机。您的应用中应该只有一个版本,onPause()是拨打releaseCamera()的理想场所。我不明白为什么你需要覆盖onBackPressed(),不建议从此覆盖调用finish(),并且更多地调用System.exit()。另外,我会将来电转至getCameraInstance()onResume()或致onStart()

答案 1 :(得分:0)

你的应用程序在按下时需要时间关闭的原因是你的应用程序崩溃了,因为在onBackPressed()方法中你将mCamera设置为null,而在onDestroy()中你再次使用它来停止和释放相机。