返回活动时,相机为空

时间:2015-11-21 03:17:15

标签: android android-activity android-camera

所以我跟着Android开发人员构建了一个摄像头应用程序示例,让我的摄像头活动正常运行。然而,当我去另一个活动然后点击后退按钮我发生了崩溃,因为相机在表面创建的表面视图中为空。有人可以解释这个错误是如何发生的。谢谢!

**活动

public class PhotoCaptureActivity extends AppCompatActivity implements View.OnClickListener{

    public static final String TAG = "PhotoCaptureActivity";

    CameraPreview mPreviewScreen;
    Button mCaptureButton;
    ImageView mPreviewThumbnail;
    TextView mPhotoActionLabel;
    TextView mImageLogText;
    Camera mCamera;
    Camera.PictureCallback mPicture;

    ArrayList<Bitmap> mPictures  = new ArrayList<>();

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_photo_capture);

        getSupportActionBar().hide();

        mCaptureButton = (Button) findViewById(R.id.button_capture);
        mPreviewThumbnail = (ImageView) findViewById(R.id.thumb_nail_image);
        mPhotoActionLabel = (TextView) findViewById(R.id.photo_action_text);
        mImageLogText = (TextView) findViewById(R.id.image_log);

        mPicture = new Camera.PictureCallback() {

            @Override
            public void onPictureTaken(byte[] data, Camera camera) {
                BitmapFactory.Options scalingOptions = new BitmapFactory.Options();
                scalingOptions.inSampleSize = camera.getParameters().getPictureSize().width / mPreviewThumbnail.getMeasuredWidth();
                final Bitmap bmp = BitmapFactory.decodeByteArray(data, 0, data.length, scalingOptions);
                mPictures.add(bmp);
                mPreviewThumbnail.setImageBitmap(bmp);
                mPreviewThumbnail.setVisibility(ImageView.VISIBLE);
                mCamera.startPreview();
                mPhotoActionLabel.setText(getString(R.string.done));
            }
        };

        mCaptureButton.setOnClickListener(this);
        mPhotoActionLabel.setOnClickListener(this);
        mImageLogText.setOnClickListener(this);
    }

    public static Camera getCameraInstance(){
        Camera c = null;
        try {
            c = Camera.open(); // attempt to get a Camera instance
        }
        catch (Exception e){
            e.printStackTrace();
        }
        return c; // returns null if camera is unavailable
    }

    @Override
    public void onClick(View v) {
        switch (v.getId()){
            case R.id.button_capture:
                mCamera.takePicture(null, null, mPicture);
                break;
            case R.id.photo_action_text:
                if (mPhotoActionLabel.getText().toString().equalsIgnoreCase(getString(R.string.cancel)))
                    finish();
                else {
                    Intent photoReviewIntent = new Intent(this,PhotoReviewActivity.class);
                    startActivity(photoReviewIntent);
                }
                break;
            case R.id.image_log:
                Intent imageLogIntent = new Intent(this,ImageLogActivity.class);
                startActivity(imageLogIntent);
                break;
        }
    }

    @Override
    public void onPause(){
        super.onPause();
        mCamera.stopPreview();
        mCamera.release();
    }

    @Override
    public void onResume(){
        super.onResume();
        if (getPackageManager().hasSystemFeature(PackageManager.FEATURE_CAMERA)){
            mCamera = getCameraInstance();
            if (mCamera != null){
                mPreviewScreen = new CameraPreview(this,mCamera);
                FrameLayout frameLayout = (FrameLayout) findViewById(R.id.camera_preview);
                frameLayout.addView(mPreviewScreen);
            }
            else
                Toast.makeText(this, R.string.failed_to_open_camera, Toast.LENGTH_LONG).show();
        }
        else
            Toast.makeText(this, R.string.no_camera_available, Toast.LENGTH_LONG).show();
    }
}

**预览屏幕java类

public class CameraPreview extends SurfaceView implements SurfaceHolder.Callback {

    private SurfaceHolder mHolder;
    private Camera mCamera;

    public CameraPreview(Context context, Camera camera) {
        super(context);
        this.mCamera = camera;
        mHolder = getHolder();
        mHolder.addCallback(this);
        mHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
    }

    @Override
    public void surfaceCreated(SurfaceHolder holder) {
        // The Surface has been created, now tell the camera where to draw the preview.
        try {
            mCamera.setPreviewDisplay(holder);
            mCamera.setDisplayOrientation(90);
            mCamera.startPreview();
        } catch (IOException e) {
            Log.i("Error starting camera", e.getLocalizedMessage());
        }
    }

    @Override
    public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {

        if (mHolder.getSurface() == null){
            // preview surface does not exist
            return;
        }

        // stop preview before making changes
        try {
            mCamera.stopPreview();
        } catch (Exception e){
        }

        try {
            mCamera.setPreviewDisplay(mHolder);
            mCamera.startPreview();

        } catch (Exception e){
            Log.i("Error starting camera", e.getLocalizedMessage());
        }
    }

    @Override
    public void surfaceDestroyed(SurfaceHolder holder) {
        //Handeled in activity
    }
}

1 个答案:

答案 0 :(得分:1)

onResume()中,旧的 mPreviewScreen 可能仍然存在,并会导致问题。请考虑将以下内容添加到onPause()

if (mPreviewScreen != null) {
    FrameLayout frameLayout = (FrameLayout) findViewById(R.id.camera_preview);
    frameLayout.removeView(mPreviewScreen);
    mPreviewScreen = null;
}
mCamera = null;