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>