SurfaceView goes black when comes to foreground, for Camera App

1.8k views Asked by At

I am using Camera feature in my app. Everything works fine but when the device gets locked/sleep, upon returning to the app the camera portion(SurfaceView) is just black. Below is my code. Can someone please identify the problem?

public class Activity_Camera extends Activity implements SurfaceHolder.Callback, Camera.AutoFocusCallback, Observer
{
    // Surface vars
    private SurfaceView preview;
    private SurfaceHolder previewHolder;

    // Camera vars
    private Camera mCamera;
    private boolean mPreviewRunning = false;
    private boolean mCaptureFrame = false;
    private int frame_number = 1;
    private byte[] frame = new byte[1];

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

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

    @Override
    public void onPause()
    {
        super.onPause();
        if (mPreviewRunning)
                 {
                     mCamera.stopPreview();
                     mPreviewRunning = false;
                 }
                 mCamera.setPreviewCallback(null); 
                 mCamera.release();
    }



    // implements SurfaceHolder.Callback
    public void surfaceCreated(SurfaceHolder holder)
    {
        mCamera = Camera.open();
    }

    // implements SurfaceHolder.Callback
    public void surfaceDestroyed(SurfaceHolder holder)
    {
        mPreviewRunning = false;
    }

    // implements Camera.AutoFocusCallback
    public void onAutoFocus(boolean success, Camera camera)
    {

    }

    PreviewCallback previewCallback = new PreviewCallback()
    {
        public void onPreviewFrame(byte[] data, Camera camera)
        {

        }
    };

    // implements SurfaceHolder.Callback
    public void surfaceChanged(SurfaceHolder holder, int format, int width, int height)
    {
        if (mPreviewRunning)
        {
            mCamera.stopPreview();
        }

        Camera.Parameters p = mCamera.getParameters();
        p.setPreviewSize(640, 480);
        mCamera.setParameters(p);

        try
        {
            mCamera.setPreviewDisplay(holder);
        } catch (IOException e)
        {
            e.printStackTrace();
        }

        mCamera.setPreviewCallback(previewCallback);

        int rotation = getWindowManager().getDefaultDisplay().getRotation();
        int degrees = 0;
        switch (rotation)
        {
        case Surface.ROTATION_0:
            degrees = 90;
            break;
        case Surface.ROTATION_90:
            degrees = 0;
            break;
        case Surface.ROTATION_180:
            degrees = 270;
            break;
        case Surface.ROTATION_270:
            degrees = 180;
            break;

        }
        Log.i("DEGREES ARE WHAT??", Integer.toString(degrees));

//      mCamera.setDisplayOrientation(degrees);
        mCamera.setDisplayOrientation(90);

        mCamera.startPreview();
        mPreviewRunning = true;

    }

    // implements Observer
    // captures a frame when the compass listener says it is appropriate
    public void update(Observable observable, Object data)
    {
        mCaptureFrame = true;
    }
}

Please identify the issue, as I suspect something wrong with onPause(), it also gives me exception when I press back button after the black camera screen:

java.lang.RuntimeException: Method called after release()

on this line:

 mCamera.setPreviewCallback(null); // (in onPause())

Here is the XML:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:orientation="vertical"
    android:background="#E6E5E6">
    <LinearLayout 
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:orientation="vertical"
        android:gravity="center_horizontal">
        <TextView 
            android:id="@+id/tv_camera_url"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:maxLines="1"
            android:textColor="@android:color/black"
            android:text="URL goes here........"
            android:layout_marginTop="3dp"
            android:textStyle="bold"/>
        <TextView 
            android:id="@+id/tv_speaknow"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:padding="3dp"
            android:background="#ffffff"
            android:layout_marginTop="3dp"
            android:text="Speak Now"
            android:textColor="#ff0000"
            android:textStyle="bold"/>
    </LinearLayout>
    <RelativeLayout
        android:id="@+id/rl_main"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content">
        <SurfaceView
            android:id="@+id/preview"
            android:layout_width="480px"
            android:layout_height="640px"
            android:layout_alignParentBottom="true"/>
        <Button
            android:id="@+id/btn_take_picture"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:background="@drawable/camera"
            android:layout_alignBottom="@+id/preview"
            android:layout_centerHorizontal="true"
            android:layout_marginBottom="5dp"/>
    </RelativeLayout>
</LinearLayout>
1

There are 1 answers

0
Anders Metnik On

If its the first time you are launching the app, the onPause really shouldn't be the problem. But I'd move down the creation and such to onResume instead of onCreate.

And can i see your xml of the surfaceview?

Do you just want 1 picture?

if (mPreviewRunning) { mCamera.stopPreview(); }

And most people startPreview from onResume. try to move it up there..