I want to capture photos continuously so that every time user don't have to press the button.
My code
public class CameraView extends Activity implements SurfaceHolder.Callback, OnClickListener {
private static final String TAG = "CameraTest";
Camera mCamera;
boolean mPreviewRunning = false;
String currentDateTimeString;
Timer myTimer;
ImageView img;
static boolean flagShowPic = true;
public static int TIME_BET_SHOOT = 1000;
public void onCreate(Bundle icicle) {
super.onCreate(icicle);
try {
getWindow().setFormat(PixelFormat.TRANSLUCENT);
requestWindowFeature(Window.FEATURE_NO_TITLE);
getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN);
setContentView(R.layout.cameraview);
img = (ImageView) findViewById(R.id.blankImage);
mSurfaceView = (SurfaceView) findViewById(R.id.surface_camera);
mSurfaceView.setOnClickListener(this);
mSurfaceHolder = mSurfaceView.getHolder();
mSurfaceHolder.addCallback(this);
} catch (Exception e) {
e.printStackTrace();
}
}
Camera.PictureCallback mPictureCallback = new Camera.PictureCallback() {
public void onPictureTaken(byte[] data, Camera camera) {
if (data != null) {
try {
currentDateTimeString = DateFormat.getDateTimeInstance().format(new Date());
currentDateTimeString = currentDateTimeString.replace(" ", "_");
currentDateTimeString = currentDateTimeString.replace(":", "");
File f = new File(CaptureCameraImage.imageSavePath + currentDateTimeString + ".png");
f.createNewFile();
FileOutputStream fo = new FileOutputStream(f);
fo.write(data);
fo.close();
if (flagShowPic == true) {
BitmapFactory.Options opts = new BitmapFactory.Options();
Bitmap bitmap = BitmapFactory.decodeByteArray(data, 0, data.length, opts);
bitmap = Bitmap.createScaledBitmap(bitmap, 300, 300, false);
img.setImageBitmap(bitmap);
}
mCamera.startPreview();
} catch (Exception e) {
e.printStackTrace();
}
setResult(585);
}
}
};
// protected void onStop() {
// Log.e(TAG, "onStop");
// super.onStop();
// if (null != myTimer) {
// myTimer.cancel();
// }
// if (null != mCamera) {
// mCamera.stopPreview();
// mPreviewRunning = false;
// mCamera.release();
// }
// }
public void surfaceCreated(SurfaceHolder holder) {
Log.e(TAG, "surfaceCreated");
try {
mCamera = Camera.open(CaptureCameraImage.cameraID);
} catch (Exception e) {
e.printStackTrace();
}
}
public void surfaceChanged(SurfaceHolder holder, int format, int w, int h) {
Log.e(TAG, "surfaceChanged");
try {
if (mPreviewRunning) {
//mCamera.stopPreview();
}
Camera.Parameters p = mCamera.getParameters();
p.setPreviewSize(300, 300);
if (CaptureCameraImage.cameraID == 0) {
String stringFlashMode = p.getFlashMode();
if (stringFlashMode.equals("torch"))
p.setFlashMode("on"); // Light is set off, flash is set to
// normal 'on' mode
else
p.setFlashMode("torch");
}
mCamera.setPreviewDisplay(holder);
mCamera.startPreview();
mPreviewRunning = true;
myTimer = new Timer();
MyTimerTask myTimerTask = new MyTimerTask();
myTimer.scheduleAtFixedRate(myTimerTask, 1000, TIME_BET_SHOOT);
} catch (Exception e) {
e.printStackTrace();
}
}
public void surfaceDestroyed(SurfaceHolder holder) {
Log.e(TAG, "surfaceDestroyed");
// mCamera.stopPreview();
// mPreviewRunning = false;
// mCamera.release();
}
private SurfaceView mSurfaceView;
private SurfaceHolder mSurfaceHolder;
private class MyTimerTask extends TimerTask {
#Override
public void run() {
runOnUiThread(new Runnable() {
#Override
public void run() {
if (mPreviewRunning == true)
mCamera.takePicture(null, mPictureCallback, mPictureCallback);
}
});
}
}
#Override
public void onClick(View v) {
}
}
I'm getting exception
FATAL EXCEPTION: main java.lang.RuntimeException: takePicture failed
at android.hardware.Camera.native_takePicture(Native Method)
at android.hardware.Camera.takePicture(Camera.java:1194)
at android.hardware.Camera.takePicture(Camera.java:1139)
at com.androidmyway.demo.capturecameraimage.CameraView$MyTimerTask$1.run(CameraView.java:152)
at android.os.Handler.handleCallback(Handler.java:730)
at android.os.Handler.dispatchMessage(Handler.java:92)
at android.os.Looper.loop(Looper.java:137)
at android.app.ActivityThread.main(ActivityThread.java:5419)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:525)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1187)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1003)
at dalvik.system.NativeStart.main(Native Method)
use this to open camera. to avoid errors while opening camera.
private void safeCameraOpen(int id) {
try {
releaseCameraAndPreview();
mCamera = Camera.open(id);
} catch (Exception e) {
Log.e(getString(R.string.app_name), "failed to open Camera");
e.printStackTrace();
}
}
private void releaseCameraAndPreview() {
if (mCamera != null) {
mCamera.release();
mCamera = null;
}
}
Related
I know there are some similar subjects connecting to this but I couldn't solve mine. anyway,I am trying to make some front camera with "flash" where I am calling Camera.release only once in the whole activities, when surfaceDestroyed(). so here is my MainActivity:
#SuppressWarnings("deprecation")
public class MainActivity extends AppCompatActivity {
private Camera mCamera = null;
private CameraPreview mCameraView = null;
private int cameraId = 0;
private void addView() {
if (!getPackageManager()
.hasSystemFeature(PackageManager.FEATURE_CAMERA)) {
Toast.makeText(this, "No camera on this device", Toast.LENGTH_LONG)
.show();
} else {
cameraId = findFrontFacingCamera();
if (cameraId < 0) {
Toast.makeText(this, "No front facing camera found.",
Toast.LENGTH_LONG).show();
} else {
try {
mCamera = Camera.open(cameraId);
} catch (Exception e) {
Log.d("ERROR", "Failed to get camera: " + e.getMessage());
}
}
}
if (mCamera != null) {
mCameraView = new CameraPreview(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
}
}
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
addView();
ImageButton imgCapture = (ImageButton) findViewById(R.id.imgCapture);
imgCapture.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
WindowManager.LayoutParams layout = getWindow().getAttributes();
layout.screenBrightness = 1F;
getWindow().setAttributes(layout);
setContentView(R.layout.whitescreen);
new CountDownTimer(3000, 1000) {
public void onTick(long millisUntilFinished) {
}
public void onFinish() {
if (CameraPreview.safeToTakePicture) {
CameraPreview.safeToTakePicture = false;
mCamera.takePicture(null, null,
new PhotoHandler(getApplicationContext()));
}
setContentView(R.layout.activity_main);
addView();
}
}.start();
}
});
}
private int findFrontFacingCamera() {
int cameraId = -1;
// Search for the front facing camera
int numberOfCameras = Camera.getNumberOfCameras();
for (int i = 0; i < numberOfCameras; i++) {
Camera.CameraInfo info = new Camera.CameraInfo();
Camera.getCameraInfo(i, info);
if (info.facing == Camera.CameraInfo.CAMERA_FACING_FRONT) {
Log.d("Camera", "Camera found");
cameraId = i;
break;
}
}
return cameraId;
}
}
When pressing the capture button I switch the layout to an empty one(white layout), wait 3 seconds take a picture and then add the camera view again, here is my CameraPreview class:
#SuppressWarnings("deprecation")
public class CameraPreview extends SurfaceView implements SurfaceHolder.Callback {
private SurfaceHolder mHolder;
private Camera mCamera;
public static boolean safeToTakePicture = false;
public CameraPreview(Context context, Camera camera) {
super(context);
mCamera = camera;
mCamera.setDisplayOrientation(90);
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 surfaceHolder, int i, int i2, int i3) {
if (mHolder.getSurface() == null)
return;
try {
mCamera.stopPreview();
} catch (Exception e) {
Log.d("ERROR", "Trying the camera and it's not running");
}
try {
mCamera.setPreviewDisplay(mHolder);
mCamera.startPreview();
safeToTakePicture = true;
} catch (IOException e) {
Log.d("ERROR", "Camera error on surfaceChanged " + e.getMessage());
}
}
#Override
public void surfaceDestroyed(SurfaceHolder surfaceHolder) {
mCamera.stopPreview();
mCamera.release();
}
}
I get the error Camera is being used after Camera.release was called a lot of times, for example when taking a picture:
07-02 14:49:35.561 19017-19017/davidandguy.com.selfielightcamera E/AndroidRuntime: FATAL EXCEPTION: main
Process: davidandguy.com.selfielightcamera, PID: 19017
java.lang.RuntimeException: Camera is being used after Camera.release() was called
at android.hardware.Camera.native_takePicture(Native Method)
at android.hardware.Camera.takePicture(Camera.java:1523)
at android.hardware.Camera.takePicture(Camera.java:1468)
at davidandguy.com.selfielightcamera.MainActivity$1$1.onFinish(MainActivity.java:65)
at android.os.CountDownTimer$1.handleMessage(CountDownTimer.java:127)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:158)
at android.app.ActivityThread.main(ActivityThread.java:7224)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1230)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1120)
Or even when onResume() is called, for example, minimize the activity and then run again. I know I need to put somewhere onPause() and onResume() but I don't know where/how to implement it. thanks
This is really overdue but as I managed to solve a similar problem of mine a minute ago, I thought I'd contribute for the benefit of yourself and anyone else who might be desperately searching Stack.
I cant see your lifecycle code here , but heres what worked for me, surfaceDestroyed was empty in my case
Firstly, the cameraPreview
public void surfaceChanged(SurfaceHolder surfaceHolder, int format, int width, int height) {
try {
this.mCamera.setPreviewDisplay(surfaceHolder);
this.mCamera.startPreview();
} catch (Exception e) {
}
}
public void surfaceCreated(SurfaceHolder surfaceHolder) {
try {
//TODO we need this here too because on SurfaceCreated we always need to open the camera, in case its released
this.mCamera.setPreviewDisplay(surfaceHolder);
this.mCamera.setDisplayOrientation(90);
//this.mCamera.startPreview();
} catch (IOException e) {
}
}
Next, the CameraActivity
#Override
public void onResume() {
super.onResume();
try{
mCamera = openFrontFacingCameraGingerbread();
// Add to Framelayout
this.mCameraPreview = new CameraPreview(this, this.mCamera);
mImage.removeAllViews();
this.mImage.addView(this.mCameraPreview);
}catch (RuntimeException ex){
}
}
#Override
public void onPause() {
super.onPause();
captureButton.setText("Begin Capture");
if(CameraActivity.this.timer !=null) {
CameraActivity.this.timer.cancel();
CameraActivity.this.timer.purge();
CameraActivity.this.timer = null;
}
if (mCamera != null) {
mCamera.setPreviewCallback(null);
mCameraPreview.getHolder().removeCallback(mCameraPreview);
mCamera.release();
mCamera = null;
}
}
#Override
protected void onDestroy(){
super.onDestroy();
releaseCameraAndPreview();
}
private void releaseCameraAndPreview() {
if (mCamera != null) {
mCamera.stopPreview();
mCamera.release();
mCamera = null;
}
if(mCameraPreview != null){
mCameraPreview.destroyDrawingCache();
mCameraPreview.mCamera = null;
}
}
I'm being frustrated by something that should very simple: taking a picture using Android's camera API (with no preview). I've been following several answers from stackoverflow, but with no success.
Initially I followed this answer (#sush): How to take pictures from the camera without preview when my app starts?
But the PictureCallback was never called. I then followed this answer (#Alex Cohn):
You correctly found that takePicture() should not be called before startPreview() or immediately after it. (onPictureTaken never called)
Which led me to try three solutions.
Solution 1
The first solution places a callback in SurfaceHolder:
public class TestActivity extends Activity
{
private Camera mCamera;
#Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
takeSnapShot();
}
#Override
protected void onPause()
{
clearCamera();
super.onPause();
}
private void takeSnapShot()
{
if (mCamera == null)
{
try { mCamera = Camera.open(); }
catch (Exception e) { e.printStackTrace(); }
SurfaceView surface = (SurfaceView) findViewById(R.id.preview);
surface.getHolder().addCallback(mSurfaceHolderCallback);
try { mCamera.setPreviewDisplay(surface.getHolder()); }
catch (IOException e) { e.printStackTrace(); }
mCamera.startPreview();
}
}
private final SurfaceHolder.Callback mSurfaceHolderCallback = new SurfaceHolder.Callback()
{
#Override
public void surfaceCreated(SurfaceHolder holder)
{
try
{
mCamera.setPreviewDisplay(holder);
mCamera.startPreview();
mCamera.takePicture(null, null, mPictureCallback);
}
catch (IOException e) { e.printStackTrace(); }
}
#Override
public void surfaceDestroyed(SurfaceHolder holder) {}
#Override
public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {}
};
private final Camera.PictureCallback mPictureCallback = new Camera.PictureCallback()
{
#Override
public void onPictureTaken(byte[] data, Camera camera)
{
FileOutputStream outStream = null;
try
{
File dir_path =
Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DCIM);
File pictureFile = new File(dir_path, "snapshot-test.jpg");
outStream = new FileOutputStream(pictureFile);
outStream.write(data);
outStream.close();
}
catch (FileNotFoundException e) { e.printStackTrace(); }
catch (IOException e) { e.printStackTrace(); }
finally { clearCamera(); }
}
};
private void clearCamera()
{
if (mCamera != null)
{
try
{
mCamera.stopPreview();
mCamera.release();
mCamera = null;
}
catch (final Exception e) { e.printStackTrace(); }
}
}
This first solution works if I call takeSnapShot just once. Unfortunately, I can't get mSurfaceHolderCallback to run SurfaceCreated multiple times.
Solution 2
My second solution was to use PreviewCallback. In this solution I've re-used onPause:
public class TestActivity extends Activity
{
private Camera mCamera;
private boolean mReadyToTakePicture;
#Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
takeSnapShot();
}
private void takeSnapShot()
{
if (mCamera == null)
{
try { mCamera = Camera.open(); }
catch (Exception e) { e.printStackTrace(); }
mCamera.setPreviewCallback(mRawPreviewCallback);
SurfaceView surface = (SurfaceView) findViewById(R.id.preview);
try { mCamera.setPreviewDisplay(surface.getHolder()); }
catch (IOException e) { e.printStackTrace(); }
mCamera.startPreview();
}
}
private final Camera.PreviewCallback mRawPreviewCallback = new Camera.PreviewCallback()
{
#Override
public void onPreviewFrame(byte [] rawData, Camera camera)
{
int rawDataLength = 0;
if (rawData != null) { rawDataLength = rawData.length; }
if (rawDataLength > 0 && !mReadyToTakePicture)
{
mReadyToTakePicture = true;
mCamera.takePicture(null, null, mPictureCallback);
}
else { mReadyToTakePicture = false; }
}
};
private final Camera.PictureCallback mPictureCallback = new Camera.PictureCallback()
{
#Override
public void onPictureTaken(byte[] data, Camera camera)
{
FileOutputStream outStream = null;
mReadyToTakePicture = false;
try
{
File dir_path =
Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DCIM);
File pictureFile = new File(dir_path, "snapshot-test.jpg");
outStream = new FileOutputStream(pictureFile);
outStream.write(data);
outStream.close();
}
catch (FileNotFoundException e) { e.printStackTrace(); }
catch (IOException e) { e.printStackTrace(); }
finally { clearCamera(); }
}
};
private void clearCamera()
{
if (mCamera != null)
{
try
{
mReadyToTakePicture = false;
mCamera.stopPreview();
mCamera.release();
mCamera = null;
}
catch (final Exception e) { e.printStackTrace(); }
}
}
}
In this solution both mRawPreviewCallback and mPictureCallback are never called.
Solution 3
My last example is using an AsyncTask that waits for a while before actually taking a picture. Hopefully this would give enough time for the preview to be set. In this solution I've re-used onPause and clearCamera:
public class TestActivity extends Activity
{
private Camera mCamera;
#Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
takeSnapShot();
}
private void takeSnapShot()
{
if (mCamera == null)
{
try { mCamera = Camera.open(); }
catch (Exception e) { e.printStackTrace(); }
SurfaceView surface = (SurfaceView) findViewById(R.id.preview);
try { mCamera.setPreviewDisplay(surface.getHolder()); }
catch (IOException e) { e.printStackTrace(); }
mCamera.startPreview();
new CameraTask().execute(mCamera);
}
}
private class CameraTask extends AsyncTask<Camera, Void, Void>
{
protected String doInBackground(Camera... cameras)
{
try { Thread.sleep(1500); } catch (InterruptedException e)
{ e.printStackTrace(); }
mCamera = cameras[0];
mCamera.takePicture(null, null, mPictureCallback);
return mPicturePath;
}
private final Camera.PictureCallback mPictureCallback = new Camera.PictureCallback()
{
#Override
public void onPictureTaken(byte[] data, Camera camera)
{
FileOutputStream outStream = null;
try
{
File dir_path =
Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DCIM);
File pictureFile = new File(dir_path, "snapshot-test.jpg");
mPicturePath = pictureFile.getAbsolutePath();
outStream = new FileOutputStream(pictureFile);
outStream.write(data);
outStream.close();
}
catch (FileNotFoundException e) { e.printStackTrace(); }
catch (IOException e) { e.printStackTrace(); }
finally { clearCamera(); }
}
};
}
}
As with solution 2, onPictureTaken is never called.
In all examples the layout of my SurfaceView is as follows (for no preview):
<SurfaceView
android:id="#+id/preview"
android:layout_width="1dp"
android:layout_height="1dp"></SurfaceView>
At this point I'm running out of ideas. My first example was successful in taking one picture, so if I could at least force the app to run surfaceCreated multiple times, it should work. Any ideas?
Ok so I have faced this issue before on gingerbread devices.
Do the following:
mCamera.takePicture(null, null, new Camera.PictureCallback() {
#Override
public void onPictureTaken(final byte[] originalData, Camera camera) {
// logic here
});
instead of:
mCamera.takePicture(null, null,myCallback);
private PictureCallback mPicallback = new PictureCallback(){
};
i am try to to capture image,which previews in a surfaceview and there is a button by which picture taken and save onto memory card.preview and capture works well but not able to store on memory card..
there are created file but picture not store one by one...
plz help me...
my try one is here....
public class MainActivity extends Activity {
int TAKE_PHOTO_CODE = 0;
public static int count=0;
Camera mCamera;
private CameraView cameraview;
RelativeLayout mainlayout;
ImageView capture;
ImageView image;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
cameraview = new CameraView(this, CameraInfo.CAMERA_FACING_BACK);
setContentView(R.layout.activity_main);
mainlayout = (RelativeLayout) findViewById(R.id.mainlayout);
mainlayout.addView(cameraview);
capture=(ImageView)findViewById(R.id.capture);
/////////////////////////////////////////////////////////
final String dir = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES) + "/picFolder/";
File newdir = new File(dir);
newdir.mkdirs();
capture.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View arg0) {
// TODO Auto-generated method stub
//if(android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.HONEYCOMB) {
// getWindow().setFlags(WindowManager.LayoutParams.FLAG_SECURE, WindowManager.LayoutParams.FLAG_SECURE);
cameraview.mCamera.takePicture(shutterCallback, rawCallback,
jpegCallback);
Toast.makeText(getApplicationContext(), "Captured", 2000).show();
}
});
}
ShutterCallback shutterCallback = new ShutterCallback() {
public void onShutter() {
// Log.d(TAG, "onShutter'd");
}
};
/** Handles data for raw picture */
PictureCallback rawCallback = new PictureCallback() {
public void onPictureTaken(byte[] data, Camera camera) {
//Log.d(TAG, "onPictureTaken - raw");
}
};
/** Handles data for jpeg picture */
PictureCallback jpegCallback = new PictureCallback() {
public void onPictureTaken(byte[] data, Camera camera) {
FileOutputStream outStream = null;
try {
outStream = new FileOutputStream(String.format(
"/sdcard/Demo%d.jpg", System.currentTimeMillis()));
outStream.write(data);
outStream.close();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
};
}
and my CameraView class is here..
public class CameraView extends SurfaceView implements SurfaceHolder.Callback {
SurfaceHolder mHolder;
Camera mCamera;
int mCameraFacingInfo;
Context m_context;
public CameraView(Context context, int camereface) {
super(context);
// TODO Auto-generated constructor stub
m_context = context;
mCameraFacingInfo = camereface;
mHolder = getHolder();
mHolder.addCallback(this);
mHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
}
#Override
public void surfaceChanged(SurfaceHolder holder, int format, int width,
int height) {
// TODO Auto-generated method stub
if (mCamera != null) {
int rotation = ((Activity) m_context).getWindowManager()
.getDefaultDisplay().getRotation();
if (rotation == Surface.ROTATION_0
|| rotation == Surface.ROTATION_180) {
mCamera.setDisplayOrientation(90);
} else if (rotation == Surface.ROTATION_90) {
mCamera.setDisplayOrientation(0);
} else if (rotation == Surface.ROTATION_270) {
mCamera.setDisplayOrientation(180);
}
Camera.Parameters parameters = mCamera.getParameters();
parameters.setPreviewSize(width, height);
// mCamera.setParameters(parameters);
mCamera.startPreview();
}
}
#TargetApi(Build.VERSION_CODES.GINGERBREAD)
#SuppressLint("NewApi")
#Override
public void surfaceCreated(SurfaceHolder holder) {
// TODO Auto-generated method stub
// ////////////////////////////////////////////////////
/*mCamera.setCameraViewDisplay(holder);
mCamera.setCameraViewCallback(new CameraViewCallback() {
public void onPreviewFrame(byte[] data, Camera arg1) {
//
CameraView.this.invalidate();
}
});
*/
// //////////////////////////////////////////
synchronized (this) {
int cameraFacingInfo = -1;
boolean errorFound = false;
boolean hasFeatCamera = m_context.getPackageManager()
.hasSystemFeature(PackageManager.FEATURE_CAMERA);
if (hasFeatCamera) {
try {
cameraFacingInfo = mCameraFacingInfo;
mCamera = Camera.open(cameraFacingInfo);
} catch (Exception e) {
mCamera = Camera.open(0);
}
} else if (CameraInfo.CAMERA_FACING_FRONT > -1) {
try {
cameraFacingInfo = CameraInfo.CAMERA_FACING_FRONT;
mCamera = Camera.open(cameraFacingInfo);
} catch (Exception e) {
errorFound = true;
}
if (errorFound == true) {
try {
mCamera = Camera.open(0);
cameraFacingInfo = 0;
} catch (Exception e) {
cameraFacingInfo = -1;
}
}
}
if (cameraFacingInfo < 0) {
Toast.makeText(m_context, "No camera found.", Toast.LENGTH_LONG)
.show();
}
if (mCamera != null) {
try {
mCamera.setPreviewDisplay(holder);
int rotation = ((Activity) m_context).getWindowManager()
.getDefaultDisplay().getRotation();
if (rotation == Surface.ROTATION_0
|| rotation == Surface.ROTATION_180) {
// Log.i(TAG, "0");
mCamera.setDisplayOrientation(90);
} else if (rotation == Surface.ROTATION_90) {
// Log.i(TAG, "90");
mCamera.setDisplayOrientation(0);
} else if (rotation == Surface.ROTATION_270) {
// Log.i(TAG, "270");
mCamera.setDisplayOrientation(180);
}
} catch (IOException exception) {
mCamera.release();
mCamera = null;
// TODO: add more exception handling logic here
}
}
}
}
#Override
public void surfaceDestroyed(SurfaceHolder holder) {
// TODO Auto-generated method stub
if (mCamera != null) {
mCamera.stopPreview();
mCamera.release();
mCamera = null;
}
}
public void setCameraFacingInfo(int cameraFacingInfo) {
mCameraFacingInfo = cameraFacingInfo;
}
}
Try to change your jpegCallback class to this:
PictureCallback jpegCallback = new PictureCallback() {
public void onPictureTaken(byte[] data, Camera camera) {
//Creating empty file in sdcard
File pictureFile = new File(String.format("/sdcard/Demo%d.jpg", System.currentTimeMillis()));
if (pictureFile == null) {
Log.e("IMAGE CAPTURE", "Error creating media file, check storage permissions: ");
return;
}
if (data != null) {
BitmapFactory.Options opts = new BitmapFactory.Options();
ActivityManager activityManager = (ActivityManager) MainActivity.this.getSystemService(Activity.ACTIVITY_SERVICE);
int memoryLimit = 100;
if (activityManager != null) {
memoryLimit = activityManager.getMemoryClass();
}
// Considering memory limitation of device we will resize image to prevent OutOfMemory
if (memoryLimit < 20) {
opts.inSampleSize = 6;
} else if (memoryLimit < 40) {
opts.inSampleSize = 4;
} else if (memoryLimit < 64) {
opts.inSampleSize = 2;
}
Bitmap bitmap = BitmapFactory.decodeByteArray(data, 0, data.length, opts);
try {
FileOutputStream fos = new FileOutputStream(pictureFile);
if (bitmap.compress(Bitmap.CompressFormat.JPEG, 90, fos)) {
fos.close();
}
bitmap.recycle();
} catch (FileNotFoundException e) {
} catch (IOException e) {
}
}
}
I am using camera in my application,I have no done more work on camera my requirement is only taken picture and with front and back camera and flash light.Camera will be open inside a customview for that I am using this code:-
public class CaptureDealImage extends Activity implements OnClickListener,
CameraCallback {
private Camera myCamera;
private MyCameraSurfaceView myCameraSurfaceView;
private MediaRecorder mediaRecorder;
private Button objbtncapture, objbtnback, objbtngalary, objbtnretake,
objbtnuse;
private Button objbtnflashlight, objbbtnfrontcam;// ,flashButton_p,flashButton_l,cameraRotate_p,cameraRotate_l;
private boolean recording;
private TextView show_p, show_l;
int nCurrentOrientation;
private WakeLock wakeLock;
private int count, mode;
private boolean backendCamera = true;
private FrameLayout mymiddlelayout;
private String sdcardpath;
private boolean flashlight = false;
private boolean cameramode = false;
private boolean isfrontcamera = false;
private RelativeLayout objrelativeLayoutretake, objrelativeLayout3;
private byte[] data;
/** Called when the activity is first created. */
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.dealpick);
PowerManager mgr = (PowerManager) getSystemService(Context.POWER_SERVICE);
wakeLock = mgr
.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "MyWakeLock");
wakeLock.acquire();
// Get Camera for preview
objbtnflashlight = (Button) findViewById(R.id.btnflashlight);
objbbtnfrontcam = (Button) findViewById(R.id.bbtnfrontcam);
objbtncapture = (Button) findViewById(R.id.btncapture);
objbtngalary = (Button) findViewById(R.id.btngalary);
objbtnback = (Button) findViewById(R.id.btnback);
objbtnretake = (Button) findViewById(R.id.btnretake);
objbtnuse = (Button) findViewById(R.id.btnuse);
objrelativeLayoutretake = (RelativeLayout) findViewById(R.id.relativeLayoutretake);
objrelativeLayout3 = (RelativeLayout) findViewById(R.id.relativeLayout3);
objbtnback.setOnClickListener(this);
objbtncapture.setOnClickListener(this);
objbtngalary.setOnClickListener(this);
objbtnflashlight.setOnClickListener(this);
objbbtnfrontcam.setOnClickListener(this);
objbtnretake.setOnClickListener(this);
objbtnuse.setOnClickListener(this);
}
private Camera getCameraInstance() {
Camera c = null;
try {
c = Camera.open(); // attempt to get a Camera instance
Display getOrient = getWindowManager().getDefaultDisplay();
if (getOrient.getHeight() > getOrient.getWidth()) {
c.setDisplayOrientation(90);
}
} catch (Exception e) {
}
return c; // returns null if camera is unavailable
}
#Override
protected void onPause() {
super.onPause();
releaseCamera();
}
#Override
protected void onResume() {
// TODO Auto-generated method stub
super.onResume();
myCamera = getCameraInstance();
if (myCamera == null) {
Toast.makeText(CaptureDealImage.this, "Fail to get Camera",
Toast.LENGTH_LONG).show();
}
myCameraSurfaceView = new MyCameraSurfaceView(this, myCamera);
mymiddlelayout = (FrameLayout) findViewById(R.id.middlelayout);
mymiddlelayout.removeAllViews();
mymiddlelayout.addView(myCameraSurfaceView);
myCameraSurfaceView.setCallback(this);
}
private void releaseCamera() {
/*
* if (myCamera != null) { myCamera.release(); // release the camera for
* other applications myCamera = null; }
*/
Camera camera = this.myCameraSurfaceView.getCamera();
if (camera != null) {
camera.stopPreview();
camera.release();
camera = null;
}
}
#Override
protected void onDestroy() {
super.onDestroy();
wakeLock.release();
/*
* ReleaseRootBitmap mReleaseRootBitmap=new ReleaseRootBitmap();
* LinearLayout
* mLinearLayout=(LinearLayout)findViewById(R.id.record_video_parent);
* mReleaseRootBitmap.unbindDrawables(mLinearLayout);
*/
}
public class MyCameraSurfaceView extends SurfaceView implements
SurfaceHolder.Callback {
private SurfaceHolder mHolder;
private Camera mCamera;
private CameraCallback callback = null;
private boolean isStarted = true;
public MyCameraSurfaceView(Context context, Camera camera) {
super(context);
mCamera = camera;
initialize(context);
}
public MyCameraSurfaceView(Context context) {
super(context);
initialize(context);
}
public void setCallback(CameraCallback callback) {
this.callback = callback;
}
public void startPreview() {
mCamera.startPreview();
}
public void initialize(Context mcontext) {
// Install a SurfaceHolder.Callback so we get notified when the
// underlying surface is created and destroyed.
mHolder = getHolder();
mHolder.addCallback(this);
// deprecated setting, but required on Android versions prior to 3.0
mHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
}
#Override
public void surfaceChanged(SurfaceHolder holder, int format,
int weight, int height) {
if (holder.getSurface() == null) {
// preview surface does not exist
return;
}
// stop preview before making changes
try {
if (null != mCamera) {
mCamera.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 {
if (null != mCamera) {
mCamera.setPreviewDisplay(holder);
mCamera.startPreview();
}
/*
* if (null != camera) { camera.startPreview();
*/
} catch (Exception e) {
Log.d("check",
"Error starting camera preview: " + e.getMessage());
}
}
public Camera getCamera() {
return this.mCamera;
}
public void startTakePicture() {
mCamera.autoFocus(new AutoFocusCallback() {
#Override
public void onAutoFocus(boolean success, Camera camera) {
takePicture();
}
});
}
public void takePicture() {
mCamera.takePicture(new ShutterCallback() {
#Override
public void onShutter() {
if (null != callback)
callback.onShutter();
}
}, new PictureCallback() {
#Override
public void onPictureTaken(byte[] data, Camera camera) {
if (null != callback)
callback.onRawPictureTaken(data, camera);
}
}, new PictureCallback() {
#Override
public void onPictureTaken(byte[] data, Camera camera) {
if (null != callback)
callback.onJpegPictureTaken(data, camera);
}
});
}
#Override
public void surfaceCreated(SurfaceHolder holder) {
try {
// mCamera.startPreview();
try {
mCamera.setPreviewDisplay(holder);
} catch (Throwable ignored) {
}
mCamera.setPreviewDisplay(holder);
mCamera.setPreviewCallback(new Camera.PreviewCallback() {
#Override
public void onPreviewFrame(byte[] data, Camera camera) {
if (null != callback)
callback.onPreviewFrame(data, camera);
}
});
} catch (IOException e) {
}
}
#Override
public void surfaceDestroyed(SurfaceHolder holder) {
if (mCamera != null) {
// camera.stopPreview();
mCamera.release();
mCamera = null;
}
}
}
#Override
public void onConfigurationChanged(Configuration newConfig) {
// TODO Auto-generated method stub
super.onConfigurationChanged(newConfig);
Display display = getWindowManager().getDefaultDisplay();
if (display.getHeight() > display.getWidth()) {
myCamera.setDisplayOrientation(90);
show_l.setVisibility(View.GONE);
show_p.setVisibility(View.VISIBLE);
} else {
myCamera.setDisplayOrientation(0);
show_l.setVisibility(View.VISIBLE);
show_p.setVisibility(View.GONE);
}
}
private Handler checkHandler = new Handler() {
#Override
public void handleMessage(Message msg) {
if (recording && count <= 15) {
if (mode == 1) {
show_l.setText(count + "/15");
} else {
show_p.setText(count + "/15");
}
}
}
};
#Override
public void onClick(View v) {
if (v.equals(objbtncapture)) {
myCameraSurfaceView.startTakePicture();
}
if (v.equals(objbtngalary)) {
// releaseCamera();
Intent i = new Intent(
Intent.ACTION_PICK,
android.provider.MediaStore.Images.Media.INTERNAL_CONTENT_URI);
final int ACTIVITY_SELECT_IMAGE = 100;
startActivityForResult(i, ACTIVITY_SELECT_IMAGE);
}
if (v.equals(objbtnflashlight)) {
if (!isfrontcamera) {
if (!flashlight) {
flashlight = true;
Parameters params = myCamera.getParameters();
params.setFlashMode(Parameters.FLASH_MODE_TORCH);
myCamera.setParameters(params);
} else {
flashlight = false;
Parameters params = myCamera.getParameters();
params.setFlashMode(Parameters.FLASH_MODE_OFF);
myCamera.setParameters(params);
}
}
}
if (v.equals(objbbtnfrontcam)) {
if (!cameramode) {
cameramode = true;
switchToCamera(cameramode);
} else {
cameramode = false;
switchToCamera(cameramode);
}
}
if (v.equals(objbtnback)) {
finish();
}
if (v.equals(objbtnretake)) {
objrelativeLayoutretake.setVisibility(View.GONE);
objrelativeLayout3.setVisibility(View.VISIBLE);
myCameraSurfaceView.startPreview();
}
if (v.equals(objbtnuse)) {
try {
PhotoComplete(data);
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
private void switchToCamera(boolean frontcamera) {
releaseCamera();
if (frontcamera) {
isfrontcamera = true;
myCamera = getFrontCameraId();
} else {
isfrontcamera = false;
myCamera = getCameraInstance();
}
if (myCamera == null) {
Toast.makeText(CaptureDealImage.this, "fail to get front camera",
Toast.LENGTH_SHORT).show();
myCamera = getCameraInstance();
}
myCameraSurfaceView = new MyCameraSurfaceView(this, myCamera);
mymiddlelayout = (FrameLayout) findViewById(R.id.middlelayout);
mymiddlelayout.removeAllViews();
mymiddlelayout.addView(myCameraSurfaceView);
}
Camera getFrontCameraId() {
int cameraCount = 0;
Camera.CameraInfo cameraInfo = new Camera.CameraInfo();
cameraCount = Camera.getNumberOfCameras();
Camera camera = null;
for (int camIdx = 0; camIdx < cameraCount; camIdx++) {
Camera.getCameraInfo(camIdx, cameraInfo);
if (cameraInfo.facing == Camera.CameraInfo.CAMERA_FACING_FRONT) {
try {
camera = Camera.open(camIdx);
Display getOrient = getWindowManager().getDefaultDisplay();
if (getOrient.getHeight() > getOrient.getWidth()) {
camera.setDisplayOrientation(90);
}
// myCamera.unlock();
// mediaRecorder.setCamera(myCamera);
// myCamera.setParameters(myCamera.getParameters());
} catch (RuntimeException e) {
Log.e("",
"Camera failed to open: " + e.getLocalizedMessage());
}
}
}
return camera;
// No front-facing camera found
}
#Override
public void onPreviewFrame(byte[] data, Camera camera) {
// TODO Auto-generated method stub
}
#Override
public void onShutter() {
// TODO Auto-generated method stub
}
#Override
public void onRawPictureTaken(byte[] data, Camera camera) {
// TODO Auto-generated method stub
}
#Override
public void onJpegPictureTaken(byte[] data, Camera camera) {
try {
this.data = data;
objrelativeLayoutretake.setVisibility(View.VISIBLE);
objrelativeLayout3.setVisibility(View.GONE);
} catch (Exception e) {
e.printStackTrace();
}
}
private void PhotoComplete(byte[] data) throws FileNotFoundException,
IOException {
try {
sdcardpath = String.format(getResources().getString(R.string.path),
System.currentTimeMillis());
FileOutputStream outStream = new FileOutputStream(sdcardpath);
outStream.write(data);
outStream.close();
Bundle objbundle = new Bundle();
Intent objintent = new Intent(CaptureDealImage.this,
com.flashdeal.mycamera.SetDealImageCategory.class);
objbundle.putString("from", "camera");
objbundle.putString("imagepath", sdcardpath);
Log.e("check===path", sdcardpath);
objintent.putExtras(objbundle);
startActivity(objintent);
finish();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
#Override
public String onGetVideoFilename() {
// TODO Auto-generated method stub
return null;
}
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (requestCode == 100 && resultCode == RESULT_OK) {
Uri selectedImage = data.getData();
String[] filePathColumn = { MediaStore.Images.Media.DATA };
Cursor cursor = getContentResolver().query(selectedImage,
filePathColumn, null, null, null);
cursor.moveToFirst();
int columnIndex = cursor.getColumnIndex(filePathColumn[0]);
String filePath = cursor.getString(columnIndex);
cursor.close();
Bundle objbundle = new Bundle();
Intent objintent = new Intent(CaptureDealImage.this,
com.flashdeal.mycamera.SetDealImageCategory.class);
objbundle.putString("from", "camera");
objbundle.putString("imagepath", filePath);
objintent.putExtras(objbundle);
startActivity(objintent);
finish();
}
}
}
But this not work and when I click front camera ,again back camera and again on capture button camera become freez.Please anyone guide me or give imp link for my requirement.
Refer this links ::
They are facing the same issue that you have.Have a look at once .
Link 1
Link 2
Hope this helps :)
My app requires that I take a picture, and the only device I'm running in problems with is the Motorola Razr. I've tried it on the Nexus One, Droid X, Droid 2, Sensation, and a few others. Here is the code I am using:
public class CameraView extends Activity {
private static final String TAG = "CameraView";
private SurfaceView preview=null;
private SurfaceHolder previewHolder=null;
public Camera camera=null;
private boolean inPreview=false;
private ImageView takePicture;
private Uri uriTarget;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.cameraview);
takePicture = (ImageView)findViewById(R.id.take_picture);
preview=(SurfaceView)findViewById(R.id.preview);
previewHolder=preview.getHolder();
previewHolder.addCallback(surfaceCallback);
previewHolder
.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
if (savedInstanceState != null)
{
uriTarget = savedInstanceState.getParcelable("uriTarget");
}
preview.setOnClickListener(new OnClickListener(){
#Override
public void onClick(View arg0) {
takePicture.setEnabled(false);
camera.autoFocus(myAutoFocusCallback);
}
});
takePicture.setOnClickListener(new OnClickListener(){
#Override
public void onClick(View arg0) {
//camera.takePicture(null, null, photoCallback);
camera.takePicture(myShutterCallback,
myPictureCallback_RAW, myPictureCallback_JPG);
inPreview=false;
}
});
}
#Override
public void onResume() {
super.onResume();
try{
if (camera==null) {
camera=Camera.open();
camera.setDisplayOrientation(90);
Camera.Parameters params = camera.getParameters();
params.set("rotation", 90);
params.setJpegQuality(60);
//params.setPictureSize(32, 32);
camera.setParameters(params);
}
}catch (Exception e){
finish();
}
}
#Override
public void onPause() {
if (inPreview) {
camera.stopPreview();
}
if(camera != null)
camera.release();
camera=null;
inPreview=false;
super.onPause();
}
SurfaceHolder.Callback surfaceCallback=new SurfaceHolder.Callback() {
public void surfaceCreated(SurfaceHolder holder) {
try {
camera.setPreviewDisplay(previewHolder);
}
catch (Throwable t) {
Log.e("PictureDemo-surfaceCallback",
"Exception in setPreviewDisplay()", t);
Toast.makeText(CameraView.this, t.getMessage(),
Toast.LENGTH_LONG).show();
}
}
public void surfaceChanged(SurfaceHolder holder,
int format, int width, int height) {
Camera.Parameters parameters=camera.getParameters();
parameters.setPictureFormat(PixelFormat.JPEG);
parameters.setJpegQuality(60);
parameters.set("rotation", 90);
camera.setParameters(parameters);
camera.startPreview();
inPreview=true;
}
public void surfaceDestroyed(SurfaceHolder holder) {
// no-op
}
};
ShutterCallback myShutterCallback = new ShutterCallback(){
#Override
public void onShutter() {
}};
PictureCallback myPictureCallback_RAW = new PictureCallback(){
#Override
public void onPictureTaken(byte[] arg0, Camera arg1) {
}};
PictureCallback myPictureCallback_JPG = new PictureCallback(){
#Override
public void onPictureTaken(byte[] data, Camera camera1) {
Constants.car_image = BitmapFactory.decodeByteArray(data, 0, data.length);
Constants.showImage = true;
FileOutputStream outStream = null;
try {
File esd = Environment.getExternalStorageDirectory();
File newDirectory = new File(esd.getAbsolutePath() + "/DCIM/statefair/");
if(!newDirectory.exists())
newDirectory.mkdirs();
outStream = new FileOutputStream(esd.getAbsolutePath() + String.format(
"/DCIM/statefair/%d.jpg", System.currentTimeMillis()));
outStream.write(data);
outStream.close();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
System.out.println("IO exception");
} finally {
System.out.println("Finally");
camera.release();
}
finish();
}
};
AutoFocusCallback myAutoFocusCallback = new AutoFocusCallback(){
#Override
public void onAutoFocus(boolean arg0, Camera arg1) {
// TODO Auto-generated method stub
takePicture.setEnabled(true);
}
};
protected void onSaveInstanceState(Bundle outState)
{
outState.putParcelable("uriTarget", uriTarget);
}
}
I get an outOfMemory error on this line:
Constants.car_image = BitmapFactory.decodeByteArray(data, 0, data.length);
even when I set the JPEG quality to 10. Anyone else run into this problem?
Check this BitmapFactory.Options
Full size images take a lot of memory, you should make re-size. Just for quick test, try this:
Options opts = new Options();
opts.inSampleSize = 4;
Constants.car_image = BitmapFactory.decodeByteArray(data, 0, data.length, opts);