I'm trying to capture an image from a SurfaceView custom camera. I have set up the initial code but I don't know how to call the 'take photo' method so that I can see the preview on the surface.
Currently this code displays the preview in realtime. I need to take the picture and access the byte[] array
Please help me complete the code:
private SurfaceView mSurfaceView;
private SurfaceHolder mSurfaceHolder;
private Camera mCamera;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_camera);
captureImage = (ImageButton) findViewById(R.id.captureImage);
mSurfaceView = (SurfaceView) findViewById(R.id.surfaceView);
captureImage.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
//this button press should take the picture
}
});
mSurfaceView.getHolder().addCallback(this);
mSurfaceView.getHolder().setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
mCamera = Camera.open();
}
#Override
public void onPause() {
super.onPause();
mCamera.stopPreview();
}
#Override
public void onDestroy() {
super.onDestroy();
mCamera.release();
}
#Override
public void surfaceCreated(SurfaceHolder holder) {
try {
mCamera.setPreviewDisplay(mSurfaceView.getHolder());
} catch (Exception e) {
e.printStackTrace();
}
}
#Override
public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
Camera.Parameters params = mCamera.getParameters();
List<Camera.Size> sizes = params.getSupportedPreviewSizes();
Camera.Size selected = sizes.get(0);
params.setPreviewSize(selected.width,selected.height);
mCamera.setParameters(params);
mCamera.setDisplayOrientation(90);
mCamera.startPreview();
}
#Override
public void surfaceDestroyed(SurfaceHolder holder) {
mCamera.stopPreview();
mCamera.release();
mCamera = null;
}
I need to get the bytes [] data so that I can convert the image to a base64 string. How do I call the necessary methods to take the picture using the code above?
Check "jpegCallback" in my example:
public class CameraActivity extends ActionBarActivity implements SurfaceHolder.Callback {
Camera camera;
SurfaceView surfaceView;
SurfaceHolder surfaceHolder;
PictureCallback jpegCallback;
#Override
protected void onCreate(#Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_camera);
surfaceView = (SurfaceView) findViewById(R.id.surfaceView);
surfaceHolder = surfaceView.getHolder();
// Install a SurfaceHolder.Callback so we get notified when the
// underlying surface is created and destroyed.
surfaceHolder.addCallback(this);
// deprecated setting, but required on Android versions prior to 3.0
surfaceHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
jpegCallback = new PictureCallback() {
public void onPictureTaken(byte[] data, Camera camera) {
FileOutputStream outStream = null;
try {
outStream = new FileOutputStream(String.format("/sdcard/%d.jpg", System.currentTimeMillis()));
outStream.write(data);
outStream.close();
Log.d("Log", "onPictureTaken - wrote bytes: " + data.length);
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} finally {
}
Toast.makeText(getApplicationContext(), "Picture Saved", 2000).show();
refreshCamera();
}
};
}
public void captureImage(View v) throws IOException {
//take the picture
camera.takePicture(null, null, jpegCallback);
}
#Override
public void surfaceCreated(SurfaceHolder surfaceHolder) {
try {
// open the camera
camera = Camera.open();
} catch (RuntimeException e) {
// check for exceptions
System.err.println(e);
return;
}
Camera.Parameters param;
param = camera.getParameters();
// modify parameter
List<Camera.Size> sizes = param.getSupportedPreviewSizes();
Camera.Size selected = sizes.get(0);
param.setPreviewSize(selected.width,selected.height);
camera.setParameters(param);
try {
// The Surface has been created, now tell the camera where to draw
// the preview.
camera.setDisplayOrientation(90);
camera.setPreviewDisplay(surfaceHolder);
camera.startPreview();
} catch (Exception e) {
// check for exceptions
System.err.println(e);
return;
}
}
#Override
public void surfaceChanged(SurfaceHolder surfaceHolder, int i, int i1, int i2) {
// Now that the size is known, set up the camera parameters and begin
// the preview.
refreshCamera();
}
#Override
public void surfaceDestroyed(SurfaceHolder surfaceHolder) {
// stop preview and release camera
camera.stopPreview();
camera.release();
camera = null;
}
public void refreshCamera() {
if (surfaceHolder.getSurface() == null) {
// preview surface does not exist
return;
}
// stop preview before making changes
try {
camera.stopPreview();
} catch (Exception e) {
// ignore: tried to stop a non-existent preview
}
// set preview size and make any resize, rotate or
// reformatting changes here
// start preview with new settings
try {
camera.setPreviewDisplay(surfaceHolder);
camera.startPreview();
} catch (Exception e) {
}
}
}
Related
I have been following two links to create custom camera for my application. I have been successful in opening the camera. The problem is that it reduces that image quality. The links I have been following are these:
http://www.coderzheaven.com/2011/12/28/how-to-create-a-custom-layout-for-your-camera-in-android/
http://blog.rhesoft.com/2015/04/02/tutorial-how-to-use-camera-with-android-and-android-studio/
and my code is:
Camera Activity:
public class CameraSetter extends Activity {
public Context context;
public int CAMERA;
// ImageView photo_setter;
private Camera mCamera = null;
private CameraView mCameraView = null;
public CameraSetter() {
}
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
TypefaceProvider.registerDefaultIconSets();
setContentView(R.layout.camera_preview);
Initialize();
}
private void Initialize() {
//photo_setter = (ImageView)findViewById(R.id.imview_camera_setter);
try {
mCamera = Camera.open();//you can use open(int) to use different cameras
} catch (Exception e) {
Log.d("ERROR", "Failed to get camera: " + e.getMessage());
}
if (mCamera != null) {
mCameraView = new CameraView(this, mCamera);//create a SurfaceView to show camera data
FrameLayout camera_view = (FrameLayout) findViewById(R.id.camera_view);
camera_view.addView(mCameraView);//add the SurfaceView to the layout
}
//btn to close the application
ImageButton imgClose = (ImageButton) findViewById(R.id.imgClose);
imgClose.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
System.exit(0);
}
});
}
}
and my cameraview class is:
public class CameraView extends SurfaceView implements SurfaceHolder.Callback {
private SurfaceHolder mHolder;
private Camera mCamera;
public CameraView(Context context, Camera camera) {
super(context);
mCamera = camera;
mCamera.setDisplayOrientation(90);
//get the holder and set this class as the callback, so we can get camera data here
mHolder = getHolder();
mHolder.addCallback(this);
mHolder.setType(SurfaceHolder.SURFACE_TYPE_NORMAL);
}
#Override
public void surfaceCreated(SurfaceHolder surfaceHolder) {
try {
//when the surface is created, we can set the camera to draw images in this surfaceholder
mCamera.setPreviewDisplay(surfaceHolder);
mCamera.startPreview();
} catch (IOException e) {
Log.d("ERROR", "Camera error on surfaceCreated " + e.getMessage());
}
}
#Override
public void surfaceChanged(SurfaceHolder surfaceHolder, int i, int i2, int i3) {
if (mHolder.getSurface() == null)//check if the surface is ready to receive camera data
return;
try {
mCamera.stopPreview();
} catch (Exception e) {
//this will happen when you are trying the camera if it's not running
}
//now, recreate the camera preview
try {
mCamera.setPreviewDisplay(mHolder);
mCamera.startPreview();
} catch (IOException e) {
Log.d("ERROR", "Camera error on surfaceChanged " + e.getMessage());
}
}
#Override
public void surfaceDestroyed(SurfaceHolder surfaceHolder) {
//our app has only one screen, so we'll destroy the camera in the surface
//if you are unsing with more screens, please move this code your activity
mCamera.stopPreview();
mCamera.release();
}
}
Can I increase the image quality using the same code or I have to do something else?
problem is solved by adding in surfacechanged:
Camera.Parameters parameters = mCamera.getParameters();
parameters.setFlashMode(Camera.Parameters.FLASH_MODE_AUTO);
parameters.setFocusMode(Camera.Parameters.FOCUS_MODE_CONTINUOUS_PICTURE);
parameters.setJpegQuality(100);
parameters.setRotation(90);
List<Camera.Size> sizes = parameters.getSupportedPictureSizes();
Camera.Size size = sizes.get(0);
for(int j=0;j<sizes.size();j++)
{
if(sizes.get(j).width > size.width)
size = sizes.get(j);
}
parameters.setPictureSize(size.width, size.height);
Display display = ((WindowManager) getContext().getSystemService(Context.WINDOW_SERVICE)).getDefaultDisplay();
if (display.getRotation() == Surface.ROTATION_0) {
mCamera.setDisplayOrientation(90);
} else if (display.getRotation() == Surface.ROTATION_270) {
mCamera.setDisplayOrientation(180);
}
mCamera.setParameters(parameters);
My application freezes when I call switchCam method in my code.something must be wrong there, but i cant understand what is the problem.Can someone help me out there what is the actual problem in my code.
public class MainActivity extends AppCompatActivity {
private Camera mCamera = null;
SurfaceHolder surfaceHolder=null;
private CameraView mCameraView = null;
int currentCameraId = 0;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
this.getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,
WindowManager.LayoutParams.FLAG_FULLSCREEN);//int flag, int mask
openCam();
//setCameraDisplayOrientation(MainActivity.this, currentCameraId, mCamera);
}
public void openCam() {
try {
mCamera = Camera.open();//you can use open(int) to use different cameras
} catch (Exception e) {
Log.d("ERROR", "Failed to get camera: " + e.getMessage());
mCamera = Camera.open();//you can use open(int) to use different cameras
}
if (mCamera != null) {
mCameraView = new CameraView(this, mCamera);//create a SurfaceView to show camera data
FrameLayout camera_view = (FrameLayout) findViewById(R.id.camera_preview);
camera_view.addView(mCameraView);//add the SurfaceView to the layout
}
}
public void switchCam(View view){
int camNum = 0;
camNum = Camera.getNumberOfCameras();
int camBackId = Camera.CameraInfo.CAMERA_FACING_BACK;
int camFrontId = Camera.CameraInfo.CAMERA_FACING_FRONT;
Toast.makeText(getApplicationContext(),"Hi Cam"+camNum,Toast.LENGTH_SHORT).show();
Camera.CameraInfo currentCamInfo = new Camera.CameraInfo();
//if camera is running
if (mCamera != null){
//and there is more than one camera
mCamera.stopPreview();
mCamera.release();
//swap the id of the camera to be used
if(currentCameraId == Camera.CameraInfo.CAMERA_FACING_BACK){
currentCameraId = Camera.CameraInfo.CAMERA_FACING_FRONT;
}
else {
currentCameraId = Camera.CameraInfo.CAMERA_FACING_BACK;
}
mCamera = Camera.open(currentCameraId);
//setCameraDisplayOrientation(MainActivity.this, currentCameraId, mCamera);
try {
mCamera.setPreviewDisplay(surfaceHolder);
} catch (IOException e) {
e.printStackTrace();
}
mCamera.startPreview();
}
}
CameraView class is here
public class CameraView extends SurfaceView implements SurfaceHolder.Callback{
private SurfaceHolder mHolder;
private Camera mCamera;
int currentCameraId=0;
public CameraView(Context context, Camera camera) {
super(context);
mCamera = camera;
//get the holder and set this class as the callback, so we can get camera data here
mHolder = getHolder();
mHolder.addCallback(this);
mHolder.setType(SurfaceHolder.SURFACE_TYPE_NORMAL);
}
#Override
public void surfaceCreated(SurfaceHolder surfaceHolder) {
try {
mCamera.setPreviewDisplay(surfaceHolder);
mCamera.startPreview();
}catch (IOException e) {
Log.d("ERROR", "Camera error on surfaceCreated " + e.getMessage());
}
}
#Override
public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
mCamera.startPreview();
if(mHolder.getSurface() == null)//check if the surface is ready to receive camera data
return;
try{
mCamera.stopPreview();
} catch (Exception e){
//this will happen when you are trying the camera if it's not running
}
try{
mCamera.setPreviewDisplay(mHolder);
mCamera.startPreview();
} catch (IOException e) {
Log.d("ERROR", "Camera error on surfaceChanged " + e.getMessage());
}
}
#Override
public void surfaceDestroyed(SurfaceHolder holder) {
mCamera.stopPreview();
mCamera.release();
}
}
It will be my very pleasure if you share any link with me that can help me out for taking picture too .Thanks in advance :)
I have the code setup (obviously not correctly but it seems ok)
My test code for capturing frame is like this:
frameCallback = new Camera.PreviewCallback() {
public void onPreviewFrame(byte[] data, Camera camera) {
System.out.println("preview frame captured");
But this onPreviewFrame is never ran, as the print statement tests.
The weird thing is, the preview is showing up perfectly on my surface. i.e- I can see it on my screen and there is no errors. Why isn't onPreviewFrame being called then?
Here is all my code for reference:
public class HuntActivity extends AppCompatActivity implements SurfaceHolder.Callback{
Camera camera;
SurfaceView surfaceView;
SurfaceHolder surfaceHolder;
Camera.PreviewCallback frameCallback;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_hunt);
surfaceView = (SurfaceView) findViewById(R.id.surfaceView);
surfaceHolder = surfaceView.getHolder();
surfaceHolder.addCallback(this);
surfaceHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
frameCallback = new Camera.PreviewCallback() {
public void onPreviewFrame(byte[] data, Camera camera) {
System.out.println("preview frame captured");
}
};
}
#Override
public void surfaceCreated(SurfaceHolder holder) {
try {camera = Camera.open();
} catch (RuntimeException e) {
System.err.println(e);
return;
}
camera.setPreviewCallback(frameCallback);
Camera.Parameters param;
param = camera.getParameters();
param.setPreviewSize(800, 480);
camera.setDisplayOrientation(90);
camera.setParameters(param);
try {
camera.setPreviewDisplay(surfaceHolder);
camera.startPreview();
} catch (Exception e) {
System.err.println(e);
return;
}
}
#Override
public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
refreshCamera();
}
#Override
public void surfaceDestroyed(SurfaceHolder holder) {
camera.stopPreview();
camera.release();
camera = null;
}
public void refreshCamera() {
if (surfaceHolder.getSurface() == null) {return;}
try {camera.stopPreview();
} catch (Exception e){}
try {
camera.setPreviewDisplay(surfaceHolder);
camera.startPreview();
} catch (Exception e) {}
}
refreshCamera();
Do not call that function there. It will stop the preview functionality before you can use it.
Move following code to onSurfaceChanged() and use the width and heigth parameters
Camera.Parameters param;
param = camera.getParameters();
//param.setPreviewSize(800, 480);
param.setPreviewSize(width, height);
... and the rest of those lines...
Never hardcode resolutions like 800x480
try to unlock
camera.unlock();
camera.reconnect();
frameCallback.setPreviewCallback(mCallback);
Im trying to set up a custom SurfaceView (which work as excepted) for the first time.
After onResume/onPause has been called im getting a "media server died" message.
After the media server died i can add another preview. Any idea why it's crashing? Im Releasing the Camera in onPause and open the camera on onResume.
-- Camera Activity --
public class CameraActivity extends DashboardActivity {
private static String TAG = "CameraActivity";
Camera camera;
CameraPreview cameraPreview;
Context _context;
FrameLayout frameLayout;
CameraPreview preview;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.camera_layout);
this._context = this;
frameLayout = (FrameLayout) findViewById(R.id.preview);
}
#Override
protected void onResume() {
super.onResume();
camera = Camera.open();
if (null != camera) {
camera.setDisplayOrientation(90);
preview = new CameraPreview(getApplicationContext(), camera);
frameLayout.addView(preview);
}
}
#Override
public void onBackPressed() {
super.onBackPressed();
if (camera != null) {
Log.e(TAG, "Camera was not null on back pressed!");
try {
camera.stopPreview();
} catch (Exception e) {
}
// camera.release();
// camera = null;
}
finish();
}
#Override
protected void onPause() {
super.onPause();
if (camera != null) {
camera.release();
camera = null;
}
frameLayout.removeView(preview);
preview = null;
}
-- Camera Preview --
public class CameraPreview extends SurfaceView implements
SurfaceHolder.Callback {
private static final String TAG = "Preview";
SurfaceHolder mHolder;
public Camera camera;
CameraPreview(Context context, Camera camera) {
super(context);
this.camera = camera;
// Install a SurfaceHolder.Callback so we get notified when the
// underlying surface is created and destroyed.
mHolder = getHolder();
mHolder.addCallback(this);
mHolder.setFormat(PixelFormat.RGB_332);
mHolder.setType(SurfaceHolder.SURFACE_TYPE_GPU);
}
public void surfaceCreated(SurfaceHolder holder) {
try {
Camera.Parameters p = camera.getParameters();
p.setPictureSize(80, 60);
p.setColorEffect(android.hardware.Camera.Parameters.EFFECT_NONE);
p.setJpegQuality(20);
p.setPreviewFrameRate(1);
p.setPreviewFpsRange(5, 10);
p.setPreviewSize(80, 60);
camera.setParameters(p);
try {
camera.setPreviewDisplay(holder);
camera.setPreviewCallback(new PreviewCallback() {
public void onPreviewFrame(byte[] data, Camera arg1) {
}
});
} catch (IOException e) {
e.printStackTrace();
}
} catch (Exception e) {
e.printStackTrace();
}
}
public void stopCameraPreview() {
}
public void takePicture() {
camera.takePicture(null, null, null);
stopCameraPreview();
}
public void surfaceDestroyed(SurfaceHolder holder) {
Log.e(TAG, "SurfaceDestroyed called");
if (camera != null) {
try {
camera.stopPreview();
} catch (Exception e) {
}
// camera.lock();
// camera.release();
// camera = null;
}
}
public void surfaceChanged(SurfaceHolder holder, int format, int w, int h) {
Log.d(TAG, "SurfaceChanged called!");
if (holder.getSurface() == null) {
Log.d(TAG, "SurfaceChanged Surface is null! Stopping!");
return;
}
try {
Camera.Parameters parameters = camera.getParameters();
// parameters.setPreviewSize(80, 60);
camera.setParameters(parameters);
// camera.setPreviewDisplay(holder);
camera.startPreview();
} catch (Exception e) {
e.printStackTrace();
}
}
}
The proper way to stop the camera is in
public void onPause() {
super.onPause();
releaseCamera();
}
and
public void releaseCamera() {
if (mCamera != null) {
mCamera.stopPreview();
mCamera.setPreviewCallback(null);
mCamera.release();
mCamera = null;
}
}
I do not have much experience with the Camera functionality in Android. I need to take a photo through code which I am planning to send back to a server. I based my logic off of this post and it works well as long as I do not add mCamera.takePicture(null, null, mPictureCallback); to the end of the surfaceChange method (which is what I want I guess). When I do add that line, it works sometimes but most of the times, I just get back a black screen. This is the main problem. I don't think there is a compatibility issue with the device because I got this functionality working atleast 3-4 times earlier.
My device that I am testing on is Galaxy Nexus
public class CameraView extends Activity implements SurfaceHolder.Callback, OnClickListener
{
private static final String TAG = "CameraTest";
Camera mCamera;
boolean mPreviewRunning = false;
public void onCreate(Bundle icicle)
{
super.onCreate(icicle);
Log.e(TAG, "onCreate");
getWindow().setFormat(PixelFormat.TRANSLUCENT);
requestWindowFeature(Window.FEATURE_NO_TITLE);
getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,WindowManager.LayoutParams.FLAG_FULLSCREEN);
setContentView(R.layout.activity_camera_view);
mSurfaceView = (SurfaceView) findViewById(R.id.surface_camera);
mSurfaceView.setOnClickListener(this);
mSurfaceHolder = mSurfaceView.getHolder();
mSurfaceHolder.addCallback(this);
mSurfaceHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
}
#Override
protected void onRestoreInstanceState(Bundle savedInstanceState)
{
super.onRestoreInstanceState(savedInstanceState);
}
Camera.PictureCallback mPictureCallback = new Camera.PictureCallback() {
#Override
public void onPictureTaken(byte[] data, Camera camera) {
// TODO Auto-generated method stub
if (data != null)
{
//Intent mIntent = new Intent();
//mIntent.putExtra("image",imageData);
mCamera.stopPreview();
mPreviewRunning = false;
mCamera.release();
try
{
BitmapFactory.Options opts = new BitmapFactory.Options();
Bitmap bitmap= BitmapFactory.decodeByteArray(data, 0, data.length,opts);
bitmap = Bitmap.createScaledBitmap(bitmap, 480, 480, false);
CameraProjectActivity.image.setImageBitmap(bitmap);
}
catch(Exception e)
{
e.printStackTrace();
}
//StoreByteImage(mContext, imageData, 50,"ImageName");
//setResult(FOTO_MODE, mIntent);
setResult(585);
finish();
}
}
};
protected void onResume()
{
Log.e(TAG, "onResume");
super.onResume();
}
protected void onSaveInstanceState(Bundle outState)
{
super.onSaveInstanceState(outState);
}
protected void onStop()
{
Log.e(TAG, "onStop");
super.onStop();
}
public void surfaceCreated(SurfaceHolder holder)
{
Log.e(TAG, "surfaceCreated");
mCamera = Camera.open();
mCamera.setDisplayOrientation(90);
}
public void surfaceChanged(SurfaceHolder holder, int format, int w, int h) {
Log.e(TAG, "surfaceChanged");
// XXX stopPreview() will crash if preview is not running
if (mPreviewRunning)
{
mCamera.stopPreview();
}
Camera.Parameters p = mCamera.getParameters();
List<Camera.Size> previewSizes = p.getSupportedPreviewSizes();
Camera.Size previewSize = previewSizes.get(3);
p.setPreviewSize(previewSize.width, previewSize.height);
mCamera.setParameters(p);
try
{
mCamera.setPreviewDisplay(holder);
}
catch (Exception e)
{
// TODO Auto-generated catch block
e.printStackTrace();
}
mCamera.startPreview();
mPreviewRunning = true;
// THIS IS THE CODE THAT BREAKS IT. IS THERE ANY OTHER WAY TO DO THIS??? ********
// mCamera.takePicture(null, null, mPictureCallback);
}
#Override
public void surfaceDestroyed(SurfaceHolder holder) {
Log.e(TAG, "surfaceDestroyed");
// mCamera.stopPreview();
// mPreviewRunning = false;
// mCamera.release();
}
private SurfaceView mSurfaceView;
private SurfaceHolder mSurfaceHolder;
#Override
public void onClick(View v) {
// TODO Auto-generated method stub
mCamera.takePicture(null, mPictureCallback, mPictureCallback);
}
}
Any help would be appreciated.
Thanks!
I am not sure if this is a good solution, but I just fixed it by making the surfaceChanged() method synchronized and making the thread wait for a second just before I call takePicture.
try {
this.wait(1000);
mCamera.takePicture(null, null, mPictureCallback);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
I believe that it is recommended to call startPreview() before setPreviewDisplay(), but this should not make a major difference.
What you see is that it takes time for the camera to initialize, and it cannot take a picture until it's ready. It's better to use a callback from camera to decide that it's ready, than to wait for arbitrary 1000 ms.
The callback you can use is a Camera.PreviewCallback. You can implement it in your CameraView class. To trigger the callback, simply add setOneShotPreviewCallback(this) to CameraView.surfaceChanged():
mCamera.startPreview();
mCamera.setPreviewDisplay(holder);
mCamera.setOneShotPreviewCallback(this);