启动Activy时Android camera startPreview失败

启动Activy时Android camera startPreview失败,android,android-camera,surfaceview,Android,Android Camera,Surfaceview,我有一个用于相机预览的自定义SurfaceView。当我启动带有它的活动时,应用程序崩溃,运行时异常显示:startPreview failed,surfaceChanged方法中出现摄像头错误1。发生了什么?下面是我的表面视图和一项活动 public class CameraView extends SurfaceView implements SurfaceHolder.Callback { private Path mClipPath; private Camera mC

我有一个用于相机预览的自定义SurfaceView。当我启动带有它的活动时,应用程序崩溃,运行时异常显示:
startPreview failed
,surfaceChanged方法中出现摄像头错误1。发生了什么?下面是我的表面视图和一项活动

public class CameraView extends SurfaceView implements SurfaceHolder.Callback {

    private Path mClipPath;
    private Camera mCamera;
    private Context mContext;
    private SurfaceHolder mHolder;

    public CameraView(Context context) {
        super(context);
        init(context);
    }

    public CameraView(Context context, Camera camera) {
        super(context);
        mCamera = camera;
        mHolder = getHolder();
        mHolder.addCallback(this);
        init(context);
    }

    public CameraView(Context context, AttributeSet attrs) {
        super(context, attrs);
        init(context);
    }

    public CameraView(Context context, AttributeSet attrs, int defStyleAttr) {
         super(context, attrs, defStyleAttr);
         init(context);
    }

    @TargetApi(Build.VERSION_CODES.LOLLIPOP)
    public CameraView(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
        super(context, attrs, defStyleAttr, defStyleRes);
        init(context);
    }

    private void init(Context context) {
        mContext = context;
        WindowManager manager = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);
        Display display = manager.getDefaultDisplay();
        Point size = new Point();
        display.getSize(size);
        float radius;
        float center;
        if (display.getRotation() == Surface.ROTATION_0 || display.getRotation() == Surface.ROTATION_180) {
            radius = size.x / 2;
            center = size.x / 2;
        } else {
            radius = size.y / 2;
            center = size.y / 2;
        }
        mClipPath = new Path();
        mClipPath.addCircle(center, center, radius, Path.Direction.CW);
    }

    @Override
    protected void dispatchDraw(Canvas canvas) {
        canvas.clipPath(mClipPath);
        super.dispatchDraw(canvas);
    }

    @Override
    public void surfaceCreated(SurfaceHolder holder) {
        try {
            mCamera.setPreviewDisplay(holder);
            mCamera.startPreview();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    @Override
    public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
        if (mHolder.getSurface() == null) {
            return;
        }
        try {
            mCamera.stopPreview();
        } catch (Exception e) {
            e.printStackTrace();
        }
        Camera.Parameters parameters = mCamera.getParameters();
        Display display = ((WindowManager) mContext.getSystemService(Context.WINDOW_SERVICE)).getDefaultDisplay();
        if (display.getRotation() == Surface.ROTATION_0) {
            parameters.setPreviewSize(height, width);
            mCamera.setDisplayOrientation(90);
        }
        if (display.getRotation() == Surface.ROTATION_90) {
            parameters.setPreviewSize(width, height);
        }
        if (display.getRotation() == Surface.ROTATION_180) {
            parameters.setPreviewSize(height, width);
        }
        if (display.getRotation() == Surface.ROTATION_270) {
            parameters.setPreviewSize(width, height);
            mCamera.setDisplayOrientation(180);
        }
        try {
            mCamera.setPreviewDisplay(holder);
            mCamera.startPreview();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    @Override
    public void surfaceDestroyed(SurfaceHolder holder) {

    }
}
和一项活动

public class CameraActivity extends AppCompatActivity {

    public static final String EXTRA_PICTURE = "com.rcd.perfecto.extra.PICTURE";

    @Bind(R.id.btn_photo_capture) Button mPhotoCaptureButton;
    @Bind(R.id.fl_camera_preview) FrameLayout mCameraPreviewFrameLayout;
    @Bind(R.id.btn_choose_from_gallery) Button mChooseFromGalleryButton;
    @Bind(R.id.iv_avatar) RoundedImageView mAvatarImageView;

    private Camera mCamera;
    private CameraView mCameraView;
    private boolean mCaptured = false;
    private byte[] mData;

    private Camera.PictureCallback mPictureCallback = new Camera.PictureCallback() {
        @Override
        public void onPictureTaken(byte[] data, Camera camera) {
            mData = data;
        }
    };

    public CameraActivity() {
    }

    @OnClick(R.id.btn_photo_capture)
    void takePicture() {
        mCameraView.setVisibility(View.VISIBLE);
        mAvatarImageView.setVisibility(View.GONE);
        if (!mCaptured) {
            mCamera.takePicture(null, null, mPictureCallback);
            mPhotoCaptureButton.setText(R.string.reshoot);
        }
        else {
            mCamera.startPreview();
            mPhotoCaptureButton.setText(R.string.btn_photo_capture);
        }
        mCaptured = !mCaptured;
    }

    @OnClick(R.id.btn_choose_from_gallery)
    void chooseFromGallery() {
        Intent intent = new Intent();
        intent.setType("image/*");
        intent.setAction(Intent.ACTION_GET_CONTENT);
        startActivityForResult(intent, 0);
    }


    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_camera);
        ButterKnife.bind(this);
        if (checkCameraHardware()) {
            if (Camera.getNumberOfCameras() > 1) {
                mCamera = getCameraInstance(Camera.CameraInfo.CAMERA_FACING_FRONT);
            } else mCamera = getCameraInstance();
        }
        mCameraView = new CameraView(CameraActivity.this, mCamera);
        mCameraPreviewFrameLayout.addView(mCameraView, 0);

    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        mCamera.release();
    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
         getMenuInflater().inflate(R.menu.menu_camera, menu);
         return super.onCreateOptionsMenu(menu);
    } 

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        switch (item.getItemId()) {
            case R.id.me_done:
                Intent intent = new Intent();
                if (mData != null) {
                    intent.putExtra(EXTRA_PICTURE, mData);
                }
                setResult(RESULT_OK, intent);
                finish();
                return true;
            default:
                return super.onOptionsItemSelected(item);
        }

    }

    private static Camera getCameraInstance() {
        Camera c = null;
        try {
            c = Camera.open();
        } catch (Exception e) {
            e.printStackTrace();
        }
        return c;
    }

    private static Camera getCameraInstance(int id) {
         Camera c = null;
         try {
            c = Camera.open(id);
         } catch (Exception e) {
            e.printStackTrace();
         }
         return c;
     }

    private boolean checkCameraHardware() {
        return getPackageManager().hasSystemFeature(PackageManager.FEATURE_CAMERA);
    }

    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        super.onActivityResult(requestCode, resultCode, data);
        if (resultCode == RESULT_OK) {
            Uri imageUri = data.getData();
            try {
                Bitmap bitmap = MediaStore.Images.Media.getBitmap(getContentResolver(), imageUri);
                mCameraView.setVisibility(View.GONE);
                mAvatarImageView.setVisibility(View.VISIBLE);
                mAvatarImageView.setImageBitmap(bitmap);
                mCaptured = true;
                mPhotoCaptureButton.setText(R.string.reshoot);
                ByteArrayOutputStream stream = new ByteArrayOutputStream();
                bitmap.compress(Bitmap.CompressFormat.PNG, 100, stream);
                mData = stream.toByteArray();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

}
编辑:添加了完整堆栈跟踪:

03-03 12:03:28.158 29399-29399/com.rcd.perfecto W/System.err: java.lang.RuntimeException: startPreview failed
03-03 12:03:28.158 29399-29399/com.rcd.perfecto W/System.err:     at android.hardware.Camera.startPreview(Native Method)
03-03 12:03:28.158 29399-29399/com.rcd.perfecto W/System.err:     at com.rcd.perfecto.ui.custom.CameraView.surfaceChanged(CameraView.java:122)
03-03 12:03:28.158 29399-29399/com.rcd.perfecto W/System.err:     at android.view.SurfaceView.updateWindow(SurfaceView.java:594)
03-03 12:03:28.159 29399-29399/com.rcd.perfecto W/System.err:     at android.view.SurfaceView$3.onPreDraw(SurfaceView.java:177)
03-03 12:03:28.159 29399-29399/com.rcd.perfecto W/System.err:     at android.view.ViewTreeObserver.dispatchOnPreDraw(ViewTreeObserver.java:944)
03-03 12:03:28.159 29399-29399/com.rcd.perfecto W/System.err:     at android.view.ViewRootImpl.performTraversals(ViewRootImpl.java:2055)
03-03 12:03:28.159 29399-29399/com.rcd.perfecto W/System.err:     at android.view.ViewRootImpl.doTraversal(ViewRootImpl.java:1107)
03-03 12:03:28.159 29399-29399/com.rcd.perfecto W/System.err:     at android.view.ViewRootImpl$TraversalRunnable.run(ViewRootImpl.java:6013)
03-03 12:03:28.159 29399-29399/com.rcd.perfecto W/System.err:     at android.view.Choreographer$CallbackRecord.run(Choreographer.java:858)
03-03 12:03:28.159 29399-29399/com.rcd.perfecto W/System.err:     at android.view.Choreographer.doCallbacks(Choreographer.java:670)
03-03 12:03:28.159 29399-29399/com.rcd.perfecto W/System.err:     at android.view.Choreographer.doFrame(Choreographer.java:606)
03-03 12:03:28.159 29399-29399/com.rcd.perfecto W/System.err:     at android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:844)
03-03 12:03:28.159 29399-29399/com.rcd.perfecto W/System.err:     at android.os.Handler.handleCallback(Handler.java:739)
03-03 12:03:28.159 29399-29399/com.rcd.perfecto W/System.err:     at android.os.Handler.dispatchMessage(Handler.java:95)
03-03 12:03:28.159 29399-29399/com.rcd.perfecto W/System.err:     at android.os.Looper.loop(Looper.java:148)
03-03 12:03:28.159 29399-29399/com.rcd.perfecto W/System.err:     at android.app.ActivityThread.main(ActivityThread.java:5417)
03-03 12:03:28.159 29399-29399/com.rcd.perfecto W/System.err:     at java.lang.reflect.Method.invoke(Native Method)
03-03 12:03:28.159 29399-29399/com.rcd.perfecto W/System.err:     at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:726)
03-03 12:03:28.159 29399-29399/com.rcd.perfecto W/System.err:     at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:616)
03-03 12:03:28.207 29399-29399/com.rcd.perfecto E/Camera: Error 1

不能将surfaceview的宽度和高度用作参数的输入参数

因为相机可能不支持宽度和高度。 相反,您应该使用相机支持的宽度和高度

像这样:

List supportedPreviewSizes=参数。getSupportedPreviewSizes();
Camera.Size optimalizepreviewsize=getoptimalizepreviewsize(supportedPreviewSizes,w,h);
f(最佳预览大小!=null){
parameters.setPreviewSize(optimalPreviewSize.width、optimalPreviewSize.height);
设置参数(参数);

}
能否发布异常的完整日志?谢谢您在21摄像头api被弃用后使用的api我知道,但它在api 21中也起到了作用,我没有做任何更改我看到了您的代码为什么要使用摄像头预览。如果您只想拍摄图像,请使用MediaStore.ACTION\u image\u CAPTURE