0

我正在尝试在 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;
}

}

4

2 回答 2

0

如果不遵循调试器中的代码,很难判断实际发生了什么,但您可能调用Camera.release()了太多次。可能存在NullPointerExeception阻止正常关机的地方。您的应用程序中应该只有一个版本,并且onPause()是一个完美的调用位置releaseCamera()。我不明白为什么你需要覆盖onBackPressed()finish()不建议从这个覆盖调用,调用System.exit()更是如此。另外,我会将呼叫移至getCameraInstance()onResume()可能移至onStart()

于 2013-10-08T08:53:37.850 回答
0

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

于 2013-10-08T09:05:19.707 回答