title: Width and height passed in surfaceChanged() not supported by setParameters()?
body: <p>I am having a RuntimeException error when calling Camera.setParameters() from the method surfaceChanged(). I saw other posts about the same issue, but didn't find a definite solution:
  <a href="https://stackoverflow.com/questions/6830723/problem-with-setting-the-parameters-to-camera">Issue with setting the parameters to camera</a></p>
  
  <p>My questions are:</p>
  
  <ol>
  <li><p>Why should surfaceChanged() be called right after surfaceCreated()? It is counter intuitive  (at least to me) to start the preview in surfaceCreated(), only to stop it and restart another one in surfaceChanged().</p></li>
  <li><p>When surfaceChanged() is called for the first time, what decides the width and height that are passed in? As suggested in the aforementioned post, and verified in my experiment, the values are not necessarily supported by Camera.setParameters(). See below for my code snippet and log information.</p></li>
  <li><p>Before surfaceChanged() is called, is there a way to guarantee that the width and height values will be supported by Camera.setParameters()? It is possible to add code within surfaceChanged() to ensure that. For example, w and h can be compared against all supported preview sizes, and be changed to the closest supported values. However, doing so will hinder performance.</p></li>
  </ol>
  
  <p>List below are my code snippet and the LogCat output. The logging info indicates that Camera.setParameters() within surfaceChanged() is causing the error. If I comment out the line where setParameters() is called, I don't see the error message any more.</p>
  
  <p>[<strong>Edit</strong>: I am testing on an Amazon Kindle Fire HD. The Android version is 4.0.3, API 15]</p>
  
  <p>Code snippet:</p>
  
  <pre><code>public void surfaceCreated(SurfaceHolder holder) {
      // Log &amp; debug
      Log.d(TAG, "surfaceCreated() is called");
  
      // The Surface has been created, now tell the camera where to draw the preview.
      try {
          mCamera.setPreviewDisplay(mHolder);
          mCamera.startPreview();
      } catch (IOException e) {
          Log.d(TAG, "surfaceCreated(): " + e.getMessage());
      }
  
      if (mHolder.getSurface() == null) {
          Log.d(TAG, "surfaceCreated(): preview surface does not exist yet!");
      }
  }
  
  public void surfaceDestroyed(SurfaceHolder holder) {
      // Log &amp; debug
      Log.d(TAG, "surfaceDestroyed() is called");
  
      // Stop preview and release camera 
      if (holder.getSurface() != null) {
          mCamera.stopPreview();
          //mCamera.release();  //should we release camera here?
          //mCamera = null;
      }
      else {
          Log.d(TAG, "surfaceDestroyed(): preview surface does not exist");
      }
  }
  
  public void surfaceChanged(SurfaceHolder holder, int format, int w, int h) {
      // Log and debug
      Log.d(TAG, "surfaceChanged() is called with width = " + w);
      Log.d(TAG, "surfaceChanged() is called with height = " + h);
  
      // If your preview can change or rotate, take care of those events here.
      // Make sure to stop the preview before resizing or reformatting it.
      if (holder.getSurface() == null) {
        Log.d(TAG, "surfaceChanged(): preview surface does not exist");
        return;
      }
  
      // stop preview before making changes
      try {
          mCamera.stopPreview();
      } catch (Exception e) {
          Log.d(TAG, "surfaceChanged(): tried to stop a non-existent preview " + e.getMessage());
      }
  
      // set preview size and make any resize, rotate or
      // reformatting changes here
      Camera.Parameters params = mCamera.getParameters();
      List&lt;Size&gt; mSizes = params.getSupportedPreviewSizes();
  
      // list all 25 supported preview sizes
      // i==25 will cause an "IndexOutofBoundsException"
      for (int i=0; i&lt;25; i++) {
          Size mSize  = mSizes.get(i);
          if (mSize == null) break;
          Log.d(TAG, "surfaceChanged() i = " + i);
          Log.d(TAG, "surfaceChanged() preview width = " + mSize.width);
          Log.d(TAG, "surfaceChanged() preview height = " + mSize.height);
      }
      Size       mSize  = mSizes.get(0);
      if(mSize != null) { //make sure we don't pull a NullException.
          if (w &gt; mSize.width) w  = mSize.width;
          if (h &gt; mSize.height) h = mSize.height;
          params.setPreviewSize(w, h); //set the size, since we know it. 
      } 
      mCamera.setParameters(params); //set the parameters now. 
  
      // start preview with new settings
      try {
          mCamera.setPreviewDisplay(holder);
          mCamera.startPreview();
      } catch (Exception e){
          Log.d(TAG, "surfaceChanged() restart preview " + e.getMessage());
      }
  }
  </code></pre>
  
  <p>LogCat output:</p>
  
  <pre><code>02-13 10:46:08.113: D/CameraPreview(2886): surfaceCreated() is called
  02-13 10:46:08.496: D/CameraPreview(2886): surfaceChanged() is called with width = 1072
  02-13 10:46:08.496: D/CameraPreview(2886): surfaceChanged() is called with height = 705
  02-13 10:46:08.941: D/CameraPreview(2886): surfaceChanged() i = 0
  02-13 10:46:08.941: D/CameraPreview(2886): surfaceChanged() preview width = 1280
  02-13 10:46:08.941: D/CameraPreview(2886): surfaceChanged() preview height = 720
  02-13 10:46:08.941: D/CameraPreview(2886): surfaceChanged() i = 1
  02-13 10:46:08.941: D/CameraPreview(2886): surfaceChanged() preview width = 960
  02-13 10:46:08.941: D/CameraPreview(2886): surfaceChanged() preview height = 720
  02-13 10:46:08.941: D/CameraPreview(2886): surfaceChanged() i = 2
  02-13 10:46:08.941: D/CameraPreview(2886): surfaceChanged() preview width = 800
  02-13 10:46:08.941: D/CameraPreview(2886): surfaceChanged() preview height = 480
  02-13 10:46:08.941: D/CameraPreview(2886): surfaceChanged() i = 3
  02-13 10:46:08.941: D/CameraPreview(2886): surfaceChanged() preview width = 720
  02-13 10:46:08.941: D/CameraPreview(2886): surfaceChanged() preview height = 576
  02-13 10:46:08.941: D/CameraPreview(2886): surfaceChanged() i = 4
  02-13 10:46:08.941: D/CameraPreview(2886): surfaceChanged() preview width = 720
  02-13 10:46:08.941: D/CameraPreview(2886): surfaceChanged() preview height = 480
  02-13 10:46:08.941: D/CameraPreview(2886): surfaceChanged() i = 5
  02-13 10:46:08.941: D/CameraPreview(2886): surfaceChanged() preview width = 768
  02-13 10:46:08.941: D/CameraPreview(2886): surfaceChanged() preview height = 576
  02-13 10:46:08.941: D/CameraPreview(2886): surfaceChanged() i = 6
  02-13 10:46:08.941: D/CameraPreview(2886): surfaceChanged() preview width = 640
  02-13 10:46:08.941: D/CameraPreview(2886): surfaceChanged() preview height = 480
  02-13 10:46:08.941: D/CameraPreview(2886): surfaceChanged() i = 7
  02-13 10:46:08.941: D/CameraPreview(2886): surfaceChanged() preview width = 320
  02-13 10:46:08.941: D/CameraPreview(2886): surfaceChanged() preview height = 240
  02-13 10:46:08.941: D/CameraPreview(2886): surfaceChanged() i = 8
  02-13 10:46:08.941: D/CameraPreview(2886): surfaceChanged() preview width = 352
  02-13 10:46:08.941: D/CameraPreview(2886): surfaceChanged() preview height = 288
  02-13 10:46:08.941: D/CameraPreview(2886): surfaceChanged() i = 9
  02-13 10:46:08.941: D/CameraPreview(2886): surfaceChanged() preview width = 240
  02-13 10:46:08.941: D/CameraPreview(2886): surfaceChanged() preview height = 160
  02-13 10:46:08.941: D/CameraPreview(2886): surfaceChanged() i = 10
  02-13 10:46:08.941: D/CameraPreview(2886): surfaceChanged() preview width = 176
  02-13 10:46:08.941: D/CameraPreview(2886): surfaceChanged() preview height = 144
  02-13 10:46:08.941: D/CameraPreview(2886): surfaceChanged() i = 11
  02-13 10:46:08.941: D/CameraPreview(2886): surfaceChanged() preview width = 160
  02-13 10:46:08.941: D/CameraPreview(2886): surfaceChanged() preview height = 120
  02-13 10:46:08.941: D/CameraPreview(2886): surfaceChanged() i = 12
  02-13 10:46:08.941: D/CameraPreview(2886): surfaceChanged() preview width = 128
  02-13 10:46:08.941: D/CameraPreview(2886): surfaceChanged() preview height = 96
  02-13 10:46:08.941: D/CameraPreview(2886): surfaceChanged() i = 13
  02-13 10:46:08.941: D/CameraPreview(2886): surfaceChanged() preview width = 720
  02-13 10:46:08.941: D/CameraPreview(2886): surfaceChanged() preview height = 1280
  02-13 10:46:08.941: D/CameraPreview(2886): surfaceChanged() i = 14
  02-13 10:46:08.941: D/CameraPreview(2886): surfaceChanged() preview width = 480
  02-13 10:46:08.941: D/CameraPreview(2886): surfaceChanged() preview height = 800
  02-13 10:46:08.941: D/CameraPreview(2886): surfaceChanged() i = 15
  02-13 10:46:08.941: D/CameraPreview(2886): surfaceChanged() preview width = 576
  02-13 10:46:08.941: D/CameraPreview(2886): surfaceChanged() preview height = 720
  02-13 10:46:08.941: D/CameraPreview(2886): surfaceChanged() i = 16
  02-13 10:46:08.941: D/CameraPreview(2886): surfaceChanged() preview width = 576
  02-13 10:46:08.941: D/CameraPreview(2886): surfaceChanged() preview height = 768
  02-13 10:46:08.941: D/CameraPreview(2886): surfaceChanged() i = 17
  02-13 10:46:08.941: D/CameraPreview(2886): surfaceChanged() preview width = 480
  02-13 10:46:08.941: D/CameraPreview(2886): surfaceChanged() preview height = 720
  02-13 10:46:08.941: D/CameraPreview(2886): surfaceChanged() i = 18
  02-13 10:46:08.941: D/CameraPreview(2886): surfaceChanged() preview width = 480
  02-13 10:46:08.941: D/CameraPreview(2886): surfaceChanged() preview height = 640
  02-13 10:46:08.941: D/CameraPreview(2886): surfaceChanged() i = 19
  02-13 10:46:08.941: D/CameraPreview(2886): surfaceChanged() preview width = 288
  02-13 10:46:08.941: D/CameraPreview(2886): surfaceChanged() preview height = 352
  02-13 10:46:08.941: D/CameraPreview(2886): surfaceChanged() i = 20
  02-13 10:46:08.941: D/CameraPreview(2886): surfaceChanged() preview width = 240
  02-13 10:46:08.941: D/CameraPreview(2886): surfaceChanged() preview height = 320
  02-13 10:46:08.941: D/CameraPreview(2886): surfaceChanged() i = 21
  02-13 10:46:08.941: D/CameraPreview(2886): surfaceChanged() preview width = 240
  02-13 10:46:08.941: D/CameraPreview(2886): surfaceChanged() preview height = 160
  02-13 10:46:08.941: D/CameraPreview(2886): surfaceChanged() i = 22
  02-13 10:46:08.941: D/CameraPreview(2886): surfaceChanged() preview width = 144
  02-13 10:46:08.941: D/CameraPreview(2886): surfaceChanged() preview height = 176
  02-13 10:46:08.941: D/CameraPreview(2886): surfaceChanged() i = 23
  02-13 10:46:08.941: D/CameraPreview(2886): surfaceChanged() preview width = 120
  02-13 10:46:08.941: D/CameraPreview(2886): surfaceChanged() preview height = 160
  02-13 10:46:08.941: D/CameraPreview(2886): surfaceChanged() i = 24
  02-13 10:46:08.941: D/CameraPreview(2886): surfaceChanged() preview width = 96
  02-13 10:46:08.941: D/CameraPreview(2886): surfaceChanged() preview height = 128
  02-13 10:46:08.957: D/AndroidRuntime(2886): Shutting down VM
  02-13 10:46:08.957: W/dalvikvm(2886): threadid=1: thread exiting with uncaught exception (group=0x40a6c1f8)
  02-13 10:46:08.965: E/AndroidRuntime(2886): FATAL EXCEPTION: main
  02-13 10:46:08.965: E/AndroidRuntime(2886): java.lang.RuntimeException: setParameters failed
  02-13 10:46:08.965: E/AndroidRuntime(2886):     at android.hardware.Camera.native_setParameters(Native Method)
  02-13 10:46:08.965: E/AndroidRuntime(2886):     at android.hardware.Camera.setParameters(Camera.java:1295)
  02-13 10:46:08.965: E/AndroidRuntime(2886):     at com.xyz.camera.CameraPreview.surfaceChanged(CameraPreview.java:109)
  02-13 10:46:08.965: E/AndroidRuntime(2886):     at android.view.SurfaceView.updateWindow(SurfaceView.java:544)
  02-13 10:46:08.965: E/AndroidRuntime(2886):     at android.view.SurfaceView.access$000(SurfaceView.java:81)
  02-13 10:46:08.965: E/AndroidRuntime(2886):     at android.view.SurfaceView$3.onPreDraw(SurfaceView.java:169)
  02-13 10:46:08.965: E/AndroidRuntime(2886):     at android.view.ViewTreeObserver.dispatchOnPreDraw(ViewTreeObserver.java:590)
  02-13 10:46:08.965: E/AndroidRuntime(2886):     at android.view.ViewRootImpl.performTraversals(ViewRootImpl.java:1630)
  02-13 10:46:08.965: E/AndroidRuntime(2886):     at android.view.ViewRootImpl.handleMessage(ViewRootImpl.java:2462)
  02-13 10:46:08.965: E/AndroidRuntime(2886):     at android.os.Handler.dispatchMessage(Handler.java:99)
  02-13 10:46:08.965: E/AndroidRuntime(2886):     at android.os.Looper.loop(Looper.java:137)
  02-13 10:46:08.965: E/AndroidRuntime(2886):     at android.app.ActivityThread.main(ActivityThread.java:4486)
  02-13 10:46:08.965: E/AndroidRuntime(2886):     at java.lang.reflect.Method.invokeNative(Native Method)
  02-13 10:46:08.965: E/AndroidRuntime(2886):     at java.lang.reflect.Method.invoke(Method.java:511)
  02-13 10:46:08.965: E/AndroidRuntime(2886):     at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:784)
  02-13 10:46:08.965: E/AndroidRuntime(2886):     at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:551)
  02-13 10:46:08.965: E/AndroidRuntime(2886):     at dalvik.system.NativeStart.main(Native Method)
  </code></pre>