I've seen similar problems to the one I'm having, but I still can't find a solution. I'm very new to Android development, so I'm having trouble tracking down my problem. Anyways, I'm trying to create a camera preview using a CameraSurfaceView class I created that extends SurfaceView and implements SurfaceHolder.Callback. No matter what I try in my StartCamera class, the surfaceCreated() method is never called, hence my camera never starts. Any help would be great, thanks!
StartCamera.java
import net.peterd.zombierun.R;
import android.hardware.Camera;
import android.os.Bundle;
import android.widget.FrameLayout;
public class StartCamera extends BaseActivity {
private Camera mCamera;
private CameraSurfaceView mView;
public void onCreate(Bundle state) {
// TODO Auto-generated constructor stub
super.onCreate(state);
setContentView(R.layout.start_camera);
}
public void onResume() {
super.onResume();
mView = new CameraSurfaceView(this);
FrameLayout preview = (FrameLayout) findViewById(R.id.cPreview);
preview.addView(mView);
}
public void onPause() {
mCamera.stopPreview();
mCamera.release();
}
}
CameraSurfaceView.java
import java.io.IOException;
import android.content.Context;
import android.hardware.Camera;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
public class CameraSurfaceView extends SurfaceView implements SurfaceHolder.Callback
{
private SurfaceHolder holder;
private Camera camera;
public CameraSurfaceView(Context context)
{
super(context);
//Initiate the Surface Holder properly
this.holder = this.getHolder();
this.holder.addCallback(this);
this.holder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
}
@Override
public void surfaceCreated(SurfaceHolder holder)
{
try
{
//Open the Camera in preview mode
this.camera = Camera.open();
this.camera.setPreviewDisplay(this.holder);
}
catch(IOException ioe)
{
ioe.printStackTrace(System.out);
}
}
@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 = camera.getParameters();
parameters.setPreviewSize(width, height);
camera.setParameters(parameters);
camera.startPreview();
}
@Override
public void surfaceDestroyed(SurfaceHolder holder)
{
// Surface will be destroyed when replaced with a new screen
//Always make sure to release the Camera instance
camera.stopPreview();
camera.release();
camera = null;
}
public Camera getCamera() {
return camera;
}
}
start_camera.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical" android:layout_width="fill_parent"
android:layout_height="fill_parent">
<FrameLayout android:id="@+id/cPreview"
android:layout_weight="1" android:layout_width="fill_parent"
android:layout_height="fill_parent">
</FrameLayout>
</LinearLayout>
Apparently this is due to FrameLayout being empty and thus not creating any kind of SurfaceView. You can try to force the parent LinearLayout setting height and width manually or simply adding an imageView inside the FrameLayout. Since FrameLayout may contain many widgets, but it only shows the last of them you can put a ImageView inside the FrameLayout showing a small image only for the SurfaceView to be created.
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical" android:layout_width="fill_parent"
android:layout_height="fill_parent">
<FrameLayout android:id="@+id/cPreview"
android:layout_weight="1" android:layout_width="fill_parent"
android:layout_height="fill_parent">
<!-- Adding small dummy image -->
<ImageView android:layout_width="wrap_content"
android:layout_height="wrap_content"
src="@drawable/small_picture">
</FrameLayout>
</LinearLayout>
I have had the same problem. For me it was because the View size was being set to 0, and therefore the surface was never created. I checked this by setting a specific size, and all of a sudden the callbacks were called. (Same, apparently, holds if the View is laid out off-screen).
@jvnane I tried your code, it works, with minor bug.
surfaceChanged
is called without problem. In what way you think it doesn't work? Try adding debug message and see it in LogCat:
@Override
public void surfaceCreated(final SurfaceHolder holder)
{
Log.i("Camera Test", "It works!");
try
{
//Open the Camera in preview mode
this.camera = Camera.open();
this.camera.setPreviewDisplay(this.holder);
}
catch(final IOException ioe)
{
ioe.printStackTrace(System.out);
}
}
Minor bug: Camera
object is released in surfaceDestroyed
so you don't need to release it again in the activity's onPause
. Also, you need to call super.onPause()
when overriding onPause()
method.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With