title: Android: "Camera.takePicture failed" Exception
body: <p>I'm experiencing an odd problem. I'm doing my testing on an HTC EVO. I have written a demo camera application targeting 2.2 and almost everything works correctly. The problem is that after taking three or four pictures, the application crashes and gives me the following messages:</p>
  
  <pre><code>D/QualcommCameraHardware(   64): takePicture(479)
  D/QualcommCameraHardware(   64): val_ril_status = 0,val_wimax_status = 0,val_hotspot_status = 0,val_low_temp_limit = 10.000000,val_batt_temp = 29.799999,val_low_temp_limit = 15,val_batt_cap  = 96
  D/QualcommCameraHardware(   64): FLASHLIGHT is ENABLED
  D/QualcommCameraHardware(   64): stopPreviewInternal E: 1
  D/QualcommCameraHardware(   64): cancelAutoFocusInternal E
  D/QualcommCameraHardware(   64): cancelAutoFocusInternal X: 0
  I/QualcommCameraHardware(   64): deinitPreview E
  D/QualcommCameraHardware(   64): launch_watchdog_thread:
  D/QualcommCameraHardware(   64): watchdog_thread_id = 369048
  I/QualcommCameraHardware(   64): register_buf: camfd = 35, reg = 1 buffer = 0x4153f000
  I/QualcommCameraHardware(   64): register_buf: camfd = 35, reg = 1 buffer = 0x415bf000
  I/QualcommCameraHardware(   64): register_buf: camfd = 35, reg = 1 buffer = 0x4163f000
  I/QualcommCameraHardware(   64): register_buf: camfd = 35, reg = 1 buffer = 0x416bf000
  I/QualcommCameraHardware(   64): register_buf: camfd = 38, reg = 1 buffer = 0x4331d000
  I/QualcommCameraHardware(   64): register_buf: camfd = 38, reg = 1 buffer = 0x4351d000
  I/QualcommCameraHardware(   64): register_buf: camfd = 38, reg = 1 buffer = 0x4371d000
  I/QualcommCameraHardware(   64): register_buf: camfd = 38, reg = 1 buffer = 0x4391d000
  I/QualcommCameraHardware(   64): register_buf: camfd = 38, reg = 1 buffer = 0x43b1d000
  I/QualcommCameraHardware(   64): register_buf: camfd = 38, reg = 1 buffer = 0x43d1d000
  I/QualcommCameraHardware(   64): register_buf: camfd = 38, reg = 1 buffer = 0x43f1d000
  I/QualcommCameraHardware(   64): register_buf: camfd = 38, reg = 1 buffer = 0x4411d000
  I/QualcommCameraHardware(   64): deinitPreview X
  D/QualcommCameraHardware(   64): stopPreviewInternal X: 0
  D/QualcommCameraHardware(   64): initRaw E: raw size=3264x2448
  D/QualcommCameraHardware(   64): initRaw: raw ration = 0.750000, display size=768x432
  D/QualcommCameraHardware(   64): initRaw: thumbnail_width=768, thumbnail_height=576, thumbnail_buffer_size=663552
  D/QualcommCameraHardware(   64): native_access_parm: fd 24, type 1, length 32
  D/mm-camera-ov8810_u(   64): andy cam_mode_sel 0
  D/QualcommCameraHardware(   64): initRaw: initializing mRawHeap.
  E/MemoryHeapBase(   64): error opening /dev/pmem_camera: No such file or directory
  E/QualcommCameraHardware(   64): failed to construct master heap for pmem pool /dev/pmem_camera
  E/QualcommCameraHardware(   64): initRaw X failed with pmem_camera, trying with pmem_adsp
  D/QualcommCameraHardware(   64): frame_thread X
  D/QualcommCameraHardware(   64): watchdog_thread_id = 369048
  D/QualcommCameraHardware(   64): release_watchdog_thread: frame_thread_released = 1
  E/MemoryHeapBase(   64): mmap(fd=38, size=11988992) failed (Invalid argument)
  E/QualcommCameraHardware(   64): failed to construct master heap for pmem pool /dev/pmem_adsp
  E/QualcommCameraHardware(   64): initRaw X: error initializing mRawHeap
  E/QualcommCameraHardware(   64): initRaw failed.  Not taking picture.
  D/AndroidRuntime( 2650): Shutting down VM
  W/dalvikvm( 2650): threadid=1: thread exiting with uncaught exception (group=0x400259f8)
  E/AndroidRuntime( 2650): FATAL EXCEPTION: main
  E/AndroidRuntime( 2650): java.lang.RuntimeException: takePicture failed
  E/AndroidRuntime( 2650):  at android.hardware.Camera.native_takePicture(Native Method)
  E/AndroidRuntime( 2650):  at android.hardware.Camera.takePicture(Camera.java:535)
  E/AndroidRuntime( 2650):  at android.hardware.Camera.takePicture(Camera.java:503)
  E/AndroidRuntime( 2650):  at spikes.cameraSpike03.MainActivity.takePicture(MainActivity.java:90)
  E/AndroidRuntime( 2650):  at spikes.cameraSpike03.MainActivity.access$3(MainActivity.java:87)
  E/AndroidRuntime( 2650):  at spikes.cameraSpike03.MainActivity$3.onClick(MainActivity.java:80)
  E/AndroidRuntime( 2650):  at android.view.View.performClick(View.java:2408)
  E/AndroidRuntime( 2650):  at android.view.View$PerformClick.run(View.java:8817)
  E/AndroidRuntime( 2650):  at android.os.Handler.handleCallback(Handler.java:587)
  E/AndroidRuntime( 2650):  at android.os.Handler.dispatchMessage(Handler.java:92)
  E/AndroidRuntime( 2650):  at android.os.Looper.loop(Looper.java:144)
  E/AndroidRuntime( 2650):  at android.app.ActivityThread.main(ActivityThread.java:4937)
  E/AndroidRuntime( 2650):  at java.lang.reflect.Method.invokeNative(Native Method)
  E/AndroidRuntime( 2650):  at java.lang.reflect.Method.invoke(Method.java:521)
  E/AndroidRuntime( 2650):  at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:868)
  E/AndroidRuntime( 2650):  at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:626)
  E/AndroidRuntime( 2650):  at dalvik.system.NativeStart.main(Native Method)
  W/ActivityManager(  107):   Force finishing activity spikes.cameraSpike03/.MainActivity
  D/QualcommCameraHardware(   64): void* watchdog(void*), frame_thread_released = 1, cnt = 0
  D/QualcommCameraHardware(   64): void* watchdog(void*), exit, frame_thread_released=1
  D/QualcommCameraHardware(   64): void release_watchdog_thread(): pthread_join succeeded on watchdog.
  </code></pre>
  
  <p>Could this be a memory management problem?</p>
  
  <p>Below is all the code I'm using.</p>
  
  <p>[AndroidManifest.xml]</p>
  
  <pre><code>&lt;?xml version="1.0" encoding="utf-8"?&gt;
  &lt;manifest xmlns:android="http://schemas.android.com/apk/res/android"
        package="spikes.cameraSpike03"
        android:versionCode="1"
        android:versionName="1.0"&gt;
      &lt;application android:icon="@drawable/icon" android:label="@string/app_name" android:debuggable="true"&gt;
          &lt;activity android:name=".MainActivity" android:label="@string/app_name" android:screenOrientation="portrait"&gt;
              &lt;intent-filter&gt;
                  &lt;action android:name="android.intent.action.MAIN" /&gt;
                  &lt;category android:name="android.intent.category.LAUNCHER" /&gt;
              &lt;/intent-filter&gt;
          &lt;/activity&gt;
      &lt;/application&gt;
  
      &lt;uses-sdk android:minSdkVersion="8" /&gt;
  
   &lt;uses-permission android:name="android.permission.CAMERA" /&gt;
  
   &lt;uses-feature android:name="android.hardware.camera" /&gt;
   &lt;uses-feature android:name="android.hardware.camera.autofocus" /&gt;
   &lt;uses-feature android:name="android.hardware.camera.flash" /&gt;
  &lt;/manifest&gt;
  </code></pre>
  
  <p>[main.xml]</p>
  
  <pre><code>&lt;?xml version="1.0" encoding="utf-8"?&gt;
  &lt;RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="vertical" android:layout_width="fill_parent" android:layout_height="fill_parent"&gt;
   &lt;SurfaceView android:id="@+id/svCameraView" android:layout_width="fill_parent" android:layout_height="fill_parent" /&gt;
   &lt;LinearLayout android:layout_width="fill_parent" android:layout_height="wrap_content" android:orientation="horizontal" android:background="#3000" android:layout_alignParentBottom="true" android:layout_centerHorizontal="true" android:gravity="center_horizontal"&gt;
    &lt;Button android:id="@+id/btnCapture" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="capture" /&gt;
    &lt;CheckBox android:id="@+id/chkAutofocus" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="Autofocus" /&gt;
   &lt;/LinearLayout&gt;
  &lt;/RelativeLayout&gt;
  </code></pre>
  
  <p>[MainActivity.java]</p>
  
  <pre><code>package spikes.cameraSpike03;
  
  import java.util.List;
  
  import android.app.Activity;
  import android.content.pm.ActivityInfo;
  import android.content.res.Configuration;
  import android.graphics.PixelFormat;
  import android.hardware.Camera;
  import android.hardware.Camera.AutoFocusCallback;
  import android.hardware.Camera.Parameters;
  import android.hardware.Camera.PictureCallback;
  import android.hardware.Camera.ShutterCallback;
  import android.hardware.Camera.Size;
  import android.os.Bundle;
  import android.util.Log;
  import android.view.SurfaceHolder;
  import android.view.SurfaceView;
  import android.view.View;
  import android.view.Window;
  import android.view.WindowManager;
  import android.view.View.OnClickListener;
  import android.widget.Button;
  import android.widget.CheckBox;
  
  public class MainActivity extends Activity implements SurfaceHolder.Callback {
   private static final String LOG_TAG = MainActivity.class.getName();
   private static final String LOG_LINE = "---------------------------------";
  
   private Camera _camera;
   private boolean _previewIsRunning = false;
  
   private SurfaceView _svCameraView;
   private SurfaceHolder _surfaceHolder;
   private Button _btnCapture;
   private CheckBox _chkAutofocus;
  
      @Override
      public void onCreate(Bundle savedInstanceState) {
          super.onCreate(savedInstanceState);
  
          getWindow().setFormat(PixelFormat.TRANSLUCENT);
          requestWindowFeature(Window.FEATURE_NO_TITLE);
          getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN);
  
          setContentView(R.layout.main);
  
          _svCameraView = (SurfaceView)findViewById(R.id.svCameraView);
  
          _surfaceHolder = _svCameraView.getHolder();
          _surfaceHolder.addCallback(this);
          _surfaceHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
  
          _chkAutofocus = (CheckBox)findViewById(R.id.chkAutofocus);
  
          _btnCapture = (Button)findViewById(R.id.btnCapture);
          _btnCapture.setOnClickListener(new OnClickListener() {
     @Override
     public void onClick(View v) {
      if(_camera != null){
       //Decide whether or not to use autofocus
       if(_chkAutofocus.isChecked()){
        Log.d(LOG_TAG, LOG_LINE + "Preparing to take the picture using autofocus...");
  
        _camera.autoFocus(new AutoFocusCallback() {
         @Override
         public void onAutoFocus(boolean success, Camera camera) {
          Log.d(LOG_TAG, LOG_LINE + "_camera.autoFocus.onAutoFocus(...) entered.");
  
          takePicture();
  
          Log.d(LOG_TAG, LOG_LINE + "_camera.autoFocus.onAutoFocus(...) finished.");
         }
        });
       }
       else{
        Log.d(LOG_TAG, LOG_LINE + "Preparing to take the picture without autofocus...");
  
        takePicture();
       }
      }
     }
    });
      }
  
      private void takePicture(){
       Log.d(LOG_TAG, LOG_LINE + "takePicture() entered.");
  
       _camera.takePicture(_shutterCallback, null, _jpegCallback);
    _previewIsRunning = false;
  
    Log.d(LOG_TAG, LOG_LINE + "takePicture() finished.");
      }
  
      private ShutterCallback _shutterCallback = new ShutterCallback() {
    @Override
    public void onShutter() {
     Log.d(LOG_TAG, LOG_LINE + "_shutterCallback.onShutter() called.");
    }
   };
  
   private PictureCallback _jpegCallback = new PictureCallback() {
    @Override
    public void onPictureTaken(byte[] data, Camera camera) {
     Log.d(LOG_TAG, LOG_LINE + "_jpegCallback.onPictureTaken() called.");
  
     _camera.startPreview();
     _previewIsRunning = true;
    }
   };
  
   @Override
   public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
    if(_previewIsRunning){
     Log.d(LOG_TAG, LOG_LINE + "About to stop preview...");
  
     _camera.stopPreview();
  
     Log.d(LOG_TAG, LOG_LINE + "Stopped preview.");
    }
  
    try{
     Log.d(LOG_TAG, LOG_LINE + "About to set up camera parameters...");
  
     Camera.Parameters parameters = _camera.getParameters();
  
     //Get the optimal preview size so we don't get an exception when setting the parameters 
     List&lt;Size&gt; supportedPreviewSizes = parameters.getSupportedPreviewSizes();
     Size optimalPreviewSize = CameraUtil.getOptimalPreviewSize(supportedPreviewSizes, width, height);
  
     parameters.setPreviewSize(optimalPreviewSize.width, optimalPreviewSize.height);
     parameters.setFocusMode(Parameters.FOCUS_MODE_AUTO);
     parameters.setFlashMode(Parameters.FLASH_MODE_AUTO);
  
     _camera.setDisplayOrientation(90);
  
     _camera.setParameters(parameters);
  
     _camera.setPreviewDisplay(holder);
  
     Log.d(LOG_TAG, LOG_LINE + "Finished setting up camera parameters.");
    }
    catch(Exception ex){
     ex.printStackTrace();
     Log.e(LOG_TAG, ex.toString());
    }
  
    Log.d(LOG_TAG, LOG_LINE + "About to start preview...");
  
    _camera.startPreview();
    _previewIsRunning = true;
  
    Log.d(LOG_TAG, LOG_LINE + "Started preview.");
   }
  
   @Override
   public void surfaceCreated(SurfaceHolder holder) {
    _camera = Camera.open();
   }
  
   @Override
   public void surfaceDestroyed(SurfaceHolder holder) {
    Log.d(LOG_TAG, LOG_LINE + "Tearing down camera because surface was destroyed...");
  
    _camera.stopPreview();
    _previewIsRunning = false;
    _camera.release();
  
    Log.d(LOG_TAG, LOG_LINE + "Finished tearing down camera because surface was destroyed.");
   }
  
   @Override
   public void onConfigurationChanged(Configuration newConfig){
    Log.d(LOG_TAG, LOG_LINE + "About to set request orientation to SCREEN_ORIENTATION_PORTRAIT...");
  
    setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
  
    Log.d(LOG_TAG, LOG_LINE + "Successfully set request orientation to SCREEN_ORIENTATION_PORTRAIT.");
   }
  }
  </code></pre>
  
  <p>[CameraUtil.java]</p>
  
  <pre><code>package spikes.cameraSpike03;
  
  import java.util.List;
  
  import android.hardware.Camera.Size;
  
  public class CameraUtil {
   private CameraUtil(){}
  
   /**
    * Returns a Size object containing the dimensions for an optimal preview size for the current hardware.
    * This code is based on that found at: http://developer.android.com/resources/samples/ApiDemos/src/com/example/android/apis/graphics/CameraPreview.html
    * 
    * @param supportedSizes
    * A list of Size objects representing all the known preview sizes supported by this hardware.
    * 
    * @param w
    * The surface width.
    * 
    * @param h
    * The surface height.
    * 
    * @return
    * Returns a Size object containing the dimensions for an optimal preview size for the current hardware.
    */
   public static Size getOptimalPreviewSize(List&lt;Size&gt; supportedSizes, int w, int h) {
          final double ASPECT_TOLERANCE = 0.05;
          double targetRatio = (double) w / h;
          if (supportedSizes == null) return null;
  
          Size optimalSize = null;
          double minDiff = Double.MAX_VALUE;
  
          int targetHeight = h;
  
          // Try to find an size match aspect ratio and size
          for (Size size : supportedSizes) {
              double ratio = (double) size.width / size.height;
              if (Math.abs(ratio - targetRatio) &gt; ASPECT_TOLERANCE) continue;
              if (Math.abs(size.height - targetHeight) &lt; minDiff) {
                  optimalSize = size;
                  minDiff = Math.abs(size.height - targetHeight);
              }
          }
  
          // Cannot find the one match the aspect ratio, ignore the requirement
          if (optimalSize == null) {
              minDiff = Double.MAX_VALUE;
              for (Size size : supportedSizes) {
                  if (Math.abs(size.height - targetHeight) &lt; minDiff) {
                      optimalSize = size;
                      minDiff = Math.abs(size.height - targetHeight);
                  }
              }
          }
          return optimalSize;
      }
  }
  </code></pre>
  
  <p>Any suggestions would be greatly appreciated.</p>
  
  <p>Thank you.</p>