user1104836
user1104836

Reputation: 205

android camera preview blank screen

I want to capture a photo manually not by using existing camera apps. So i made this Activity:

  public class CameraActivity extends Activity {

    private Camera mCamera;
    private Preview mPreview;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_camera);


         // Create an instance of Camera
        mCamera = Camera.open(0); if(mCamera !=null) Log.i("CameraActivity.onCreate()", "mCamera initialized");

        // Create our Preview view and set it as the content of our activity.
        mPreview = new Preview(this); if(mPreview !=null) Log.i("CameraActivity.onCreate()", "mPreview initialized");

        FrameLayout preview = (FrameLayout) findViewById(R.id.camera_preview);

        preview.addView(mPreview); Log.i("CameraActivity.onCreate()", "mPreview added to FrameLayout");

        mPreview.setCamera(mCamera); Log.i("CameraActivity.onCreate()", "mPreview.setCamera(mCamera)");

    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        // Inflate the menu; this adds items to the action bar if it is present.
        getMenuInflater().inflate(R.menu.activity_camera, menu);
        return true;
    }

    @Override
    public void onPause() {
        super.onPause();
        mPreview.stopPreviewAndFreeCamera();
    }

}

This is the CameraPreview which i want to use:

    public class Preview extends ViewGroup implements SurfaceHolder.Callback {

    SurfaceView mSurfaceView;
    SurfaceHolder mHolder;

    private Camera mCamera;
    List<Size> mSupportedPreviewSizes;

    /**
     * @param context
     */
    public Preview(Context context) {
        super(context);

        mSurfaceView = new SurfaceView(context); Log.i("CameraPreview.constructor(...)", "mSurfaceView initialized");
        if(mSurfaceView==null) {Log.i("CameraPreview.constructor(...)", "mSurfaceView is null");}
        addView(mSurfaceView);

        // Install a SurfaceHolder.Callback so we get notified when the
        // underlying surface is created and destroyed.
        mHolder = mSurfaceView.getHolder(); Log.i("CameraPreview.constructor(...)", "mHolder setup");
        if(mHolder==null) {Log.e("PreviewCamera", "mHolder is null");}

        mHolder.addCallback(this);
        mHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
    }

    /**
     * @param context
     * @param attrs
     */
    public Preview(Context context, AttributeSet attrs) {
        super(context, attrs);
        // TODO Auto-generated constructor stub
    }

    /**
     * @param context
     * @param attrs
     * @param defStyle
     */
    public Preview(Context context, AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);
        // TODO Auto-generated constructor stub
    }

    /* (non-Javadoc)
     * @see android.view.ViewGroup#onLayout(boolean, int, int, int, int)
     */
    @Override
    protected void onLayout(boolean arg0, int arg1, int arg2, int arg3, int arg4) {
        // TODO Auto-generated method stub

    }

    @Override
    public void surfaceChanged(SurfaceHolder holder, int format, int width,
            int height) {
        // Now that the size is known, set up the camera parameters and begin
        // the preview.
        Camera.Parameters parameters = mCamera.getParameters();
        parameters.setPreviewSize(width, height);
        requestLayout();
        mCamera.setParameters(parameters);

        /*
          Important: Call startPreview() to start updating the preview surface. Preview must be
          started before you can take a picture.
        */
        mCamera.startPreview(); Log.i("CameraPreview.surfaceChanged(...)", "mCamera.startPreview()");

    }

    @Override
    public void surfaceCreated(SurfaceHolder holder) {
        // TODO Auto-generated method stub

    }

    @Override
    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(); Log.i("CameraPreview.surfaceDestroyed(...)", "mCamera.stopPreview()");
        }

    }



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

        if (mCamera != null) {
            /*
              Call stopPreview() to stop updating the preview surface.
            */
            mCamera.stopPreview(); Log.i("CameraPreview.stopPreviewAndFreeCamera()", "mCamera.stopPreview()");

            /*
              Important: Call release() to release the camera for use by other applications. 
              Applications should release the camera immediately in onPause() (and re-open() it in
              onResume()).
            */
            mCamera.release(); Log.i("CameraPreview.stopPreviewAndFreeCamera()", "mCamera.release()");

            mCamera = null;
        }
    }


    /***
     * 
     * @param camera
     */
    public void setCamera(Camera camera) {
        if (mCamera == camera) { Log.i("CameraPreview.setCamera()", "mCamera equals the Camera you want to set"); return; }

        stopPreviewAndFreeCamera(); Log.i("CameraPreview.setCamera()", "stopPreviewAndFreeCamera()");

        mCamera = camera; Log.i("CameraPreview.setCamera()", "setup  new Camera");

        if (mCamera != null) {
            List<Size> localSizes = mCamera.getParameters().getSupportedPreviewSizes();
            mSupportedPreviewSizes = localSizes;
            requestLayout();

            try {
                mCamera.setPreviewDisplay(mHolder);
                Log.i("CameraPreview.setCamera()", "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(); Log.i("CameraPreview.setCamera()", "mCamera.startPreview()");
        }
    }


    /***
     * 
     * @param id
     * @return
     */
    public boolean safeCameraOpen(int id) {
        boolean qOpened = false;

        try {
            releaseCameraAndPreview();
            mCamera = Camera.open(id);

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

        return qOpened;    
    }

    /**
     * 
     */
    Camera.PictureCallback mPicCallback = new Camera.PictureCallback() {

        @Override
        public void onPictureTaken(byte[] data, Camera camera) {
            // TODO Auto-generated method stub
            Log.d("lala", "pic is taken");
        }
    };

    /**
     * 
     */
    public void takePic() {

    //  mCamera.takePicture(null, mPicCallback, mPicCallback);

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

}

This is the Layout of CameraActivity:

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".CameraActivity" >


  <FrameLayout
    android:id="@+id/camera_preview"
    android:layout_width="0dip"
    android:layout_height="fill_parent"
    android:layout_weight="1"
    />

  <Button
    android:id="@+id/button_capture"
    android:text="Capture"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_gravity="center"
    />


</LinearLayout>

But when i start the CameraActivity, i just see a blank white background and the Capture-Button??? Why i dont see the Camera-Screen?

EDIT: Logcat:

12-16 13:09:39.941: I/CameraActivity.onCreate()(439): mCamera initialized
12-16 13:09:39.941: I/CameraPreview.constructor(...)(439): mSurfaceView initialized
12-16 13:09:39.941: I/CameraPreview.constructor(...)(439): mHolder setup
12-16 13:09:39.941: I/CameraActivity.onCreate()(439): mPreview initialized
12-16 13:09:39.952: I/CameraActivity.onCreate()(439): mPreview added to FrameLayout
12-16 13:09:39.952: I/CameraPreview.setCamera()(439): stopPreviewAndFreeCamera()
12-16 13:09:39.952: I/CameraPreview.setCamera()(439): setup  new Camera
12-16 13:09:39.961: D/Camera(439): app passed NULL surface
12-16 13:09:39.961: I/CameraPreview.setCamera()(439): mCamera.setPreviewDisplay(mHolder)
12-16 13:09:39.971: I/CameraPreview.setCamera()(439): mCamera.startPreview()
12-16 13:09:39.971: I/CameraActivity.onCreate()(439): mPreview.setCamera(mCamera)
12-16 13:09:40.622: I/ActivityManager(60): Displayed com.example.popup/.CameraActivity: +810ms

Upvotes: 2

Views: 6977

Answers (5)

Rob
Rob

Reputation: 2666

It looks like the OP followed the 'Controlling the camera' tutorial from http://developer.android.com/training/camera/cameradirect.html. I tried the same, but soon found out that this tutorial doesn't work.

To save other beginners the same frustration of trying to get the tutorial to work, here's another tutorial which does work: http://www.tutorialspoint.com/android/android_camera.htm.

Upvotes: 0

Murat
Murat

Reputation: 3294

You can check whether the layout_width and layout_height properties of Preview is set to match_parent.

Upvotes: 0

Mustafa Baquari
Mustafa Baquari

Reputation: 1

I was having same problem. Then I extended it to SurfaceView instead of ViewGroup. And in a magical moment it worked...

Upvotes: 0

Sohyun Ahn
Sohyun Ahn

Reputation: 250

I think you should call open() method after addView().
Camera preview size is set by addView().

Upvotes: 2

Philip Pearl
Philip Pearl

Reputation: 1533

You aren't calling setCamera with the camera (only null), so you never set the preview display.

Upvotes: 0

Related Questions