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;
}
}
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.