Android draw on camera preview

You can't lock and draw on a SurfaceView which has Type.PUSH_BUFFERS, (the one you're displaying frames to). You have to create another view above your original one in the Z direction and draw on a SurfaceView in that View.

So in your main.xml create a custom view below your original view in a FrameLayout.

Create and handle a SurfaceView in your Activity View. Add this view to the Camera preview display. Start your custom view passing the SurfaceHolder. In this view you can lock and draw on a canvas.


As James pointed out you need to create custom surface which extends SurfaceView (I usually implement SurfaceHolder.Callback also):

public class CameraSurfacePreview extends SurfaceView implements SurfaceHolder.Callback

Constructor will be something like:

public CameraSurfacePreview(Context context) {
     super(context);
     ...
     mHolder = getHolder();
     mHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
     ...

You need to bind camera with your surface after camera open call (if you implement implements SurfaceHolder.Callback put this somewhere inside overridden surfaceCreated):

mCamera = Camera.open();
mCamera.setPreviewDisplay(mHolder);

Finally you need to add instance of your custom surface somehere in activity content view:

CameraSurfacePreview cameraSurfacePreview = new CameraSurfacePreview(this);
//camera surface preview is first child!
((ViewGroup)findViewById(R.id.cameraLayout)).addView(cameraSurfacePreview, 0); 

In my example layout for activity looks something like(I am showing camera preview in main frame layout):

<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android" 
              android:layout_width="fill_parent"        
                      android:layout_height="fill_parent" 
              android:layout_gravity="top|left"
              android:id="@+id/cameraLayout">