【问题标题】:Android Camera takePicture() failedAndroid 相机 takePicture() 失败
【发布时间】:2016-04-05 19:26:01
【问题描述】:

我一直在尝试使用相机在 Android 中使用 Surface Preview 拍照。 Surface Preview 跨越布局中的整个屏幕。

每当我调用 takePicture 时,它​​都会失败并说我没有启用预览。

这里是活动变量、图片方法和相机拍照代码(在 onResume() 中):

public class FawkesRCActivity extends Activity implements SurfaceHolder.Callback {

  SurfaceView mSurfaceView;
  SurfaceHolder mHolder;
  public Camera mCamera;

  ...


  Camera.PictureCallback camHolla = new Camera.PictureCallback() {
    public void onPictureTaken(byte[] data, Camera camera) {
      String photoFile = "F_Auton.jpg";
      File sdDir = Environment
              .getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES);

      String filename =sdDir + File.separator + photoFile;

      File pictureFile = new File(filename);

      try {
        FileOutputStream fos = new FileOutputStream(pictureFile);
        fos.write(data);
        fos.close();
      } catch (Exception e) {
        Log.d("Errored:", e.getMessage());
      }

    }
  };

  public void setCamera(Camera camera) {
    if (mCamera == camera) { return; }

    stopPreviewAndFreeCamera();

    mCamera = camera;

    if (mCamera != null) {
      List<Camera.Size> localSizes = mCamera.getParameters().getSupportedPreviewSizes();
      try {
        mCamera.setPreviewDisplay(mHolder);
      } catch (IOException e) {
        e.printStackTrace();
      }

      // Important: Call startPreview() to start updating the preview
      // surface. Preview must be started before you can take a picture.
      mCamera.startPreview();
    }
  }

  @Override
  public void surfaceCreated(SurfaceHolder surfaceHolder) {

  }

  public void surfaceChanged(SurfaceHolder holder, int format, int w, int h) {
    mCamera.startPreview();
  }

  public void surfaceDestroyed(SurfaceHolder holder) {
    // Surface will be destroyed when we return, so stop the preview.
    if (mCamera != null) {
      // Call stopPreview() to stop updating the preview surface.
      mCamera.stopPreview();
    }
  }

  /**
   * When this function returns, mCamera will be null.
   */
  private void stopPreviewAndFreeCamera() {

    if (mCamera != null) {
      // Call stopPreview() to stop updating the preview surface.
      mCamera.stopPreview();

      // Important: Call release() to release the camera for use by other
      // applications. Applications should release the camera immediately
      // during onPause() and re-open() it during onResume()).
      mCamera.release();

      mCamera = null;
    }
  }


  @Override
  protected void onResume() {
    FawkesRCActivity.this.runOnUiThread(new Runnable() {
      public void run() {
        mSurfaceView = (SurfaceView) findViewById(R.id.cameraPreview);
        // Install a SurfaceHolder.Callback so we get notified when the
        // underlying surface is created and destroyed.
        mHolder = mSurfaceView.getHolder();
        mHolder.addCallback(FawkesRCActivity.this);
        mHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
        // Search for the front facing camera
        int numberOfCameras = Camera.getNumberOfCameras();
        int camId=0;
        for (int i = 0; i < numberOfCameras; i++) {
          Camera.CameraInfo info = new Camera.CameraInfo();
          Camera.getCameraInfo(i, info);
          if (info.facing == Camera.CameraInfo.CAMERA_FACING_BACK) {
            camId=i;
          }
        }
        if (safeCameraOpen(camId))Log.e("Camera","All Good"); else Log.e("Camera","Errored");
        try{
          SurfaceTexture surfaceTexture = new SurfaceTexture(0);
          mCamera.setPreviewTexture(surfaceTexture);
      //    mCamera.startPreview();
        }
        catch(Exception e){
          e.printStackTrace();
        }

        try {
          mCamera.takePicture(null, null, null, camHolla);
        }
        catch(Exception e){
          e.printStackTrace();
        }

      }
    });

    super.onResume();
  }

 private boolean safeCameraOpen(int id) {
    boolean qOpened = false;

    try {
      releaseCameraAndPreview();
      mCamera = Camera.open(id);
      qOpened = (mCamera != null);
    } catch (Exception e) {
      Log.e(getString(R.string.app_name), "failed to open Camera");
      e.printStackTrace();
    }

    return qOpened;
  }

  private void releaseCameraAndPreview() {
    setCamera(null);
    if (mCamera != null) {
      mCamera.release();
      mCamera = null;
    }
  }

}

这是错误:

12-31 20:00:15.407    3244-5501/? E/Camera2Client﹕ takePicture: Camera 0: Cannot take picture without preview enabled
12-31 20:00:15.408    6988-6988/? W/System.err﹕ java.lang.RuntimeException: takePicture failed
12-31 20:00:15.408    6988-6988/? W/System.err﹕ at android.hardware.Camera.native_takePicture(Native Method)
12-31 20:00:15.408    6988-6988/? W/System.err﹕ at android.hardware.Camera.takePicture(Camera.java:1434)
12-31 20:00:15.408    6988-6988/? W/System.err﹕ at org.fawkes.fawkesrc.FawkesRCActivity$5.run(FawkesRCActivity.java:327)
12-31 20:00:15.408    6988-6988/? W/System.err﹕ at android.app.Activity.runOnUiThread(Activity.java:5524)
12-31 20:00:15.408    6988-6988/? W/System.err﹕ at org.fawkes.fawkesrc.FawkesRCActivity.onResume(FawkesRCActivity.java:298)
12-31 20:00:15.408    6988-6988/? W/System.err﹕ at android.app.Instrumentation.callActivityOnResume(Instrumentation.java:1258)
12-31 20:00:15.408    6988-6988/? W/System.err﹕ at android.app.Activity.performResume(Activity.java:6327)
12-31 20:00:15.408    6988-6988/? W/System.err﹕ at android.app.ActivityThread.performResumeActivity(ActivityThread.java:3092)
12-31 20:00:15.408    6988-6988/? W/System.err﹕ at android.app.ActivityThread.handleResumeActivity(ActivityThread.java:3134)
12-31 20:00:15.408    6988-6988/? W/System.err﹕ at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2481)
12-31 20:00:15.408    6988-6988/? W/System.err﹕ at android.app.ActivityThread.-wrap11(ActivityThread.java)
12-31 20:00:15.408    6988-6988/? W/System.err﹕ at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1344)
12-31 20:00:15.409    6988-6988/? W/System.err﹕ at android.os.Handler.dispatchMessage(Handler.java:102)
12-31 20:00:15.409    6988-6988/? W/System.err﹕ at android.os.Looper.loop(Looper.java:148)
12-31 20:00:15.409    6988-6988/? W/System.err﹕ at android.app.ActivityThread.main(ActivityThread.java:5417)
12-31 20:00:15.409    6988-6988/? W/System.err﹕ at java.lang.reflect.Method.invoke(Native Method)
12-31 20:00:15.409    6988-6988/? W/System.err﹕ at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:726)
12-31 20:00:15.409    6988-6988/? W/System.err﹕ at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:616)

在论坛搜索了几个小时后,我完全迷失了方向,我们将不胜感激。

【问题讨论】:

    标签: android camera android-camera surfaceview


    【解决方案1】:

    相机操作不是即时的,而且通常不是同步的。一些设备需要在 startPreview() 和 takePicture() 之间有很大的延迟,例如在 OnePlus One 上,您至少需要 100 毫秒。

    对代码的最小修复可能是

        try{
          SurfaceTexture surfaceTexture = new SurfaceTexture(0);
          mCamera.setPreviewTexture(surfaceTexture);
      //    mCamera.startPreview();
        }
        catch(Exception e){
          e.printStackTrace();
        }
    
    mSurfaceView.postDelayed(new Runnable() {
        @Override
        public void run() {
            try {
                mCamera.takePicture(null, null, null, camHolla);
            }
            catch(Exception e){
                e.printStackTrace();
            }
        }, 100);
    
            super.onResume();
    

    【讨论】:

      【解决方案2】:

      我不是专家,但我认为您在拍照之前没有致电mCamera.startPreview()。您可以尝试在此之前调用它。

      您可以看看这个CameraFragment Sample 作为开始相机预览等的参考。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2013-01-31
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多