2016-03-03 188 views
0

我有一个自定义的SurfaceView摄像头预览。当我用它启动一个Activity时,应用程序崩溃,RuntimeException说:startPreview failed和surfaceChanged方法中的Camera Error 1。怎么了?以下是我的表面视图和一个活动。当启动活动时,Android摄像头startPreview失败

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 
+0

能请张贴的异常的全logcat的?谢谢! – fasteque

+0

哪个你使用后21摄像头api弃用 – RDY

+0

我知道这一点,但它在API 21更早的工作,我没有改变任何东西 –

回答

0

您不能使用surfaceview的宽度和高度parameters.setPreviewSize的输入参数(高度宽度);

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

像这样:

 List<Camera.Size> supportedPreviewSizes = parameters.getSupportedPreviewSizes(); 
 
     Camera.Size optimalPreviewSize = getOptimalPreviewSize(supportedPreviewSizes, w, h); 
 
     
 
     f (optimalPreviewSize != null) { 
 
      parameters.setPreviewSize(optimalPreviewSize.width, optimalPreviewSize.height); 
 
      camera.setParameters(parameters); 
 
     }