tags:

views:

4005

answers:

4

Hi,

I am trying to set a camera preview in a custom SurfaceView but I get an exception each time I execute the initialization method.

Below is the code for camera preview initialization:

private void init(Context context)
{
 setFocusable(true);
 mRecording = false;
 fileRW = new FileReaderWriter();
 frameCount = 0;
 if(mCamera == null)
 {
  mCamera = Camera.open();
 }
 Parameters parameters = mCamera.getParameters();
 parameters.setPictureFormat(PixelFormat.JPEG);
 mCamera.setParameters(parameters);
 try {
  mCamera.setPreviewDisplay(surfaceHolder);
 } catch (IOException e) {
  // TODO Auto-generated catch block
  e.printStackTrace();
 }
 mCamera.startPreview();

}

the line `mCamera.setPreviewDisplay(surfaceHolder); throws an exception (setPreviewDisplay failed) each time I try to execute the method.

Does anyone know what could be wrong? I would really appreciate any of your help.

Thanks!`

+6  A: 

I usually call setPreviewDisplay() long before adjusting camera parameters.

With a stock SurfaceView, the following works:

@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.main);

    preview=(SurfaceView)findViewById(R.id.preview);
    previewHolder=preview.getHolder();
    previewHolder.addCallback(surfaceCallback);
    previewHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
}

SurfaceHolder.Callback surfaceCallback=new SurfaceHolder.Callback() {
    public void surfaceCreated(SurfaceHolder holder) {
     camera=Camera.open();

     try {
      camera.setPreviewDisplay(previewHolder);
     }
     catch (Throwable t) {
      Log.e("PictureDemo-surfaceCallback",
         "Exception in setPreviewDisplay()", t);
      Toast
       .makeText(PictureDemo.this, t.getMessage(), Toast.LENGTH_LONG)
       .show();
     }
    }

    public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
     Camera.Parameters parameters=camera.getParameters();

     parameters.setPreviewSize(width, height);
     parameters.setPictureFormat(PixelFormat.JPEG);
     camera.setParameters(parameters);
     camera.startPreview();
    }

    public void surfaceDestroyed(SurfaceHolder holder) {
     camera.stopPreview();
     camera.release();
     camera=null;
    }
};
CommonsWare
+2  A: 

The best place to call setPreviewDisplay is in [surfaceChanged][1]. If the surface is just created, surfaceChanged will be called at least once and you can startPreview and setPreviewDisplay there. If the surface changes and the preview already starts, you can stopPreview/setPreviewDisplay/startPreview there. Even if your app does not change the size of the surface, the framework may still unexpectedly call surfaceChanged when the app starts or exits due to orientation changes. So your app really needs to handle surfaceChanged properly. You can trace the source code of camera application in Android for reference.

The code snippet in another answer works if surfaceChanged is only called once in the app lifecycle.

[1]: http://developer.android.com/reference/android/view/SurfaceHolder.Callback.html#surfaceChanged%28android.view.SurfaceHolder, int, int, int)

Garfield
A: 

i was also getting exception then i found that i was defining the permission at wrong location...try to define the permission tag outside the application tag like below, i hope this helps:

< manifest ......> < uses-permission android:name="android.permission.CAMERA" /> < application android:icon="@drawable/icon" android:label="@string/app_name"> < activity ... .....> < /application> < /manifest>

ravi
+1  A: 

For me, the problem was something entirely different - I needed to set the type of my SurfaceView's holder:

    SurfaceHolder sh = sv.getHolder();
    sh.addCallback(this);
    sh.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
Jon Bright