How start SurfaceHolder.Callback() event if Button Clicked?

1.8k Views Asked by At

i tried to start SurfaceCallback of Camera if Button Clicked, but i cannot , if i did Camera.setPreviewCallback() does not invoked although it works in i invoked SurfaceHolder.Callback() from onCreat()method as shown in code below

public class HeartRateMonitor extends ActionBarActivity {

private static final String TAG = "HeartRateMonitor";
private static SurfaceView preview = null;
private static SurfaceHolder previewHolder = null;
private static Camera camera ;
private static View image = null;
private static TextView text = null;
private static WakeLock wakeLock = null;
private static long startTime = 0;
static Context context;
static CircleButton cb ;
static int txt ;

@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.main);
    PlaceholderFragment  p = new PlaceholderFragment() ;
    if (savedInstanceState == null) {
        getSupportFragmentManager().beginTransaction()
                .add(R.id.contain, p)
                .commit();
    }
    preview = (SurfaceView) findViewById(R.id.preview);
    previewHolder = preview.getHolder();
    previewHolder.addCallback(surfaceCallback);
    previewHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);

    image = findViewById(R.id.image);
    text = (TextView) findViewById(R.id.text);
    PowerManager pm = (PowerManager) getSystemService(Context.POWER_SERVICE);
    wakeLock = pm.newWakeLock(PowerManager.FULL_WAKE_LOCK, "DoNotDimScreen");
    HeartRateMonitor.context = getApplicationContext();
}


 class PlaceholderFragment extends Fragment implements View.OnClickListener {
     // this Fragment for Circular Button .
    View rootView ;
    public PlaceholderFragment() {
    }
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
    }
    @TargetApi(Build.VERSION_CODES.JELLY_BEAN)
    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        rootView = inflater.inflate(R.layout.start, container, false);
        cb = (CircleButton) rootView.findViewById(R.id.startButton);
        cb.setImageResource(R.drawable.start);
        cb.isClickable();
        cb.findViewById(R.id.startButton).setOnClickListener(this);
        return rootView;
    }
    @Override
    public void onClick(View v) {
       // Toast.makeText(getActivity(), "Button clicked", Toast.LENGTH_SHORT).show();
        cb.setImageResource(R.drawable.stop);
        start();
    }
}


public void start(){
    // here i want start preview .
}


@Override
protected void onResume() {
    super.onResume();
    wakeLock.acquire();
    camera = Camera.open();
    startTime = System.currentTimeMillis();
}

@Override
public void onPause() {
    super.onPause();
    wakeLock.release();
    camera = null;
}


private static PreviewCallback previewCallback = new PreviewCallback() {

    @Override
    public void onPreviewFrame(byte[] data, Camera cam) {
      // process preview data here .
    }
};



private static SurfaceHolder.Callback surfaceCallback = new SurfaceHolder.Callback() {
    @Override
    public void surfaceCreated(SurfaceHolder holder) {

        try {
            camera.setPreviewDisplay(previewHolder);
            camera.setPreviewCallback(previewCallback);
        } catch (Throwable t) {
        }
    }
    @Override
    public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
        Camera.Parameters parameters = camera.getParameters();
        parameters.setFlashMode(Camera.Parameters.FLASH_MODE_TORCH);
        Camera.Size size = getSmallestPreviewSize(width, height, parameters);
        if (size != null) {
            parameters.setPreviewSize(size.width, size.height);
        }
        camera.setParameters(parameters);
        camera.startPreview();
    }
    @Override
    public void surfaceDestroyed(SurfaceHolder holder) {
        // Ignore
    }
};




private static Camera.Size getSmallestPreviewSize(int width, int height, Camera.Parameters parameters) {
    Camera.Size result = null;

    for (Camera.Size size : parameters.getSupportedPreviewSizes()) {
        if (size.width <= width && size.height <= height) {
            if (result == null) {
                result = size;
            } else {
                int resultArea = result.width * result.height;
                int newArea = size.width * size.height;
                if (newArea < resultArea) result = size;
            }
        }
    }
    return result;
}
}
1

There are 1 best solutions below

0
On BEST ANSWER

If you delay calling previewHolder.addCallback(), the actual events of surfaceCreated() and surfaceChanged() will be fired as usual, only your callbacks won't be called.

You can startPreview at any time after the preview surface is created and bound (i.e. after you call camera.setPreviewDisplay(previewHolder)). You can setPreviewCallback only when you need its data. You can set preview to be transparent, or hide it behind some other view.